View Javadoc

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 	    		//set has-data/requires data style here
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 						//TODO handle custom widgets (multiplicity field widget initializer)
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         		//set has-data/requires data style here
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 						//TODO handle custom widgets (multiplicity field widget initializer)
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         		//Alternate label possibly here
268         		parentRow.setTitle(config.getItemLabel());
269         		parentRow.setRequired(false);
270         		parentRow.setKey(config.getParentFd().getFieldKey());
271         		//set unrequired style here
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                 //GWT.log("ComparisonModel cannot be found. " + cause.getLocalizedMessage(), null);
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                 // for the first column
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                 // the second column
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 }