Skip to content

Enable SpEL to support array refs in T() construct #53

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2009 the original author or authors.
* Copyright 2002-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -16,6 +16,8 @@

package org.springframework.expression.spel.ast;

import java.lang.reflect.Array;

import org.springframework.expression.EvaluationException;
import org.springframework.expression.TypedValue;
import org.springframework.expression.spel.ExpressionState;
Expand All @@ -27,8 +29,15 @@
*/
public class TypeReference extends SpelNodeImpl {

private int dimensions;

public TypeReference(int pos,SpelNodeImpl qualifiedId) {
this(pos,qualifiedId,0);
}

public TypeReference(int pos,SpelNodeImpl qualifiedId,int dims) {
super(pos,qualifiedId);
this.dimensions = dims;
}

@Override
Expand All @@ -39,17 +48,34 @@ public TypedValue getValueInternal(ExpressionState state) throws EvaluationExcep
TypeCode tc = TypeCode.valueOf(typename.toUpperCase());
if (tc != TypeCode.OBJECT) {
// it is a primitive type
return new TypedValue(tc.getType());
Class<?> clazz = tc.getType();
clazz = makeArrayIfNecessary(clazz);
return new TypedValue(clazz);
}
}
return new TypedValue(state.findType(typename));
Class<?> clazz = state.findType(typename);
clazz = makeArrayIfNecessary(clazz);
return new TypedValue(clazz);
}

private Class makeArrayIfNecessary(Class clazz) {
if (dimensions!=0) {
for (int i=0;i<dimensions;i++) {
Object o = Array.newInstance(clazz, 0);
clazz = o.getClass();
}
}
return clazz;
}

@Override
public String toStringAST() {
StringBuilder sb = new StringBuilder();
sb.append("T(");
sb.append(getChild(0).toStringAST());
for (int d=0;d<dimensions;d++) {
sb.append("[]");
}
sb.append(")");
return sb.toString();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2009 the original author or authors.
* Copyright 2002-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -497,8 +497,14 @@ private boolean maybeEatTypeReference() {
eatToken(TokenKind.LPAREN);
SpelNodeImpl node = eatPossiblyQualifiedId();
// dotted qualified id
// Are there array dimensions?
int dims = 0;
while (peekToken(TokenKind.LSQUARE,true)) {
eatToken(TokenKind.RSQUARE);
dims++;
}
eatToken(TokenKind.RPAREN);
constructedNodes.push(new TypeReference(toPos(typeName),node));
constructedNodes.push(new TypeReference(toPos(typeName),node,dims));
return true;
}
return false;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2009 the original author or authors.
* Copyright 2002-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -1192,6 +1192,37 @@ public ContextObject() {
public Map<String, String> getFourthContext() {return fourthContext;}
}


@Test
public void testArray() {
ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext context = new StandardEvaluationContext();
Expression expression = null;
Object result = null;

expression = parser.parseExpression("new java.lang.Long[0].class");
result = expression.getValue(context, "");
assertEquals("Equal assertion failed: ", "class [Ljava.lang.Long;", result.toString());

expression = parser.parseExpression("T(java.lang.Long[])");
result = expression.getValue(context, "");
assertEquals("Equal assertion failed: ", "class [Ljava.lang.Long;", result.toString());

expression = parser.parseExpression("T(java.lang.String[][][])");
result = expression.getValue(context, "");
assertEquals("Equal assertion failed: ", "class [[[Ljava.lang.String;", result.toString());
assertEquals("T(java.lang.String[][][])",((SpelExpression)expression).toStringAST());

expression = parser.parseExpression("new int[0].class");
result = expression.getValue(context, "");
assertEquals("Equal assertion failed: ", "class [I", result.toString());

expression = parser.parseExpression("T(int[][])");
result = expression.getValue(context, "");
assertEquals("Equal assertion failed: ", "class [[I", result.toString());
}


}