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