1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.springframework.expression.spel.ast;
18
19 import java.util.Collections;
20 import java.util.LinkedHashMap;
21 import java.util.Map;
22
23 import org.springframework.expression.EvaluationException;
24 import org.springframework.expression.TypedValue;
25 import org.springframework.expression.spel.ExpressionState;
26 import org.springframework.expression.spel.SpelNode;
27
28
29
30
31
32
33
34 public class InlineMap extends SpelNodeImpl {
35
36
37 private TypedValue constant = null;
38
39
40 public InlineMap(int pos, SpelNodeImpl... args) {
41 super(pos, args);
42 checkIfConstant();
43 }
44
45
46
47
48
49
50
51 private void checkIfConstant() {
52 boolean isConstant = true;
53 for (int c = 0, max = getChildCount(); c < max; c++) {
54 SpelNode child = getChild(c);
55 if (!(child instanceof Literal)) {
56 if (child instanceof InlineList) {
57 InlineList inlineList = (InlineList) child;
58 if (!inlineList.isConstant()) {
59 isConstant = false;
60 break;
61 }
62 }
63 else if (child instanceof InlineMap) {
64 InlineMap inlineMap = (InlineMap) child;
65 if (!inlineMap.isConstant()) {
66 isConstant = false;
67 break;
68 }
69 }
70 else if (!((c%2)==0 && (child instanceof PropertyOrFieldReference))) {
71 isConstant = false;
72 break;
73 }
74 }
75 }
76 if (isConstant) {
77 Map<Object,Object> constantMap = new LinkedHashMap<Object,Object>();
78 int childCount = getChildCount();
79 for (int c = 0; c < childCount; c++) {
80 SpelNode keyChild = getChild(c++);
81 SpelNode valueChild = getChild(c);
82 Object key = null;
83 Object value = null;
84 if (keyChild instanceof Literal) {
85 key = ((Literal) keyChild).getLiteralValue().getValue();
86 }
87 else if (keyChild instanceof PropertyOrFieldReference) {
88 key = ((PropertyOrFieldReference) keyChild).getName();
89 }
90 else {
91 return;
92 }
93 if (valueChild instanceof Literal) {
94 value = ((Literal) valueChild).getLiteralValue().getValue();
95 }
96 else if (valueChild instanceof InlineList) {
97 value = ((InlineList) valueChild).getConstantValue();
98 }
99 else if (valueChild instanceof InlineMap) {
100 value = ((InlineMap) valueChild).getConstantValue();
101 }
102 constantMap.put(key, value);
103 }
104 this.constant = new TypedValue(Collections.unmodifiableMap(constantMap));
105 }
106 }
107
108 @Override
109 public TypedValue getValueInternal(ExpressionState expressionState) throws EvaluationException {
110 if (this.constant != null) {
111 return this.constant;
112 }
113 else {
114 Map<Object, Object> returnValue = new LinkedHashMap<Object, Object>();
115 int childcount = getChildCount();
116 for (int c = 0; c < childcount; c++) {
117
118 SpelNode keyChild = getChild(c++);
119 Object key = null;
120 if (keyChild instanceof PropertyOrFieldReference) {
121 PropertyOrFieldReference reference = (PropertyOrFieldReference) keyChild;
122 key = reference.getName();
123 }
124 else {
125 key = keyChild.getValue(expressionState);
126 }
127 Object value = getChild(c).getValue(expressionState);
128 returnValue.put(key, value);
129 }
130 return new TypedValue(returnValue);
131 }
132 }
133
134 @Override
135 public String toStringAST() {
136 StringBuilder sb = new StringBuilder("{");
137 int count = getChildCount();
138 for (int c = 0; c < count; c++) {
139 if (c > 0) {
140 sb.append(",");
141 }
142 sb.append(getChild(c++).toStringAST());
143 sb.append(":");
144 sb.append(getChild(c).toStringAST());
145 }
146 sb.append("}");
147 return sb.toString();
148 }
149
150
151
152
153 public boolean isConstant() {
154 return this.constant != null;
155 }
156
157 @SuppressWarnings("unchecked")
158 public Map<Object,Object> getConstantValue() {
159 return (Map<Object,Object>) this.constant.getValue();
160 }
161
162 }