1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.kuali.student.cm.course.modifiers;
18
19 import org.apache.commons.lang.StringUtils;
20 import org.kuali.rice.krad.uif.UifConstants;
21 import org.kuali.rice.krad.uif.UifPropertyPaths;
22 import org.kuali.rice.krad.uif.component.Component;
23 import org.kuali.rice.krad.uif.container.CollectionGroup;
24 import org.kuali.rice.krad.uif.container.Group;
25 import org.kuali.rice.krad.uif.element.Header;
26 import org.kuali.rice.krad.uif.field.DataField;
27 import org.kuali.rice.krad.uif.field.DataFieldBase;
28 import org.kuali.rice.krad.uif.field.Field;
29 import org.kuali.rice.krad.uif.field.SpaceField;
30 import org.kuali.rice.krad.uif.layout.GridLayoutManager;
31 import org.kuali.rice.krad.uif.lifecycle.ViewLifecycle;
32 import org.kuali.rice.krad.uif.lifecycle.ViewLifecycleUtils;
33 import org.kuali.rice.krad.uif.modifier.ComparableInfo;
34 import org.kuali.rice.krad.uif.modifier.CompareFieldCreateModifier;
35 import org.kuali.rice.krad.uif.util.ComponentFactory;
36 import org.kuali.rice.krad.uif.util.ComponentUtils;
37 import org.kuali.rice.krad.uif.util.ObjectPropertyUtils;
38 import org.kuali.rice.krad.uif.view.ExpressionEvaluator;
39 import org.kuali.rice.krad.uif.view.View;
40
41 import java.util.ArrayList;
42 import java.util.HashMap;
43 import java.util.List;
44 import java.util.Map;
45
46
47
48
49
50
51
52 public class CMCourseFieldCompareModifier extends CompareFieldCreateModifier{
53
54
55
56
57 private List<String> excludeProperties = new ArrayList<>();
58
59
60
61
62
63
64
65
66
67 @Override
68 public void performModification(Object model, Component component) {
69 if ((component != null) && !(component instanceof Group)) {
70 throw new IllegalArgumentException(
71 "Compare field initializer only support Group components, found type: " + component.getClass());
72 }
73
74 if (component == null) {
75 return;
76 }
77
78 Group group = (Group) component;
79
80
81 List<Component> comparisonItems = new ArrayList<Component>();
82
83
84 List<ComparableInfo> groupComparables = (List<ComparableInfo>) ComponentUtils.sort(getComparables(),
85 getDefaultOrderSequence());
86
87
88 Map<String, Object> context = new HashMap<String, Object>();
89
90 View view = ViewLifecycle.getView();
91
92 Map<String, Object> viewContext = view.getContext();
93 if (viewContext != null) {
94 context.putAll(view.getContext());
95 }
96
97 context.put(UifConstants.ContextVariableNames.COMPONENT, component);
98
99 ExpressionEvaluator expressionEvaluator = ViewLifecycle.getExpressionEvaluator();
100
101 for (ComparableInfo comparable : groupComparables) {
102 expressionEvaluator.evaluateExpressionsOnConfigurable(view, comparable, context);
103 }
104
105
106 if (isGenerateCompareHeaders()) {
107
108 SpaceField spaceField = ComponentFactory.getSpaceField();
109 comparisonItems.add(spaceField);
110
111 for (ComparableInfo comparable : groupComparables) {
112 Header compareHeaderField = ComponentUtils.copy(getHeaderFieldPrototype(), comparable.getIdSuffix());
113 compareHeaderField.setHeaderText(comparable.getHeaderText());
114 comparisonItems.add(compareHeaderField);
115 }
116
117
118 if (group.getLayoutManager() instanceof GridLayoutManager) {
119 ((GridLayoutManager) group.getLayoutManager()).setRenderFirstRowHeader(true);
120 }
121 }
122
123
124
125 boolean performValueChangeComparison = false;
126 String compareValueObjectBindingPath = null;
127 for (ComparableInfo comparable : groupComparables) {
128 if (comparable.isCompareToForValueChange()) {
129 performValueChangeComparison = true;
130 compareValueObjectBindingPath = comparable.getBindingObjectPath();
131 }
132 }
133
134
135 int index = 0;
136 List<String> rowCssClasses = new ArrayList<>();
137
138 for (Component item : group.getItems()) {
139
140
141 boolean excluded = false;
142 if (item instanceof DataFieldBase) {
143 String bindingPath = ((DataFieldBase) item).getBindingInfo().getBindingPath();
144 if (StringUtils.isNotBlank(bindingPath)) {
145 for (String exclude : getExcludeProperties()) {
146 if (bindingPath.endsWith(exclude)) {
147 excluded = true;
148 break;
149 }
150 }
151 }
152 }
153
154 String rowCSS = "";
155 int defaultSuffix = 0;
156 boolean suppressLabel = false;
157
158 for (ComparableInfo comparable : groupComparables) {
159 String idSuffix = comparable.getIdSuffix();
160 if (StringUtils.isBlank(idSuffix)) {
161 idSuffix = UifConstants.IdSuffixes.COMPARE + defaultSuffix;
162 }
163
164 Component compareItem = ComponentUtils.copy(item, idSuffix);
165
166 ComponentUtils.setComponentPropertyDeep(compareItem, UifPropertyPaths.BIND_OBJECT_PATH,
167 comparable.getBindingObjectPath());
168
169
170 List<CollectionGroup> collectionGroups = ViewLifecycleUtils.getElementsOfTypeDeep(compareItem, CollectionGroup.class);
171
172 for (CollectionGroup collectionGroup : collectionGroups){
173 updateCollectionGroupBindingPath(collectionGroup,comparable.getBindingObjectPath());
174 }
175
176 if (comparable.isReadOnly()) {
177 compareItem.setReadOnly(true);
178 if (compareItem.getPropertyExpressions().containsKey("readOnly")) {
179 compareItem.getPropertyExpressions().remove("readOnly");
180 }
181 }
182
183
184 if (suppressLabel && (compareItem instanceof Field)) {
185 ((Field) compareItem).getFieldLabel().setRender(false);
186 }
187
188
189 if (performValueChangeComparison && comparable.isHighlightValueChange() && !comparable
190 .isCompareToForValueChange() && ! excluded) {
191 boolean valueChanged = performValueComparison(group, compareItem, model,
192 compareValueObjectBindingPath);
193
194 if (valueChanged){
195 rowCSS = "cm-compare-highlighter";
196 }
197 }
198
199
200
201 if (excluded) {
202 item.setStyle("display: none;");
203 }
204
205 comparisonItems.add(compareItem);
206
207 defaultSuffix++;
208
209 suppressLabel = true;
210 }
211
212 rowCssClasses.add(rowCSS);
213
214 index++;
215 }
216
217 if (group.getLayoutManager() instanceof GridLayoutManager) {
218 ((GridLayoutManager) group.getLayoutManager()).setRowCssClasses(rowCssClasses);
219 }
220
221
222 group.setItems(comparisonItems);
223 }
224
225
226
227
228
229
230
231
232 protected void updateCollectionGroupBindingPath(CollectionGroup collectionGroup,String bindingPath){
233
234 ComponentUtils.setComponentPropertyDeep(collectionGroup, UifPropertyPaths.BIND_OBJECT_PATH,bindingPath);
235 ComponentUtils.setComponentPropertyDeep(collectionGroup, "fieldBindingObjectPath",bindingPath);
236
237 List<CollectionGroup> subCollection = collectionGroup.getSubCollections();
238 for (CollectionGroup subCollectionGroup1 : subCollection){
239 updateCollectionGroupBindingPath(subCollectionGroup1, bindingPath);
240 }
241
242 List<? extends Component> dataFields = collectionGroup.getItems();
243 for (Component field : dataFields) {
244 ComponentUtils.setComponentPropertyDeep(field, UifPropertyPaths.BIND_OBJECT_PATH,bindingPath);
245 ComponentUtils.setComponentPropertyDeep(field, "fieldBindingObjectPath",bindingPath);
246 if (field instanceof DataField) {
247 ((DataField)field).getBindingInfo().setBindingObjectPath(bindingPath);
248 }
249 }
250 }
251
252
253
254
255
256
257
258
259
260
261
262 @Override
263 protected boolean performValueComparison(Group group, Component compareItem, Object model,
264 String compareValueObjectBindingPath) {
265
266 List<DataField> itemFields = ViewLifecycleUtils.getElementsOfTypeDeep(compareItem, DataField.class);
267 boolean valueChanged = false;
268 for (DataField field : itemFields) {
269 String fieldBindingPath = field.getBindingInfo().getBindingPath();
270 Object fieldValue = ObjectPropertyUtils.getPropertyValue(model, fieldBindingPath);
271
272 String compareBindingPath = StringUtils.replaceOnce(fieldBindingPath,
273 field.getBindingInfo().getBindingObjectPath(), compareValueObjectBindingPath);
274 Object compareValue = ObjectPropertyUtils.getPropertyValue(model, compareBindingPath);
275
276 if (!((fieldValue == null) && (compareValue == null))) {
277
278 if ((fieldValue == null) || (compareValue == null)) {
279 valueChanged = true;
280 } else {
281
282 valueChanged = !fieldValue.equals(compareValue);
283 }
284 }
285 }
286 return valueChanged;
287 }
288
289
290
291
292
293 public List<String> getExcludeProperties() {
294 return excludeProperties;
295 }
296
297
298
299
300
301 public void setExcludeProperties(List<String> excludeProperties) {
302 this.excludeProperties = excludeProperties;
303 }
304
305 }