1 package org.kuali.student.common.ui.client.widgets.table.summary;
2
3 import java.util.ArrayList;
4 import java.util.Iterator;
5 import java.util.List;
6 import java.util.Map;
7
8 import org.kuali.student.common.assembly.data.Data;
9 import org.kuali.student.common.assembly.data.MetadataInterrogator;
10 import org.kuali.student.common.assembly.data.QueryPath;
11 import org.kuali.student.common.assembly.data.Data.Property;
12 import org.kuali.student.common.ui.client.configurable.mvc.FieldDescriptor;
13 import org.kuali.student.common.ui.client.configurable.mvc.FieldDescriptorReadOnly;
14 import org.kuali.student.common.ui.client.configurable.mvc.SectionTitle;
15 import org.kuali.student.common.ui.client.configurable.mvc.binding.ModelWidgetBinding;
16 import org.kuali.student.common.ui.client.configurable.mvc.multiplicity.MultiplicityConfiguration;
17 import org.kuali.student.common.ui.client.configurable.mvc.multiplicity.MultiplicityFieldConfiguration;
18 import org.kuali.student.common.ui.client.configurable.mvc.sections.Section;
19 import org.kuali.student.common.ui.client.configurable.mvc.sections.VerticalSection;
20 import org.kuali.student.common.ui.client.mvc.Controller;
21 import org.kuali.student.common.ui.client.mvc.DataModel;
22 import org.kuali.student.common.ui.client.mvc.ModelRequestCallback;
23 import org.kuali.student.common.validation.dto.ValidationResultInfo;
24 import org.kuali.student.common.validation.dto.ValidationResultInfo.ErrorLevel;
25
26 import com.google.gwt.core.client.GWT;
27 import com.google.gwt.user.client.ui.Widget;
28
29 public class SummaryTableSection extends VerticalSection {
30 SummaryTable summaryTable = new SummaryTable();
31 SummaryTableModel summaryTableModel = new SummaryTableModel();
32 Controller controller;
33 DataModel comparisonModel = null;
34 List<ShowRowConditionCallback> showRowCallbacks = new ArrayList<ShowRowConditionCallback>();
35
36 public SummaryTableSection(Controller controller) {
37 super();
38 this.controller = controller;
39 this.addWidget(summaryTable);
40 summaryTable.setModel(summaryTableModel);
41 }
42
43 public SummaryTableSection(Controller controller, SectionTitle title) {
44 super(title);
45 this.controller = controller;
46 this.addWidget(summaryTable);
47 summaryTable.setModel(summaryTableModel);
48 }
49
50 public void setContentColumnHeader1(String title) {
51 summaryTableModel.setContentColumnHeader1(title);
52 }
53
54 public void setContentColumnHeader2(String title) {
55 summaryTableModel.setContentColumnHeader2(title);
56 }
57
58 public String getContentColumnHeader1() {
59 return summaryTableModel.getContentColumnHeader1();
60 }
61
62 public String getContentColumnHeader2() {
63 return summaryTableModel.getContentColumnHeader2();
64 }
65
66 public void setEditable(boolean bool) {
67 summaryTableModel.setEditable(bool);
68 summaryTable.doLayout();
69 summaryTable.markDiffs("rowDiffHighlight");
70 }
71
72 public void addShowRowCallback(ShowRowConditionCallback callback){
73 this.showRowCallbacks.add(callback);
74 }
75
76 private void processShowConditions(SummaryTableFieldRow row, DataModel model, DataModel comparisonModel){
77 for(int i =0; i < showRowCallbacks.size(); i++){
78 showRowCallbacks.get(i).processShowConditions(row, model, comparisonModel);
79 }
80 }
81
82 public void addSummaryTableFieldBlock(SummaryTableFieldBlock section) {
83 summaryTableModel.addSection(section);
84 }
85
86 @Override
87 public ErrorLevel processValidationResults(
88 List<ValidationResultInfo> results) {
89 ErrorLevel status = ErrorLevel.OK;
90 for(int i = 0; i < results.size(); i++){
91 if(summaryTable.containsKey(results.get(i).getElement())){
92 System.out.println(results.get(i).getElement() + " *** " + results.get(i).getErrorLevel() + " *** " + results.get(i).getMessage());
93 if(results.get(i).getLevel().getLevel() > status.getLevel()){
94 status = results.get(i).getLevel();
95 }
96 if(this.isValidationEnabled){
97 summaryTable.highlightRow(results.get(i).getElement(), "rowHighlight");
98 }
99 }
100 }
101 return status;
102 }
103
104 @Override
105 public ErrorLevel processValidationResults(
106 List<ValidationResultInfo> results, boolean clearAllValidation) {
107 if(clearAllValidation){
108 this.removeValidationHighlighting();
109 }
110 return this.processValidationResults(results);
111 }
112
113 public void removeValidationHighlighting(){
114 summaryTable.clearHighlightedRows("rowHighlight");
115 }
116
117 private int buildMultiplicityRows(DataModel model, DataModel compModel, SummaryTableMultiplicityFieldRow parentRow,
118 List<SummaryTableRow> rowList, int styleLevel, Integer parentNum){
119 MultiplicityConfiguration config = parentRow.getConfig();
120 int index = rowList.indexOf(parentRow) + 1;
121 int fieldRowsCreated = 0;
122 int number = 0;
123 String path = parentRow.getConfig().getParentFd().getFieldKey();
124 if(parentNum != null){
125 path = path.replace("*", "" + parentNum);
126 }
127 Data data = null;
128 if(model != null && model.isValidPath(path)){
129 data = model.get(QueryPath.parse(path));
130 }
131 Data compData = null;
132 if(compModel != null && compModel.isValidPath(path)){
133 compData = compModel.get(QueryPath.parse(path));
134 }
135 if((data != null && data.size() > 0) || (compData != null && compData.size() > 0)){
136 Iterator<Property> itr = null;
137 if(data != null && compData != null){
138 if(data.size() >= compData.size()){
139 itr = data.iterator();
140 }
141 else{
142 itr = compData.iterator();
143 }
144 }
145 else if(data != null){
146 itr = data.iterator();
147 }
148 else{
149 itr = compData.iterator();
150 }
151 SummaryTableMultiplicityFieldRow currentMultiplicityRow = parentRow;
152 while (itr.hasNext()) {
153 Property p = (Property) itr.next();
154 if (p.getKey() instanceof Integer){
155 number = (Integer)p.getKey();
156 }
157 if(config.getItemLabel() != null && !config.getItemLabel().isEmpty()){
158 currentMultiplicityRow.setTitle(config.getItemLabel() + " "+ (number + 1));
159 currentMultiplicityRow.setKey(path);
160 if(MetadataInterrogator.isRequired(config.getMetaData()) ||
161 MetadataInterrogator.isRequiredForNextState(config.getMetaData())){
162 currentMultiplicityRow.setRequired(true);
163 }
164 currentMultiplicityRow.addTitleCellStyleName("summary-table-multiplicity-level-" + styleLevel);
165 }
166 else{
167 currentMultiplicityRow.setShown(false);
168 }
169
170 Map<Integer, List<MultiplicityFieldConfiguration>> fieldsCopy = config.getFields();
171 for(int i = 0; i < config.getFields().size(); i++){
172 for(int j = 0; j < config.getFields().get(i).size(); j++){
173
174 MultiplicityFieldConfiguration field = fieldsCopy.get(i).get(j);
175 String fieldKey = translatePath(field.getFieldPath(), path, number);
176 FieldDescriptorReadOnly fd1 = new FieldDescriptorReadOnly(fieldKey, field.getMessageKeyInfo(), field.getMetadata());
177 fd1.setOptional(field.isOptional());
178 if(field.getModelWidgetBinding() != null){
179 fd1.setWidgetBinding(field.getModelWidgetBinding());
180 }
181 FieldDescriptorReadOnly fd2 = new FieldDescriptorReadOnly(fieldKey, field.getMessageKeyInfo(), field.getMetadata());
182 fd2.setOptional(field.isOptional());
183 if(field.getModelWidgetBinding() != null){
184 fd2.setWidgetBinding(field.getModelWidgetBinding());
185 }
186 SummaryTableFieldRow row = new SummaryTableFieldRow(fd1, fd2);
187 row.setTemporaryRowFlag(true);
188 rowList.add(index, row);
189 index++;
190 fieldRowsCreated++;
191 }
192 }
193
194 if(config.getNestedConfig() != null){
195 MultiplicityConfiguration nestedConfig = config.getNestedConfig();
196 nestedConfig.getParentFd().getFieldKey().replace(config.getParentFd().getFieldKey(), path);
197 SummaryTableMultiplicityFieldRow mRow = new SummaryTableMultiplicityFieldRow(nestedConfig);
198 mRow.setTemporaryRowFlag(true);
199 rowList.add(index, mRow);
200 index++;
201 fieldRowsCreated++;
202 int result = buildMultiplicityRows(model, compModel, mRow, rowList, styleLevel + 1, number);
203 index = index + result;
204
205 }
206
207 if(itr.hasNext()){
208 SummaryTableMultiplicityFieldRow mRow = new SummaryTableMultiplicityFieldRow(config);
209 mRow.setTemporaryRowFlag(true);
210 rowList.add(index, mRow);
211 index++;
212 fieldRowsCreated++;
213 currentMultiplicityRow = mRow;
214 }
215 }
216 }
217 else{
218 if(MetadataInterrogator.isRequired(config.getMetaData()) ||
219 MetadataInterrogator.isRequiredForNextState(config.getMetaData())){
220 if(config.getItemLabel() != null && !config.getItemLabel().isEmpty()){
221 parentRow.setTitle(config.getItemLabel() + " "+ (number + 1));
222 parentRow.setKey(path);
223 parentRow.setRequired(true);
224 parentRow.addTitleCellStyleName("summary-table-multiplicity-level-" + styleLevel);
225 }
226 else{
227 parentRow.setShown(false);
228 }
229
230 Map<Integer, List<MultiplicityFieldConfiguration>> fields = config.getFields();
231 for(int i = 0; i < fields.size(); i++){
232 for(int j = 0; j < fields.get(i).size(); j++){
233
234 MultiplicityFieldConfiguration field = fields.get(i).get(j);
235 String fieldKey = translatePath(field.getFieldPath(), path, number);
236 FieldDescriptorReadOnly fd1 = new FieldDescriptorReadOnly(fieldKey, field.getMessageKeyInfo(), field.getMetadata());
237 fd1.setOptional(field.isOptional());
238 if(field.getModelWidgetBinding() != null){
239 fd1.setWidgetBinding(field.getModelWidgetBinding());
240 }
241 FieldDescriptorReadOnly fd2 = new FieldDescriptorReadOnly(fieldKey, field.getMessageKeyInfo(), field.getMetadata());
242 fd2.setOptional(field.isOptional());
243 if(field.getModelWidgetBinding() != null){
244 fd2.setWidgetBinding(field.getModelWidgetBinding());
245 }
246 SummaryTableFieldRow row = new SummaryTableFieldRow(fd1, fd2);
247 row.setTemporaryRowFlag(true);
248 rowList.add(index, row);
249 index++;
250 fieldRowsCreated++;
251 }
252 }
253
254
255 if(config.getNestedConfig() != null){
256 MultiplicityConfiguration nestedConfig = config.getNestedConfig();
257 nestedConfig.getParentFd().getFieldKey().replace(config.getParentFd().getFieldKey(), path);
258 SummaryTableMultiplicityFieldRow mRow = new SummaryTableMultiplicityFieldRow(nestedConfig);
259 mRow.setTemporaryRowFlag(true);
260 rowList.add(index, mRow);
261 index++;
262 fieldRowsCreated++;
263 buildMultiplicityRows(null, null, mRow, rowList, styleLevel + 1, number);
264 }
265 }
266 else{
267
268 parentRow.setTitle(config.getItemLabel());
269 parentRow.setRequired(false);
270 parentRow.setKey(config.getParentFd().getFieldKey());
271
272 }
273 }
274 return fieldRowsCreated;
275 }
276
277 public String translatePath(String path, String parentPath, int num) {
278 String fieldPath;
279 if (parentPath != null) {
280 QueryPath parent = QueryPath.concat(parentPath);
281 int i = parent.size();
282
283 QueryPath subPath = QueryPath.concat(path);
284 String itemPath = subPath.subPath(i, subPath.size()).toString();
285
286 QueryPath qp = QueryPath.concat(parentPath, itemPath);
287 fieldPath = qp.toString();
288 }
289 else {
290 fieldPath = path;
291 }
292
293 fieldPath = fieldPath.replace("*", "" + num);
294 return fieldPath;
295 }
296
297 @Override
298 public void updateWidgetData(final DataModel model) {
299
300 controller.requestModel("ComparisonModel", new ModelRequestCallback<DataModel>() {
301 @Override
302 public void onModelReady(DataModel otherModel) {
303 comparisonModel = otherModel;
304 updateTableData(model);
305 }
306
307 @Override
308 public void onRequestFail(Throwable cause) {
309 comparisonModel = null;
310 updateTableData(model);
311
312 }
313 });
314 }
315
316 private void resetSummaryTableRows(SummaryTableFieldBlock fieldBlock){
317 List<SummaryTableRow> rowList = fieldBlock.getSectionRowList();
318 List<SummaryTableRow> removeList = new ArrayList<SummaryTableRow>();
319 for (int j = 0; j < rowList.size(); j++) {
320 SummaryTableFieldRow fieldRow = (SummaryTableFieldRow) rowList.get(j);
321 if(fieldRow.isTemporaryRow()){
322 removeList.add(fieldRow);
323 }
324 if(!fieldRow.isShown()){
325 fieldRow.setShown(true);
326 }
327 }
328 rowList.removeAll(removeList);
329 }
330
331 private void buildSummaryTableMultiplicity(DataModel model, DataModel compModel, SummaryTableFieldBlock fieldBlock){
332 List<SummaryTableMultiplicityFieldRow> mRows = fieldBlock.getMultiplicityList();
333 for(int i = 0; i < mRows.size(); i++){
334 SummaryTableMultiplicityFieldRow mRow = mRows.get(i);
335
336 buildMultiplicityRows(model, compModel, mRow, fieldBlock.getSectionRowList(), 1, null);
337 }
338 }
339
340 @SuppressWarnings("unchecked")
341 private void updateTableData(DataModel model){
342 List<SummaryTableBlock> sectionList = summaryTableModel.getSectionList();
343 for (int i = 0; i < sectionList.size(); i++) {
344 SummaryTableFieldBlock fieldBlock = (SummaryTableFieldBlock) sectionList.get(i);
345 resetSummaryTableRows(fieldBlock);
346 if(!fieldBlock.getMultiplicityList().isEmpty()){
347 buildSummaryTableMultiplicity(model, comparisonModel, fieldBlock);
348 }
349 List<SummaryTableRow> rowList = fieldBlock.getSectionRowList();
350
351 for (int j = 0; j < rowList.size(); j++) {
352 SummaryTableFieldRow fieldRow = (SummaryTableFieldRow) rowList.get(j);
353 FieldDescriptor field = fieldRow.getFieldDescriptor1();
354 final FieldDescriptor field2 = fieldRow.getFieldDescriptor2();
355 boolean optional = false;
356 boolean firstValueEmpty = true;
357 boolean secondValueEmpty = true;
358
359 if(field != null){
360
361 if(field instanceof FieldDescriptorReadOnly){
362 optional = ((FieldDescriptorReadOnly)field).isOptional();
363 }
364 String fieldPath = QueryPath.getPathSeparator() + field.getFieldKey();
365 if(model.isValidPath(fieldPath)){
366
367 Object value = model.get(QueryPath.parse(fieldPath));
368 if(value != null){
369 if(value instanceof String && ((String)value).isEmpty()){
370 firstValueEmpty = true;
371 }
372 else if(value instanceof Data && ((Data) value).size() == 0){
373 firstValueEmpty = true;
374 }
375 else{
376 firstValueEmpty = false;
377 }
378 }
379
380
381 ModelWidgetBinding binding = field.getModelWidgetBinding();
382
383 if (binding != null) {
384 Widget w = field.getFieldWidget();
385 binding.setWidgetValue(w, model, fieldPath);
386 } else {
387 GWT.log(field.getFieldKey() + " has no widget binding.", null);
388 }
389 }
390
391 }
392
393
394 if (comparisonModel == null) {
395 if(fieldRow.getContentCellCount() == 2){
396 fieldRow.setContentCellCount(1);
397 }
398 }else{
399 summaryTableModel.setContentColumnHeader1(model.getModelName());
400 summaryTableModel.setContentColumnHeader2(comparisonModel.getModelName());
401 if(fieldRow.getContentCellCount() == 1){
402 fieldRow.setContentCellCount(2);
403 }
404 if(field2 != null){
405
406 String fieldPath2 = QueryPath.getPathSeparator() + field2.getFieldKey();
407 if(comparisonModel.isValidPath(fieldPath2)){
408
409 Object value = model.get(QueryPath.parse(fieldPath2));
410 if(value != null){
411 if(value instanceof String && ((String)value).isEmpty()){
412 secondValueEmpty = true;
413 }
414 else if(value instanceof Data && ((Data) value).size() == 0){
415 secondValueEmpty = true;
416 }
417 else{
418 secondValueEmpty = false;
419 }
420 }
421
422 ModelWidgetBinding binding2 = field2.getModelWidgetBinding();
423
424 if (binding2 != null) {
425 Widget w = field2.getFieldWidget();
426 binding2.setWidgetValue(w, comparisonModel, fieldPath2);
427 } else {
428 GWT.log(field2.getFieldKey() + " has no widget binding for the ComparisonModel.", null);
429 }
430 }
431 }
432 }
433
434 if(firstValueEmpty && secondValueEmpty && optional){
435 fieldRow.setShown(false);
436 }
437 processShowConditions(fieldRow, model, comparisonModel);
438 }
439
440 }
441
442 summaryTable.doLayout();
443 summaryTable.markDiffs("rowDiffHighlight");
444 }
445
446 @Override
447 public String addField(FieldDescriptor fieldDescriptor) {
448 GWT.log("addField(FieldDescriptor fieldDescriptor) method not supported");
449 throw new UnsupportedOperationException("SummaryTableSection.addField(FieldDescriptor fieldDescriptor) method not supported");
450 }
451
452 @Override
453 public String addSection(Section section) {
454 GWT.log("addSection(Section section) method not supported");
455 throw new UnsupportedOperationException("SummaryTableSection.addSection(Section section) method not supported");
456 }
457
458 @Override
459 public String addSection(String key, Section section) {
460 GWT.log("addSection(String key, Section section) method not supported");
461 throw new UnsupportedOperationException("SummaryTableSection.addSection(String key, Section section) method not supported");
462 }
463
464 }