1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.krad.uif.service.impl;
17
18 import java.util.HashMap;
19 import java.util.List;
20 import java.util.Map;
21 import java.util.Map.Entry;
22
23 import org.apache.commons.lang.StringUtils;
24 import org.kuali.rice.krad.uif.UifConstants;
25 import org.kuali.rice.krad.uif.component.Component;
26 import org.kuali.rice.krad.uif.component.Configurable;
27 import org.kuali.rice.krad.uif.component.KeepExpression;
28 import org.kuali.rice.krad.uif.component.PropertyReplacer;
29 import org.kuali.rice.krad.uif.layout.LayoutManager;
30 import org.kuali.rice.krad.uif.service.ExpressionEvaluatorService;
31 import org.kuali.rice.krad.uif.util.CloneUtils;
32 import org.kuali.rice.krad.uif.util.ExpressionFunctions;
33 import org.kuali.rice.krad.uif.util.ObjectPropertyUtils;
34 import org.springframework.expression.Expression;
35 import org.springframework.expression.ExpressionParser;
36 import org.springframework.expression.common.TemplateParserContext;
37 import org.springframework.expression.spel.standard.SpelExpressionParser;
38 import org.springframework.expression.spel.support.StandardEvaluationContext;
39
40
41
42
43
44
45
46 public class ExpressionEvaluatorServiceImpl implements ExpressionEvaluatorService {
47 private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(
48 ExpressionEvaluatorServiceImpl.class);
49
50
51
52
53
54 public void evaluateObjectExpressions(Object object, Object contextObject,
55 Map<String, Object> evaluationParameters) {
56 if ((object instanceof Component) || (object instanceof LayoutManager)) {
57 evaluatePropertyReplacers(object, contextObject, evaluationParameters);
58 }
59 evaluatePropertyExpressions(object, contextObject, evaluationParameters);
60 }
61
62
63
64
65
66 public String evaluateExpressionTemplate(Object contextObject, Map<String, Object> evaluationParameters,
67 String expressionTemplate) {
68 StandardEvaluationContext context = new StandardEvaluationContext(contextObject);
69 context.setVariables(evaluationParameters);
70 addCustomFunctions(context);
71
72 ExpressionParser parser = new SpelExpressionParser();
73
74 String result = null;
75 try {
76 Expression expression = null;
77 if (StringUtils.contains(expressionTemplate, UifConstants.EL_PLACEHOLDER_PREFIX)) {
78 expression = parser.parseExpression(expressionTemplate, new TemplateParserContext(
79 UifConstants.EL_PLACEHOLDER_PREFIX, UifConstants.EL_PLACEHOLDER_SUFFIX));
80 } else {
81 expression = parser.parseExpression(expressionTemplate);
82 }
83
84 result = expression.getValue(context, String.class);
85 } catch (Exception e) {
86 LOG.error("Exception evaluating expression: " + expressionTemplate);
87 throw new RuntimeException("Exception evaluating expression: " + expressionTemplate, e);
88 }
89
90 return result;
91 }
92
93
94
95
96
97 public Object evaluateExpression(Object contextObject, Map<String, Object> evaluationParameters,
98 String expressionStr) {
99 StandardEvaluationContext context = new StandardEvaluationContext(contextObject);
100 context.setVariables(evaluationParameters);
101 addCustomFunctions(context);
102
103
104 if (StringUtils.startsWith(expressionStr, UifConstants.EL_PLACEHOLDER_PREFIX) && StringUtils.endsWith(
105 expressionStr, UifConstants.EL_PLACEHOLDER_SUFFIX)) {
106 expressionStr = StringUtils.removeStart(expressionStr, UifConstants.EL_PLACEHOLDER_PREFIX);
107 expressionStr = StringUtils.removeEnd(expressionStr, UifConstants.EL_PLACEHOLDER_SUFFIX);
108 }
109
110 ExpressionParser parser = new SpelExpressionParser();
111 Object result = null;
112 try {
113 Expression expression = parser.parseExpression(expressionStr);
114
115 result = expression.getValue(context);
116 } catch (Exception e) {
117 LOG.error("Exception evaluating expression: " + expressionStr);
118 throw new RuntimeException("Exception evaluating expression: " + expressionStr, e);
119 }
120
121 return result;
122 }
123
124
125
126
127
128
129 protected void addCustomFunctions(StandardEvaluationContext context) {
130 try {
131
132 context.registerFunction("isAssignableFrom", ExpressionFunctions.class.getDeclaredMethod("isAssignableFrom",
133 new Class[]{Class.class, Class.class}));
134 context.registerFunction("empty", ExpressionFunctions.class.getDeclaredMethod("empty",
135 new Class[]{Object.class}));
136 context.registerFunction("getName", ExpressionFunctions.class.getDeclaredMethod("getName",
137 new Class[]{Class.class}));
138 context.registerFunction("getParm", ExpressionFunctions.class.getDeclaredMethod("getParm",
139 new Class[]{String.class, String.class, String.class}));
140 context.registerFunction("getParmInd", ExpressionFunctions.class.getDeclaredMethod("getParmInd",
141 new Class[]{String.class, String.class, String.class}));
142 context.registerFunction("hasPerm", ExpressionFunctions.class.getDeclaredMethod("hasPerm",
143 new Class[]{String.class, String.class}));
144 context.registerFunction("hasPermDtls", ExpressionFunctions.class.getDeclaredMethod("hasPermDtls",
145 new Class[]{String.class, String.class, Map.class, Map.class}));
146 context.registerFunction("hasPermTmpl", ExpressionFunctions.class.getDeclaredMethod("hasPermTmpl",
147 new Class[]{String.class, String.class, Map.class, Map.class}));
148 } catch (NoSuchMethodException e) {
149 LOG.error("Custom function for el expressions not found: " + e.getMessage());
150 throw new RuntimeException("Custom function for el expressions not found: " + e.getMessage(), e);
151 }
152 }
153
154
155
156
157
158
159
160
161
162
163 protected void evaluatePropertyReplacers(Object object, Object contextObject,
164 Map<String, Object> evaluationParameters) {
165 List<PropertyReplacer> replacers = null;
166 if (Component.class.isAssignableFrom(object.getClass())) {
167 replacers = ((Component) object).getPropertyReplacers();
168 } else if (LayoutManager.class.isAssignableFrom(object.getClass())) {
169 replacers = ((LayoutManager) object).getPropertyReplacers();
170 }
171
172 for (PropertyReplacer propertyReplacer : replacers) {
173 String conditionEvaluation = evaluateExpressionTemplate(contextObject, evaluationParameters,
174 propertyReplacer.getCondition());
175 boolean conditionSuccess = Boolean.parseBoolean(conditionEvaluation);
176 if (conditionSuccess) {
177 ObjectPropertyUtils.setPropertyValue(object, propertyReplacer.getPropertyName(),
178 propertyReplacer.getReplacement());
179 }
180 }
181 }
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196 protected void evaluatePropertyExpressions(Object object, Object contextObject,
197 Map<String, Object> evaluationParameters) {
198 Map<String, String> propertyExpressions = new HashMap<String, String>();
199 if (Configurable.class.isAssignableFrom(object.getClass())) {
200 propertyExpressions = ((Configurable) object).getPropertyExpressions();
201 }
202
203 for (Entry<String, String> propertyExpression : propertyExpressions.entrySet()) {
204 String propertyName = propertyExpression.getKey();
205 String expression = propertyExpression.getValue();
206
207
208 if (CloneUtils.fieldHasAnnotation(object.getClass(), propertyName, KeepExpression.class)) {
209
210 ObjectPropertyUtils.setPropertyValue(object, propertyName, expression);
211 continue;
212 }
213
214 Object propertyValue = null;
215
216
217 if (StringUtils.startsWith(expression, UifConstants.EL_PLACEHOLDER_PREFIX) && StringUtils.endsWith(
218 expression, UifConstants.EL_PLACEHOLDER_SUFFIX) && (StringUtils.countMatches(expression,
219 UifConstants.EL_PLACEHOLDER_PREFIX) == 1)) {
220 propertyValue = evaluateExpression(contextObject, evaluationParameters, expression);
221 } else {
222
223 propertyValue = evaluateExpressionTemplate(contextObject, evaluationParameters, expression);
224 }
225
226 ObjectPropertyUtils.setPropertyValue(object, propertyName, propertyValue);
227 }
228 }
229
230
231
232
233 public boolean containsElPlaceholder(String value) {
234 boolean containsElPlaceholder = false;
235
236 if (StringUtils.isNotBlank(value)) {
237 String elPlaceholder = StringUtils.substringBetween(value, UifConstants.EL_PLACEHOLDER_PREFIX,
238 UifConstants.EL_PLACEHOLDER_SUFFIX);
239 if (StringUtils.isNotBlank(elPlaceholder)) {
240 containsElPlaceholder = true;
241 }
242 }
243
244 return containsElPlaceholder;
245 }
246
247 }