1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.krad.uif.util;
17
18 import java.util.ArrayList;
19 import java.util.Collection;
20 import java.util.Collections;
21 import java.util.HashMap;
22 import java.util.HashSet;
23 import java.util.LinkedList;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.Queue;
27 import java.util.Set;
28
29 import org.apache.commons.lang.StringUtils;
30 import org.kuali.rice.core.framework.util.ReflectionUtils;
31 import org.kuali.rice.krad.uif.UifConstants;
32 import org.kuali.rice.krad.uif.component.Component;
33 import org.kuali.rice.krad.uif.component.DataBinding;
34 import org.kuali.rice.krad.uif.component.Ordered;
35 import org.kuali.rice.krad.uif.container.CollectionGroup;
36 import org.kuali.rice.krad.uif.container.Container;
37 import org.kuali.rice.krad.uif.container.Group;
38 import org.kuali.rice.krad.uif.field.Field;
39 import org.kuali.rice.krad.uif.field.FieldGroup;
40 import org.kuali.rice.krad.uif.field.InputField;
41 import org.kuali.rice.krad.uif.layout.LayoutManager;
42 import org.kuali.rice.krad.uif.layout.TableLayoutManager;
43 import org.kuali.rice.krad.uif.lifecycle.ViewLifecycle;
44 import org.kuali.rice.krad.uif.lifecycle.ViewLifecycleUtils;
45 import org.kuali.rice.krad.uif.lifecycle.initialize.AssignIdsTask;
46 import org.springframework.core.OrderComparator;
47
48
49
50
51
52
53 public class ComponentUtils {
54 private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(ComponentUtils.class);
55
56 private ComponentUtils() {}
57
58 public static <T extends Component> T copy(T component) {
59 return copy(component, null);
60 }
61
62 public static <T extends Component> T copy(T component, String idSuffix) {
63 if (component == null) {
64 return null;
65 }
66
67 T copy = CopyUtils.copy(component);
68
69 if (StringUtils.isNotBlank(idSuffix)) {
70 updateIdsWithSuffixNested(copy, idSuffix);
71 }
72
73 return copy;
74 }
75
76
77
78
79
80
81
82
83
84 public static <T extends Component> List<T> copy(List<T> components) {
85 if (components != null) {
86 List<T> componentsCopy = new ArrayList<T>();
87 for (T component : components) {
88 T copiedComponent = copy(component);
89 componentsCopy.add(copiedComponent);
90 }
91
92 return componentsCopy;
93 }
94
95 return new ArrayList<T>();
96 }
97
98
99
100
101
102
103
104
105
106 public static <T extends Field> void bindAndIdFieldList(List<T> fields, String addBindingPrefix, String idSuffix) {
107 updateIdsWithSuffixNested(fields, idSuffix);
108 prefixBindingPath(fields, addBindingPrefix);
109 }
110
111 public static <T extends Component> T copyComponent(T component, String addBindingPrefix, String idSuffix) {
112 T copy = copy(component, idSuffix);
113
114 prefixBindingPathNested(copy, addBindingPrefix);
115
116 return copy;
117 }
118
119 public static <T extends Component> List<T> copyComponentList(List<T> components, String idSuffix) {
120 if (components == null || components.isEmpty()) {
121 return Collections.emptyList();
122 }
123
124 List<T> copiedComponentList = new ArrayList<T>(components.size());
125
126 for (T field : components) {
127 T copiedComponent = copy(field, idSuffix);
128 copiedComponentList.add(copiedComponent);
129 }
130
131 return copiedComponentList;
132 }
133
134 public static <T extends Object> List<T> getComponentsOfType(List<? extends Component> items,
135 Class<T> componentType) {
136 if (items == null || items.isEmpty()) {
137 return Collections.emptyList();
138 }
139
140 List<T> typeComponents = Collections.emptyList();
141
142 for (Component component : items) {
143
144 if (!componentType.isInstance(component)) {
145 continue;
146 }
147
148 if (typeComponents.isEmpty()) {
149 typeComponents = new ArrayList<T>(items.size());
150 }
151
152 typeComponents.add(componentType.cast(component));
153 }
154
155 return typeComponents;
156 }
157
158
159
160
161
162
163
164
165
166
167 public static <T extends Component> List<T> getNestedContainerComponents(Container container,
168 Class<T> componentType) {
169 List<T> typeComponents = new ArrayList<T>();
170
171 if (container == null) {
172 return typeComponents;
173 }
174
175 for (Component item : container.getItems()) {
176 if (item == null) {
177 continue;
178 }
179
180 if (item instanceof Container) {
181 typeComponents.addAll(getNestedContainerComponents((Container) item, componentType));
182 } else if (item instanceof FieldGroup) {
183 typeComponents.addAll(getNestedContainerComponents(((FieldGroup) item).getGroup(), componentType));
184 } else if (componentType.isAssignableFrom(item.getClass())) {
185 typeComponents.add(componentType.cast(item));
186 }
187 }
188
189 return typeComponents;
190 }
191
192 public static <T extends Component> List<T> getNestedNonCollectionComponents(List<Component> items,
193 Class<T> componentType) {
194 List<T> typeComponents = new ArrayList<T>();
195
196 if (items == null) {
197 return typeComponents;
198 }
199
200 for (Component item : items) {
201 if (item == null) {
202 continue;
203 }
204
205 if (item instanceof Container && !(item instanceof CollectionGroup)) {
206 typeComponents.addAll(getNestedNonCollectionComponents((Container) item, componentType));
207 } else if (item instanceof FieldGroup) {
208 typeComponents.addAll(getNestedNonCollectionComponents(((FieldGroup) item).getGroup(), componentType));
209 } else if (componentType.isAssignableFrom(item.getClass())) {
210 typeComponents.add(componentType.cast(item));
211 }
212 }
213
214 return typeComponents;
215 }
216
217 public static <T extends Component> List<T> getNestedNonCollectionComponents(Container container,
218 Class<T> componentType) {
219 List<T> typeComponents = new ArrayList<T>();
220
221 if (container == null) {
222 return typeComponents;
223 }
224
225 for (Component item : container.getItems()) {
226 if (item == null) {
227 continue;
228 }
229
230 if (item instanceof Container && !(item instanceof CollectionGroup)) {
231 typeComponents.addAll(getNestedNonCollectionComponents((Container) item, componentType));
232 } else if (item instanceof FieldGroup) {
233 typeComponents.addAll(getNestedNonCollectionComponents(((FieldGroup) item).getGroup(), componentType));
234 } else if (componentType.isAssignableFrom(item.getClass())) {
235 typeComponents.add(componentType.cast(item));
236 }
237 }
238
239 return typeComponents;
240 }
241
242
243
244
245
246
247
248
249 public static List<Component> getAllNestedComponents(Component component) {
250 if (component == null) {
251 return Collections.emptyList();
252 }
253
254 List<Component> components = Collections.emptyList();
255 @SuppressWarnings("unchecked") Queue<LifecycleElement> elementQueue = RecycleUtils.getInstance(
256 LinkedList.class);
257 elementQueue.offer(component);
258
259 try {
260 while (!elementQueue.isEmpty()) {
261 LifecycleElement currentElement = elementQueue.poll();
262
263 if (currentElement == null) {
264 continue;
265 }
266
267 if (currentElement instanceof Component && currentElement != component) {
268 if (components.isEmpty()) {
269 components = new ArrayList<Component>();
270 }
271
272 components.add((Component) currentElement);
273 }
274
275 elementQueue.addAll(ViewLifecycleUtils.getElementsForLifecycle(currentElement).values());
276 }
277 } finally {
278 elementQueue.clear();
279 RecycleUtils.recycle(elementQueue);
280 }
281
282 return components;
283 }
284
285
286
287
288
289
290
291
292 public static Component findComponentInList(List<Component> components, String componentId) {
293 for (Component component : components) {
294 if (component != null && StringUtils.equals(component.getId(), componentId)) {
295 return component;
296 }
297 }
298
299 return null;
300 }
301
302 public static void prefixBindingPath(List<? extends Component> components, String addBindingPrefix) {
303 for (Component component : components) {
304 prefixBindingPath(component, addBindingPrefix);
305 }
306 }
307
308 public static void prefixBindingPath(Component component, String addBindingPrefix) {
309 if (component instanceof DataBinding) {
310 prefixBindingPath((DataBinding) component, addBindingPrefix);
311 } else if ((component instanceof FieldGroup) && (((FieldGroup) component).getItems() != null)) {
312 List<? extends Component> fieldGroupItems = ((FieldGroup) component).getItems();
313 prefixBindingPath(fieldGroupItems, addBindingPrefix);
314 } else if ((component instanceof Group) && (((Group) component).getItems() != null) &&
315 !(component instanceof CollectionGroup)) {
316 List<? extends Component> groupItems = ((Group) component).getItems();
317 prefixBindingPath(groupItems, addBindingPrefix);
318 }
319 }
320
321 public static void prefixBindingPath(DataBinding field, String addBindingPrefix) {
322 String bindingPrefix = addBindingPrefix;
323 if (StringUtils.isNotBlank(field.getBindingInfo().getBindByNamePrefix())) {
324 bindingPrefix += "." + field.getBindingInfo().getBindByNamePrefix();
325 }
326 field.getBindingInfo().setBindByNamePrefix(bindingPrefix);
327 }
328
329 public static void prefixBindingPathNested(Component component, String addBindingPrefix) {
330 @SuppressWarnings("unchecked") Queue<LifecycleElement> elementQueue = RecycleUtils.getInstance(
331 LinkedList.class);
332 elementQueue.offer(component);
333
334 try {
335 while (!elementQueue.isEmpty()) {
336 LifecycleElement currentElement = elementQueue.poll();
337 if (currentElement == null) {
338 continue;
339 }
340
341 if (currentElement instanceof DataBinding) {
342 if (LOG.isDebugEnabled()) {
343 LOG.info("setting nested binding prefix '" + addBindingPrefix + "' on " + currentElement);
344 }
345 prefixBindingPath((DataBinding) currentElement, addBindingPrefix);
346 }
347
348 elementQueue.addAll(ViewLifecycleUtils.getElementsForLifecycle(currentElement).values());
349 }
350 } finally {
351 elementQueue.clear();
352 RecycleUtils.recycle(elementQueue);
353 }
354 }
355
356 public static void updateIdsWithSuffixNested(List<? extends Component> components, String idSuffix) {
357 for (Component component : components) {
358 updateIdsWithSuffixNested(component, idSuffix);
359 }
360 }
361
362 public static void updateIdsWithSuffixNested(Component component, String idSuffix) {
363 updateIdWithSuffix(component, idSuffix);
364
365 updateChildIdsWithSuffixNested(component, idSuffix);
366 }
367
368
369
370
371
372
373
374 public static void updateIdWithSuffix(LifecycleElement element, String idSuffix) {
375 if (StringUtils.isBlank(idSuffix)) {
376 return;
377 }
378
379 if (element != null) {
380 element.setId(element.getId() + idSuffix);
381 }
382
383 if (element instanceof Container) {
384 LayoutManager manager = ((Container) element).getLayoutManager();
385
386 if (manager != null) {
387 manager.setId(manager.getId() + idSuffix);
388 }
389 }
390 }
391
392 public static void updateChildIdsWithSuffixNested(Component component, String idSuffix) {
393 @SuppressWarnings("unchecked") Queue<LifecycleElement> elementQueue = RecycleUtils.getInstance(
394 LinkedList.class);
395 try {
396 elementQueue.addAll(ViewLifecycleUtils.getElementsForLifecycle(component).values());
397
398 while (!elementQueue.isEmpty()) {
399 LifecycleElement currentElement = elementQueue.poll();
400 if (currentElement == null) {
401 continue;
402 }
403
404 if (currentElement instanceof Component) {
405 updateIdWithSuffix((Component) currentElement, idSuffix);
406 elementQueue.addAll(((Component) currentElement).getPropertyReplacerComponents());
407 }
408
409 elementQueue.addAll(ViewLifecycleUtils.getElementsForLifecycle(currentElement).values());
410 }
411 } finally {
412 elementQueue.clear();
413 RecycleUtils.recycle(elementQueue);
414 }
415 }
416
417
418
419
420
421
422
423
424
425
426
427
428
429 public static int generateId(LifecycleElement element, int seed) {
430 if (element == null) {
431 return seed;
432 }
433
434 final int prime = 6971;
435 int hash = prime * seed + element.getClass().getName().hashCode();
436
437 String id = element.getId();
438 hash *= prime;
439 if (id != null) {
440 hash += id.hashCode();
441 }
442
443 do {
444 hash *= 4507;
445 id = Long.toString(((long) hash) - ((long) Integer.MIN_VALUE), 36);
446 } while (!ViewLifecycle.getView().getViewIndex().observeAssignedId(id));
447
448 element.setId(UifConstants.COMPONENT_ID_PREFIX + id);
449
450 return hash;
451 }
452
453
454
455
456
457
458
459
460
461
462 public static void clearAndAssignIds(List<? extends Component> components) {
463 if (components == null || components.isEmpty()) {
464 return;
465 }
466
467 int hash = 1;
468 @SuppressWarnings("unchecked") Queue<LifecycleElement> toClear = RecycleUtils.getInstance(LinkedList.class);
469 toClear.addAll(components);
470 try {
471 while (!toClear.isEmpty()) {
472 LifecycleElement element = toClear.poll();
473
474 hash = generateId(element, hash);
475
476 for (LifecycleElement nested : ViewLifecycleUtils.getElementsForLifecycle(element).values()) {
477 if (nested != null) {
478 toClear.add(nested);
479 }
480 }
481
482 if (element instanceof Component) {
483 List<Component> propertyReplacerComponents = ((Component) element).getPropertyReplacerComponents();
484 if (propertyReplacerComponents == null) {
485 continue;
486 }
487
488 for (Component nested : propertyReplacerComponents) {
489 if (nested != null) {
490 toClear.add(nested);
491 }
492 }
493 }
494 }
495 } finally {
496 toClear.clear();
497 RecycleUtils.recycle(toClear);
498 }
499 }
500
501
502
503
504
505
506
507
508
509
510
511
512 public static <T extends Component> void setComponentsPropertyDeep(List<T> components, String propertyPath,
513 Object propertyValue) {
514 if (components == null || components.isEmpty()) {
515 return;
516 }
517
518 Set<Class<?>> skipTypes = null;
519 @SuppressWarnings("unchecked") Queue<LifecycleElement> elementQueue = RecycleUtils.getInstance(
520 LinkedList.class);
521 elementQueue.addAll(components);
522
523 try {
524 while (!elementQueue.isEmpty()) {
525 LifecycleElement currentElement = elementQueue.poll();
526 if (currentElement == null) {
527 continue;
528 }
529
530 elementQueue.addAll(ViewLifecycleUtils.getElementsForLifecycle(currentElement).values());
531
532 Class<?> componentClass = currentElement.getClass();
533 if (skipTypes != null && skipTypes.contains(componentClass)) {
534 continue;
535 }
536
537 if (!ObjectPropertyUtils.isWritableProperty(currentElement, propertyPath)) {
538 if (skipTypes == null) {
539 skipTypes = new HashSet<Class<?>>();
540 }
541 skipTypes.add(componentClass);
542 continue;
543 }
544
545 ObjectPropertyUtils.setPropertyValue(currentElement, propertyPath, propertyValue, true);
546 }
547 } finally {
548 elementQueue.clear();
549 RecycleUtils.recycle(elementQueue);
550 }
551 }
552
553
554
555
556
557
558
559
560
561
562 public static void setComponentPropertyDeep(Component component, String propertyPath, Object propertyValue) {
563 setComponentsPropertyDeep(Collections.singletonList(component), propertyPath, propertyValue);
564 }
565
566
567
568
569
570
571
572
573
574 public static void setComponentPropertyFinal(Component component, String propertyName, Object propertyValue) {
575 if (component == null) {
576 return;
577 }
578
579 ObjectPropertyUtils.setPropertyValue(component, propertyName, propertyValue);
580
581 if ((component.getPropertyExpressions() != null) && component.getPropertyExpressions().containsKey(
582 propertyName)) {
583 component.getPropertyExpressions().remove(propertyName);
584 }
585 }
586
587
588
589
590
591
592
593 public static boolean canBeRefreshed(Component component) {
594 boolean hasRefreshCondition = StringUtils.isNotBlank(component.getProgressiveRender()) ||
595 StringUtils.isNotBlank(component.getConditionalRefresh()) || (component.getRefreshTimer() > 0) ||
596 (component.getRefreshWhenChangedPropertyNames() != null && !component
597 .getRefreshWhenChangedPropertyNames().isEmpty());
598
599 boolean isInlineEditField =
600 component instanceof InputField && (((InputField) component).isInlineEdit() || ((InputField) component)
601 .isAjaxInlineEdit());
602
603 return hasRefreshCondition || component.isRefreshedByAction() || component.isDisclosedByAction() ||
604 component.isRetrieveViaAjax() || isInlineEditField;
605 }
606
607
608
609
610
611
612
613
614 public static void pushObjectToContext(Collection<? extends LifecycleElement> elements, String contextName,
615 Object contextValue) {
616 if (elements == null || elements.isEmpty()) {
617 return;
618 }
619
620 Queue<LifecycleElement> elementQueue = new LinkedList<LifecycleElement>();
621
622 try {
623 elementQueue.addAll(elements);
624 while (!elementQueue.isEmpty()) {
625 LifecycleElement currentElement = elementQueue.poll();
626
627 if (currentElement == null) {
628 continue;
629 }
630
631 if (currentElement instanceof Component) {
632 ((Component) currentElement).pushObjectToContext(contextName, contextValue);
633 }
634
635 elementQueue.addAll(ViewLifecycleUtils.getElementsForLifecycle(currentElement).values());
636 }
637 } finally {
638 elementQueue.clear();
639 RecycleUtils.recycle(elementQueue);
640 }
641 }
642
643
644
645
646
647
648
649
650
651
652
653 public static void pushObjectToContext(Component component, String contextName, Object contextValue) {
654 if (component == null) {
655 return;
656 }
657
658 pushObjectToContext(Collections.singletonList(component), contextName, contextValue);
659 }
660
661
662
663
664
665
666
667 public static void pushAllToContext(List<? extends Component> components, Map<String, Object> sourceContext) {
668 if (components == null || components.isEmpty()) {
669 return;
670 }
671
672 @SuppressWarnings("unchecked") Queue<LifecycleElement> elementQueue = RecycleUtils.getInstance(
673 LinkedList.class);
674 try {
675 elementQueue.addAll(components);
676 while (!elementQueue.isEmpty()) {
677 LifecycleElement currentElement = elementQueue.poll();
678
679 if (currentElement == null) {
680 continue;
681 }
682
683 if (currentElement instanceof Component) {
684 ((Component) currentElement).pushAllToContext(sourceContext);
685 }
686
687 elementQueue.addAll(ViewLifecycleUtils.getElementsForLifecycle(currentElement).values());
688 }
689 } finally {
690 elementQueue.clear();
691 RecycleUtils.recycle(elementQueue);
692 }
693 }
694
695
696
697
698
699
700
701
702
703
704 public static void pushAllToContext(Component component, Map<String, Object> sourceContext) {
705 if (component == null) {
706 return;
707 }
708
709 pushAllToContext(Collections.singletonList(component), sourceContext);
710 }
711
712
713
714
715
716
717
718
719
720
721
722
723 public static void updateContextsForLine(List<? extends Component> components, CollectionGroup collectionGroup,
724 Object collectionLine, int lineIndex, String lineSuffix) {
725 for (Component component : components) {
726 updateContextForLine(component, collectionGroup, collectionLine, lineIndex, lineSuffix);
727 }
728 }
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743 public static void updateContextForLine(Component component, CollectionGroup collectionGroup, Object collectionLine,
744 int lineIndex, String lineSuffix) {
745
746
747 if (StringUtils.isNotBlank(collectionGroup.getContainerIdSuffix())) {
748 lineSuffix = lineSuffix + collectionGroup.getContainerIdSuffix();
749 }
750
751 Map<String, Object> toUpdate = new HashMap<String, Object>(5);
752 toUpdate.put(UifConstants.ContextVariableNames.COLLECTION_GROUP, collectionGroup);
753 toUpdate.put(UifConstants.ContextVariableNames.LINE, collectionLine);
754 toUpdate.put(UifConstants.ContextVariableNames.INDEX, Integer.valueOf(lineIndex));
755 toUpdate.put(UifConstants.ContextVariableNames.LINE_SUFFIX, lineSuffix);
756
757 boolean isAddLine = (lineIndex == -1);
758 toUpdate.put(UifConstants.ContextVariableNames.IS_ADD_LINE, isAddLine);
759 pushAllToContext(component, toUpdate);
760 }
761
762
763
764
765
766
767
768 public static void cleanContextDeap(LifecycleElement lifecycleElement) {
769 if (lifecycleElement == null) {
770 return;
771 }
772
773 lifecycleElement.setContext(null);
774
775
776 Class<?> elementClass = lifecycleElement.getClass();
777
778 List<java.lang.reflect.Field> fields = ReflectionUtils.getAllFields(elementClass);
779 for (java.lang.reflect.Field field : fields) {
780
781 if (Collection.class.isAssignableFrom(field.getType())) {
782 ReflectionUtils.makeAccessible(field);
783 Collection<Object> elements = (Collection<Object>) ReflectionUtils.getField(field, lifecycleElement);
784 if (elements != null) {
785 for (Object element : elements) {
786 if (element != null && LifecycleElement.class.isAssignableFrom(element.getClass())) {
787 cleanContextDeap((LifecycleElement) element);
788 }
789 }
790 }
791
792 } else if (Map.class.isAssignableFrom(field.getType())) {
793 ReflectionUtils.makeAccessible(field);
794 Map<Object, Object> elements = (Map<Object, Object>) ReflectionUtils.getField(field, lifecycleElement);
795 if (elements != null) {
796 for (Object element : elements.entrySet()) {
797 if (element != null && LifecycleElement.class.isAssignableFrom(element.getClass())) {
798 cleanContextDeap((LifecycleElement) element);
799 }
800 }
801 }
802
803 } else if (LifecycleElement.class.isAssignableFrom(field.getType())) {
804 ReflectionUtils.makeAccessible(field);
805 LifecycleElement nestedElement = (LifecycleElement) ReflectionUtils.getField(field, lifecycleElement);
806
807 cleanContextDeap(nestedElement);
808 }
809 }
810 }
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833 public static <T extends Ordered> List<T> sort(List<T> items, int defaultOrderSequence) {
834 if (items == null) {
835 return null;
836 }
837
838 List<T> orderedItems = new ArrayList<T>(items.size());
839
840
841 Set<Integer> foundOrders = new HashSet<Integer>();
842
843
844 for (int i = items.size() - 1; i >= 0; i--) {
845 T component = items.get(i);
846 int order = component.getOrder();
847
848
849 if (order == 0) {
850 orderedItems.add(component);
851 }
852
853 else if (!foundOrders.contains(Integer.valueOf(order))) {
854 orderedItems.add(component);
855 foundOrders.add(Integer.valueOf(order));
856 }
857 }
858
859
860
861 for (int i = 0; i < items.size(); i++) {
862 Ordered component = items.get(i);
863 int order = component.getOrder();
864
865
866 if (order == 0) {
867 defaultOrderSequence++;
868 while (foundOrders.contains(Integer.valueOf(defaultOrderSequence))) {
869 defaultOrderSequence++;
870 }
871 component.setOrder(defaultOrderSequence);
872 }
873 }
874
875
876 Collections.sort(orderedItems, new OrderComparator());
877
878 return orderedItems;
879 }
880
881
882
883
884
885
886
887
888
889 public static List<InputField> getAllInputFieldsWithinContainer(Container container) {
890 List<InputField> inputFields = new ArrayList<InputField>();
891
892 for (LifecycleElement c : ViewLifecycleUtils.getElementsForLifecycle(container).values()) {
893 if (c instanceof InputField) {
894 inputFields.add((InputField) c);
895 } else if (c instanceof Container) {
896 inputFields.addAll(getAllInputFieldsWithinContainer((Container) c));
897 } else if (c instanceof FieldGroup) {
898 Container cb = ((FieldGroup) c).getGroup();
899
900 inputFields.addAll(getAllInputFieldsWithinContainer(cb));
901 }
902 }
903
904 return inputFields;
905 }
906
907
908
909
910
911
912
913
914
915
916 public static boolean containsPropertyExpression(Component component, String propertyName,
917 boolean collectionMatch) {
918 boolean hasExpression = false;
919
920 Map<String, String> propertyExpressions = component.getPropertyExpressions();
921
922 if (collectionMatch) {
923 for (String expressionPropertyName : propertyExpressions.keySet()) {
924 if (expressionPropertyName.startsWith(propertyName)) {
925 hasExpression = true;
926 }
927 }
928 } else if (propertyExpressions.containsKey(propertyName)) {
929 hasExpression = true;
930 }
931
932 return hasExpression;
933 }
934
935
936
937
938
939
940
941
942 public static void adjustNestedLevelsForTableCollections(Container container, int currentLevel) {
943 if (container != null
944 && container instanceof CollectionGroup
945 && container.getLayoutManager() != null
946 && container.getLayoutManager() instanceof TableLayoutManager
947 && ((TableLayoutManager) container.getLayoutManager()).getRichTable() != null
948 && ((TableLayoutManager) container.getLayoutManager()).getRichTable().isRender()
949 && ((TableLayoutManager) container.getLayoutManager()).getRichTable().isForceLocalJsonData()) {
950 ((TableLayoutManager) container.getLayoutManager()).getRichTable().setNestedLevel(currentLevel);
951 currentLevel++;
952 }
953
954 if (container != null) {
955 List<Container> subContainers = ViewLifecycleUtils.getNestedElementsOfTypeShallow(container,
956 Container.class);
957 for (Container subContainer : subContainers) {
958 adjustNestedLevelsForTableCollections(subContainer, currentLevel);
959 }
960
961 List<FieldGroup> subFieldGroups = ViewLifecycleUtils.getNestedElementsOfTypeShallow(container,
962 FieldGroup.class);
963 for (FieldGroup fieldGroup : subFieldGroups) {
964 if (fieldGroup != null) {
965 adjustNestedLevelsForTableCollections(fieldGroup.getGroup(), currentLevel);
966 }
967 }
968 }
969 }
970
971 }