1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.krad.uif.view;
17
18 import org.apache.commons.lang.StringUtils;
19 import org.apache.commons.lang.math.NumberUtils;
20 import org.kuali.rice.core.api.exception.RiceRuntimeException;
21 import org.kuali.rice.krad.datadictionary.uif.UifDictionaryBean;
22 import org.kuali.rice.krad.uif.UifConstants;
23 import org.kuali.rice.krad.uif.component.BindingInfo;
24 import org.kuali.rice.krad.uif.component.Component;
25 import org.kuali.rice.krad.uif.component.KeepExpression;
26 import org.kuali.rice.krad.uif.component.PropertyReplacer;
27 import org.kuali.rice.krad.uif.container.CollectionGroup;
28 import org.kuali.rice.krad.uif.field.DataField;
29 import org.kuali.rice.krad.uif.layout.LayoutManager;
30 import org.kuali.rice.krad.uif.util.CopyUtils;
31 import org.kuali.rice.krad.uif.util.ExpressionFunctions;
32 import org.kuali.rice.krad.uif.util.ObjectPropertyUtils;
33 import org.springframework.expression.Expression;
34 import org.springframework.expression.ExpressionParser;
35 import org.springframework.expression.common.TemplateParserContext;
36 import org.springframework.expression.spel.standard.SpelExpressionParser;
37 import org.springframework.expression.spel.support.StandardEvaluationContext;
38
39 import java.lang.reflect.Method;
40 import java.util.ArrayList;
41 import java.util.Collection;
42 import java.util.HashMap;
43 import java.util.List;
44 import java.util.Map;
45 import java.util.regex.Matcher;
46 import java.util.regex.Pattern;
47
48
49
50
51
52
53 public class DefaultExpressionEvaluator implements ExpressionEvaluator {
54
55 private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(
56 DefaultExpressionEvaluator.class);
57
58 protected static final Pattern SERVER_EVALUATION_PATTERN = Pattern.compile(
59 "(\\s?!?\\b(#|get|is)(.*?\\(.*?\\)))(\\s|$)");
60
61 private StandardEvaluationContext evaluationContext;
62
63 private Map<String, Expression> cachedExpressions;
64
65 protected static ExpressionParser parser = new SpelExpressionParser();
66
67 private static Method isAssignableFrom;
68 private static Method empty;
69 private static Method emptyList;
70 private static Method getService;
71 private static Method listContains;
72 private static Method getName;
73 private static Method getParam;
74 private static Method getParamAsBoolean;
75 private static Method hasPerm;
76 private static Method hasPermDtls;
77 private static Method hasPermTmpl;
78 private static Method sequence;
79 private static Method getDataObjectKey;
80 private static Method isProductionEnvironment;
81
82 static {
83 try {
84 isAssignableFrom = ExpressionFunctions.class.getDeclaredMethod("isAssignableFrom",
85 new Class[] {Class.class, Class.class});
86 empty = ExpressionFunctions.class.getDeclaredMethod("empty", new Class[] {Object.class});
87 emptyList = ExpressionFunctions.class.getDeclaredMethod("emptyList", new Class[] {List.class});
88 listContains = ExpressionFunctions.class.getDeclaredMethod("listContains",
89 new Class[] {List.class, Object[].class});
90 getName = ExpressionFunctions.class.getDeclaredMethod("getName", new Class[] {Class.class});
91 getParam = ExpressionFunctions.class.getDeclaredMethod("getParam",
92 new Class[] {String.class, String.class, String.class});
93 getParamAsBoolean = ExpressionFunctions.class.getDeclaredMethod("getParamAsBoolean",
94 new Class[] {String.class, String.class, String.class});
95 hasPerm = ExpressionFunctions.class.getDeclaredMethod("hasPerm", new Class[] {String.class, String.class});
96 hasPermDtls = ExpressionFunctions.class.getDeclaredMethod("hasPermDtls",
97 new Class[] {String.class, String.class, Map.class, Map.class});
98 hasPermTmpl = ExpressionFunctions.class.getDeclaredMethod("hasPermTmpl",
99 new Class[] {String.class, String.class, Map.class, Map.class});
100 getService = ExpressionFunctions.class.getDeclaredMethod("getService", new Class[] {String.class});
101 sequence = ExpressionFunctions.class.getDeclaredMethod("sequence", new Class[] {String.class});
102 getDataObjectKey = ExpressionFunctions.class.getDeclaredMethod("getDataObjectKey",
103 new Class[] {String.class});
104 isProductionEnvironment = ExpressionFunctions.class.getDeclaredMethod("isProductionEnvironment", null);
105 } catch (NoSuchMethodException e) {
106 LOG.error("Custom function for el expressions not found: " + e.getMessage());
107 throw new RuntimeException("Custom function for el expressions not found: " + e.getMessage(), e);
108 }
109 }
110
111
112
113
114 public DefaultExpressionEvaluator() {
115 cachedExpressions = new HashMap<String, Expression>();
116 }
117
118
119
120
121 @Override
122 public void populatePropertyExpressionsFromGraph(UifDictionaryBean expressionConfigurable,
123 boolean buildRefreshGraphs) {
124 if (expressionConfigurable == null || expressionConfigurable.getExpressionGraph() == null) {
125 return;
126 }
127
128 Map<String, String> expressionGraph = expressionConfigurable.getExpressionGraph();
129 for (Map.Entry<String, String> expressionEntry : expressionGraph.entrySet()) {
130 String propertyName = expressionEntry.getKey();
131 String expression = expressionEntry.getValue();
132
133
134 UifDictionaryBean configurableWithExpression = expressionConfigurable;
135
136
137 String adjustedPropertyName = propertyName;
138 if (StringUtils.contains(propertyName, ".")) {
139 String configurablePath = StringUtils.substringBeforeLast(propertyName, ".");
140 adjustedPropertyName = StringUtils.substringAfterLast(propertyName, ".");
141
142 Object nestedObject = ObjectPropertyUtils.getPropertyValue(expressionConfigurable, configurablePath);
143 if ((nestedObject == null) || !(nestedObject instanceof UifDictionaryBean)) {
144 throw new RiceRuntimeException(
145 "Object for which expression is configured on is null or does not implement UifDictionaryBean: '"
146 + configurablePath + "'");
147 }
148
149
150 configurableWithExpression = (UifDictionaryBean) nestedObject;
151 }
152
153 configurableWithExpression.getPropertyExpressions().put(adjustedPropertyName, expression);
154 }
155 }
156
157
158
159
160 @Override
161 public String parseExpression(String exp, List<String> controlNames, Map<String, Object> context) {
162
163 exp = cleanUpExpression(exp);
164
165
166 Map<String, String> serverEvaluations = evaluateServerSideVariables(exp, context);
167
168 String conditionJs = exp;
169 controlNames.addAll(findControlNamesInExpression(exp));
170
171
172 conditionJs = replaceWithJsEquivalents(conditionJs);
173
174
175 for (String serverEvalToken : serverEvaluations.keySet()) {
176 String evaluatedValue = serverEvaluations.get(serverEvalToken);
177 conditionJs = conditionJs.replace(serverEvalToken, evaluatedValue);
178 }
179
180 List<String> removeControlNames = new ArrayList<String>();
181 List<String> addControlNames = new ArrayList<String>();
182
183
184 for (String propertyName : controlNames) {
185
186 if (propertyName.trim().startsWith("{") && propertyName.trim().endsWith("}")) {
187 String array = propertyName.trim().replace('{', '[');
188 array = array.replace('}', ']');
189 conditionJs = conditionJs.replace(propertyName, array);
190 removeControlNames.add(propertyName);
191 continue;
192 }
193
194
195 if (propertyName.startsWith("!")) {
196 String actualPropertyName = StringUtils.removeStart(propertyName, "!");
197 conditionJs = conditionJs.replace(propertyName, "!coerceValue(\"" + actualPropertyName + "\")");
198 removeControlNames.add(propertyName);
199 addControlNames.add(actualPropertyName);
200 } else {
201 conditionJs = conditionJs.replace(propertyName, "coerceValue(\"" + propertyName + "\")");
202 }
203 }
204
205 controlNames.removeAll(removeControlNames);
206 controlNames.addAll(addControlNames);
207
208
209 boolean complexCondition = conditionJs.contains(" (") || conditionJs.startsWith("(");
210
211
212 if (conditionJs.contains("true && ") || conditionJs.contains(" && true")) {
213 conditionJs = conditionJs.replace(" && true", "");
214 conditionJs = conditionJs.replace("true && ", "");
215 }
216
217
218
219 if (!complexCondition && (conditionJs.contains("false &&")) || conditionJs.contains("&& false") || conditionJs
220 .contains("|| true") || conditionJs.contains("true ||") || conditionJs.equals("true") || conditionJs
221 .equals("false")) {
222 conditionJs = "";
223 }
224
225 return conditionJs;
226 }
227
228
229
230
231
232
233
234 private String cleanUpExpression(String exp) {
235 exp = exp.trim();
236 if (exp.startsWith("@{")) {
237 exp = StringUtils.removeStart(exp, "@{");
238 if (exp.endsWith("}")) {
239 exp = StringUtils.removeEnd(exp, "}");
240 }
241 }
242
243
244 exp = StringUtils.replace(exp, "!=", " != ");
245 exp = StringUtils.replace(exp, "==", " == ");
246 exp = StringUtils.replace(exp, ">", " > ");
247 exp = StringUtils.replace(exp, "<", " < ");
248 exp = StringUtils.replace(exp, "<=", " <= ");
249 exp = StringUtils.replace(exp, ">=", " >= ");
250 exp = StringUtils.replace(exp, "&&", " && ");
251 exp = StringUtils.replace(exp, "||", " || ");
252 exp = StringUtils.replace(exp, " ", " ");
253 exp = StringUtils.replace(exp, " )", ")");
254 exp = StringUtils.replace(exp, "( ", "(");
255 exp = StringUtils.replace(exp, " ,", ",");
256
257 return exp;
258 }
259
260
261
262
263
264
265
266
267
268 private Map<String, String> evaluateServerSideVariables(String exp, Map<String, Object> context) {
269 Map<String, String> serverEvaluations = new HashMap<String, String>();
270 Matcher matcher = SERVER_EVALUATION_PATTERN.matcher(exp);
271 while (matcher.find()) {
272 String spelMethodCall = matcher.group(1);
273
274 Object value = this.evaluateExpression(context, spelMethodCall);
275
276
277 if (value == null) {
278 serverEvaluations.put(spelMethodCall, "null");
279 } else if (value instanceof String) {
280 serverEvaluations.put(spelMethodCall, "\"" + value + "\"");
281 } else if (value instanceof Boolean || NumberUtils.isNumber(value.toString())) {
282 serverEvaluations.put(spelMethodCall, value.toString());
283 } else {
284
285 serverEvaluations.put(spelMethodCall, "\"" + value.toString() + "\"");
286 }
287 }
288
289 return serverEvaluations;
290 }
291
292
293
294
295
296
297
298 private String replaceWithJsEquivalents(String conditionJs) {
299 conditionJs = conditionJs.replaceAll("\\s(?i:ne)\\s", " != ");
300 conditionJs = conditionJs.replaceAll("\\s(?i:eq)\\s", " == ");
301 conditionJs = conditionJs.replaceAll("\\s(?i:gt)\\s", " > ");
302 conditionJs = conditionJs.replaceAll("\\s(?i:lt)\\s", " < ");
303 conditionJs = conditionJs.replaceAll("\\s(?i:lte)\\s", " <= ");
304 conditionJs = conditionJs.replaceAll("\\s(?i:gte)\\s", " >= ");
305 conditionJs = conditionJs.replaceAll("\\s(?i:and)\\s", " && ");
306 conditionJs = conditionJs.replaceAll("\\s(?i:or)\\s", " || ");
307 conditionJs = conditionJs.replaceAll("\\s(?i:not)\\s", " != ");
308 conditionJs = conditionJs.replaceAll("\\s(?i:null)\\s?", " '' ");
309 conditionJs = conditionJs.replaceAll("\\s?(?i:#empty)\\((.*?)\\)", "isValueEmpty($1)");
310 conditionJs = conditionJs.replaceAll("\\s?(?i:#listContains)\\((.*?)\\)", "listContains($1)");
311 conditionJs = conditionJs.replaceAll("\\s?(?i:#emptyList)\\((.*?)\\)", "emptyList($1)");
312
313
314 if (conditionJs.contains("matches")) {
315 conditionJs = conditionJs.replaceAll("\\s+(?i:matches)\\s+'.*'", ".match(/" + "$0" + "/) != null ");
316 conditionJs = conditionJs.replaceAll("\\(/\\s+(?i:matches)\\s+'", "(/");
317 conditionJs = conditionJs.replaceAll("'\\s*/\\)", "/)");
318 }
319
320 return conditionJs;
321 }
322
323
324
325
326 @Override
327 public List<String> findControlNamesInExpression(String exp) {
328 List<String> controlNames = new ArrayList<String>();
329 String stack = "";
330
331 boolean expectingSingleQuote = false;
332 boolean ignoreNext = false;
333 for (int i = 0; i < exp.length(); i++) {
334 char c = exp.charAt(i);
335 if (!expectingSingleQuote && !ignoreNext && (c == '(' || c == ' ' || c == ')')) {
336 evaluateCurrentStack(stack.trim(), controlNames);
337
338 stack = "";
339 continue;
340 } else if (!ignoreNext && c == '\'') {
341 stack = stack + c;
342 expectingSingleQuote = !expectingSingleQuote;
343 } else if (c == '\\') {
344 stack = stack + c;
345 ignoreNext = !ignoreNext;
346 } else {
347 stack = stack + c;
348 ignoreNext = false;
349 }
350 }
351
352 if (StringUtils.isNotEmpty(stack)) {
353 evaluateCurrentStack(stack.trim(), controlNames);
354 }
355
356 return controlNames;
357 }
358
359
360
361
362
363 protected void evaluateCurrentStack(String stack, List<String> controlNames) {
364 if (StringUtils.isBlank(stack)) {
365 return;
366 }
367
368
369 if (!(stack.equals("==") || stack.equals("!=") || stack.equals(">") || stack.equals("<") || stack.equals(">=")
370 || stack.equals("<=") || stack.equalsIgnoreCase("ne") || stack.equalsIgnoreCase("eq") || stack
371 .equalsIgnoreCase("gt") || stack.equalsIgnoreCase("lt") || stack.equalsIgnoreCase("lte") || stack
372 .equalsIgnoreCase("gte") || stack.equalsIgnoreCase("matches") || stack.equalsIgnoreCase("null") || stack
373 .equalsIgnoreCase("false") || stack.equalsIgnoreCase("true") || stack.equalsIgnoreCase("and") || stack
374 .equalsIgnoreCase("or") || stack.startsWith("#") || stack.equals("!") || stack.startsWith("'") || stack
375 .endsWith("'"))) {
376
377 boolean isNumber = NumberUtils.isNumber(stack);
378
379
380 if (!(isNumber)) {
381
382 if (StringUtils.endsWith(stack, ",")) {
383 stack = StringUtils.removeEnd(stack, ",").trim();
384 }
385
386 if (!controlNames.contains(stack)) {
387 controlNames.add(stack);
388 }
389 }
390 }
391 }
392
393
394
395
396 @Override
397 public void initializeEvaluationContext(Object contextObject) {
398 evaluationContext = new StandardEvaluationContext(contextObject);
399
400 addCustomFunctions(evaluationContext);
401 }
402
403
404
405
406 @Override
407 public void evaluateExpressionsOnConfigurable(View view, UifDictionaryBean expressionConfigurable,
408 Map<String, Object> evaluationParameters) {
409 if ((expressionConfigurable instanceof Component) || (expressionConfigurable instanceof LayoutManager)) {
410 evaluatePropertyReplacers(view, expressionConfigurable, evaluationParameters);
411 }
412 evaluatePropertyExpressions(view, expressionConfigurable, evaluationParameters);
413 }
414
415
416
417
418 @Override
419 public Object evaluateExpression(Map<String, Object> evaluationParameters, String expressionStr) {
420 Object result = null;
421
422
423 if (StringUtils.startsWith(expressionStr, UifConstants.EL_PLACEHOLDER_PREFIX) && StringUtils.endsWith(
424 expressionStr, UifConstants.EL_PLACEHOLDER_SUFFIX)) {
425 expressionStr = StringUtils.removeStart(expressionStr, UifConstants.EL_PLACEHOLDER_PREFIX);
426 expressionStr = StringUtils.removeEnd(expressionStr, UifConstants.EL_PLACEHOLDER_SUFFIX);
427 }
428
429 try {
430 Expression expression = retrieveCachedExpression(expressionStr);
431
432 if (evaluationParameters != null) {
433 evaluationContext.setVariables(evaluationParameters);
434 }
435
436 result = expression.getValue(evaluationContext);
437 } catch (Exception e) {
438 StringBuilder builder = new StringBuilder("Exception evaluating expression: ");
439 builder.append(expressionStr);
440
441 if (evaluationParameters != null) {
442 builder.append(" for the following context: ");
443 for (Map.Entry<String, Object> entry : evaluationParameters.entrySet()) {
444 builder.append(System.lineSeparator());
445 builder.append(entry.getKey());
446 builder.append(": ");
447 builder.append(entry.getValue());
448 }
449 }
450
451 LOG.error(builder.toString());
452 throw new RuntimeException(builder.toString(), e);
453 }
454
455 return result;
456 }
457
458
459
460
461 @Override
462 public String evaluateExpressionTemplate(Map<String, Object> evaluationParameters, String expressionTemplate) {
463 String result = null;
464
465 try {
466 Expression expression = retrieveCachedExpression(expressionTemplate);
467
468 if (evaluationParameters != null) {
469 evaluationContext.setVariables(evaluationParameters);
470 }
471
472 result = expression.getValue(evaluationContext, String.class);
473 } catch (Exception e) {
474 LOG.error("Exception evaluating expression: " + expressionTemplate);
475 throw new RuntimeException("Exception evaluating expression: " + expressionTemplate, e);
476 }
477
478 return result;
479 }
480
481
482
483
484 @Override
485 public void evaluatePropertyExpression(View view, Map<String, Object> evaluationParameters,
486 UifDictionaryBean expressionConfigurable, String propertyName, boolean removeExpression) {
487
488 Map<String, String> propertyExpressions = expressionConfigurable.getPropertyExpressions();
489 if ((propertyExpressions == null) || !propertyExpressions.containsKey(propertyName)) {
490 return;
491 }
492
493 String expression = propertyExpressions.get(propertyName);
494
495
496 if (CopyUtils.fieldHasAnnotation(expressionConfigurable.getClass(), propertyName, KeepExpression.class)) {
497
498 ObjectPropertyUtils.setPropertyValue(expressionConfigurable, propertyName, expression);
499 return;
500 }
501
502 Object propertyValue = null;
503
504
505 String adjustedExpression = replaceBindingPrefixes(view, expressionConfigurable, expression);
506
507
508 if (StringUtils.startsWith(adjustedExpression, UifConstants.EL_PLACEHOLDER_PREFIX) && StringUtils.endsWith(
509 adjustedExpression, UifConstants.EL_PLACEHOLDER_SUFFIX) && (StringUtils.countMatches(adjustedExpression,
510 UifConstants.EL_PLACEHOLDER_PREFIX) == 1)) {
511 propertyValue = evaluateExpression(evaluationParameters, adjustedExpression);
512 } else {
513
514 propertyValue = evaluateExpressionTemplate(evaluationParameters, adjustedExpression);
515 }
516
517
518
519 if (StringUtils.endsWith(propertyName, ExpressionEvaluator.EMBEDDED_PROPERTY_NAME_ADD_INDICATOR)) {
520 StringUtils.removeEnd(propertyName, ExpressionEvaluator.EMBEDDED_PROPERTY_NAME_ADD_INDICATOR);
521
522 Collection collectionValue = ObjectPropertyUtils.getPropertyValue(expressionConfigurable, propertyName);
523 if (collectionValue == null) {
524 throw new RuntimeException("Property name: " + propertyName
525 + " with collection type was not initialized. Cannot add expression result");
526 }
527 collectionValue.add(propertyValue);
528 } else {
529 ObjectPropertyUtils.setPropertyValue(expressionConfigurable, propertyName, propertyValue);
530 }
531
532 if (removeExpression) {
533 propertyExpressions.remove(propertyName);
534 }
535 }
536
537
538
539
540 @Override
541 public boolean containsElPlaceholder(String value) {
542 boolean containsElPlaceholder = false;
543
544 if (StringUtils.isNotBlank(value)) {
545 String elPlaceholder = StringUtils.substringBetween(value, UifConstants.EL_PLACEHOLDER_PREFIX,
546 UifConstants.EL_PLACEHOLDER_SUFFIX);
547 if (StringUtils.isNotBlank(elPlaceholder)) {
548 containsElPlaceholder = true;
549 }
550 }
551
552 return containsElPlaceholder;
553 }
554
555
556
557
558 @Override
559 public String replaceBindingPrefixes(View view, Object object, String expression) {
560 String adjustedExpression = StringUtils.replace(expression, UifConstants.NO_BIND_ADJUST_PREFIX, "");
561
562
563 if (StringUtils.contains(adjustedExpression, UifConstants.FIELD_PATH_BIND_ADJUST_PREFIX)) {
564 if (object instanceof DataField) {
565
566 BindingInfo bindingInfo = ((DataField) object).getBindingInfo();
567
568 Pattern pattern = Pattern.compile("(" + Pattern.quote(UifConstants.FIELD_PATH_BIND_ADJUST_PREFIX)
569 + "[\\.\\w]+" + ")");
570 Matcher matcher = pattern.matcher(adjustedExpression);
571 while (matcher.find()) {
572 String path = matcher.group();
573
574 String adjustedPath = bindingInfo.getPropertyAdjustedBindingPath(path);
575 adjustedExpression = StringUtils.replace(adjustedExpression, path, adjustedPath);
576 }
577 } else {
578 adjustedExpression = StringUtils.replace(adjustedExpression, UifConstants.FIELD_PATH_BIND_ADJUST_PREFIX,
579 "");
580 }
581 }
582
583
584 if (StringUtils.isNotBlank(view.getDefaultBindingObjectPath())) {
585 adjustedExpression = StringUtils.replace(adjustedExpression, UifConstants.DEFAULT_PATH_BIND_ADJUST_PREFIX,
586 view.getDefaultBindingObjectPath() + ".");
587 } else {
588 adjustedExpression = StringUtils.replace(adjustedExpression, UifConstants.DEFAULT_PATH_BIND_ADJUST_PREFIX,
589 "");
590 }
591
592
593 if (adjustedExpression.contains(UifConstants.LINE_PATH_BIND_ADJUST_PREFIX) && (object instanceof Component)) {
594 String linePath = getLinePathPrefixValue((Component) object);
595
596 adjustedExpression = StringUtils.replace(adjustedExpression, UifConstants.LINE_PATH_BIND_ADJUST_PREFIX,
597 (StringUtils.isEmpty(linePath) ? linePath : linePath + "."));
598 }
599
600
601 if (adjustedExpression.contains(UifConstants.NODE_PATH_BIND_ADJUST_PREFIX) && (object instanceof Component)) {
602 String nodePath = "";
603
604 Map<String, Object> context = ((Component) object).getContext();
605 if (context != null && context.containsKey(UifConstants.ContextVariableNames.NODE_PATH)) {
606 nodePath = (String) context.get(UifConstants.ContextVariableNames.NODE_PATH);
607 }
608
609 adjustedExpression = StringUtils.replace(adjustedExpression, UifConstants.NODE_PATH_BIND_ADJUST_PREFIX,
610 nodePath + ".");
611 }
612
613 return adjustedExpression;
614 }
615
616
617
618
619
620
621
622
623 protected Expression retrieveCachedExpression(String expressionTemplate) {
624 Expression expression = null;
625
626
627 if (cachedExpressions.containsKey(expressionTemplate)) {
628 return cachedExpressions.get(expressionTemplate);
629 }
630
631
632 if (StringUtils.contains(expressionTemplate, UifConstants.EL_PLACEHOLDER_PREFIX)) {
633 expression = parser.parseExpression(expressionTemplate, new TemplateParserContext(
634 UifConstants.EL_PLACEHOLDER_PREFIX, UifConstants.EL_PLACEHOLDER_SUFFIX));
635 } else {
636 expression = parser.parseExpression(expressionTemplate);
637 }
638
639 synchronized (cachedExpressions) {
640 cachedExpressions.put(expressionTemplate, expression);
641 }
642
643 return expression;
644 }
645
646
647
648
649
650
651 protected void addCustomFunctions(StandardEvaluationContext context) {
652 context.registerFunction("isAssignableFrom", isAssignableFrom);
653 context.registerFunction("empty", empty);
654 context.registerFunction("emptyList", emptyList);
655 context.registerFunction("getService", getService);
656 context.registerFunction("listContains", listContains);
657 context.registerFunction("getName", getName);
658 context.registerFunction("getParam", getParam);
659 context.registerFunction("getParamAsBoolean", getParamAsBoolean);
660 context.registerFunction("hasPerm", hasPerm);
661 context.registerFunction("hasPermDtls", hasPermDtls);
662 context.registerFunction("hasPermTmpl", hasPermTmpl);
663 context.registerFunction("sequence", sequence);
664 context.registerFunction("getDataObjectKey", getDataObjectKey);
665 context.registerFunction("isProductionEnvironment", isProductionEnvironment);
666 }
667
668
669
670
671
672
673
674
675
676
677
678 protected void evaluatePropertyReplacers(View view, UifDictionaryBean expressionConfigurable,
679 Map<String, Object> evaluationParameters) {
680 List<PropertyReplacer> replacers = null;
681 if (Component.class.isAssignableFrom(expressionConfigurable.getClass())) {
682 replacers = ((Component) expressionConfigurable).getPropertyReplacers();
683 } else if (LayoutManager.class.isAssignableFrom(expressionConfigurable.getClass())) {
684 replacers = ((LayoutManager) expressionConfigurable).getPropertyReplacers();
685 }
686
687 if (replacers != null) {
688 for (PropertyReplacer propertyReplacer : replacers) {
689 String expression = propertyReplacer.getCondition();
690 String adjustedExpression = replaceBindingPrefixes(view, expressionConfigurable, expression);
691
692 String conditionEvaluation = evaluateExpressionTemplate(evaluationParameters, adjustedExpression);
693 boolean conditionSuccess = Boolean.parseBoolean(conditionEvaluation);
694 if (conditionSuccess) {
695 ObjectPropertyUtils.setPropertyValue(expressionConfigurable, propertyReplacer.getPropertyName(),
696 propertyReplacer.getReplacement());
697 }
698 }
699 }
700 }
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718 protected void evaluatePropertyExpressions(View view, UifDictionaryBean expressionConfigurable,
719 Map<String, Object> evaluationParameters) {
720 if (expressionConfigurable == null) {
721 return;
722 }
723
724 Map<String, String> propertyExpressions = expressionConfigurable.getPropertyExpressions();
725 if (propertyExpressions == null) {
726 return;
727 }
728
729 for (String propertyName : propertyExpressions.keySet()) {
730 evaluatePropertyExpression(view, evaluationParameters, expressionConfigurable, propertyName, false);
731 }
732 }
733
734
735
736
737
738
739
740
741
742 protected static String getLinePathPrefixValue(Component component) {
743 Map<String, Object> componentContext = component.getContext();
744 if (componentContext == null) {
745 return "";
746 }
747
748 CollectionGroup collectionGroup = (CollectionGroup) (componentContext.get(
749 UifConstants.ContextVariableNames.COLLECTION_GROUP));
750 if (collectionGroup == null) {
751 LOG.warn("collection group not found for " + component + "," + component.getId() + ", " + component
752 .getComponentTypeName());
753 return "";
754 }
755
756 String linePath = "";
757
758 Integer indexObj = (Integer) componentContext.get(UifConstants.ContextVariableNames.INDEX);
759 if (indexObj != null) {
760 int index = indexObj.intValue();
761
762 boolean addLine = false;
763 Boolean addLineObj = (Boolean) componentContext.get(UifConstants.ContextVariableNames.IS_ADD_LINE);
764
765 if (addLineObj != null) {
766 addLine = addLineObj.booleanValue();
767 }
768
769 if (addLine) {
770 linePath = collectionGroup.getAddLineBindingInfo().getBindingPath();
771 } else {
772 linePath = collectionGroup.getBindingInfo().getBindingPath() + "[" + index + "]";
773 }
774 }
775
776 return linePath;
777 }
778 }