Coverage Report - org.kuali.student.lum.lu.ui.course.client.configuration.CourseSummaryConfigurer
 
Classes in this File Line Coverage Branch Coverage Complexity
CourseSummaryConfigurer
0%
0/264
0%
0/32
2.244
CourseSummaryConfigurer$1
0%
0/6
0%
0/4
2.244
CourseSummaryConfigurer$2
0%
0/3
N/A
2.244
CourseSummaryConfigurer$2$1
0%
0/6
0%
0/2
2.244
CourseSummaryConfigurer$2$1$1
0%
0/13
0%
0/2
2.244
CourseSummaryConfigurer$3
0%
0/3
N/A
2.244
CourseSummaryConfigurer$4
0%
0/13
0%
0/6
2.244
CourseSummaryConfigurer$5
0%
0/16
0%
0/22
2.244
CourseSummaryConfigurer$6
0%
0/11
0%
0/4
2.244
CourseSummaryConfigurer$7
0%
0/13
0%
0/6
2.244
CourseSummaryConfigurer$8
0%
0/16
0%
0/22
2.244
CourseSummaryConfigurer$9
0%
0/29
0%
0/10
2.244
CourseSummaryConfigurer$EditHandler
0%
0/5
N/A
2.244
 
 1  
 package org.kuali.student.lum.lu.ui.course.client.configuration;
 2  
 
 3  
 import java.util.ArrayList;
 4  
 import java.util.Arrays;
 5  
 import java.util.HashMap;
 6  
 import java.util.Iterator;
 7  
 import java.util.List;
 8  
 import java.util.Map;
 9  
 
 10  
 import org.kuali.student.common.assembly.data.Data;
 11  
 import org.kuali.student.common.assembly.data.Metadata;
 12  
 import org.kuali.student.common.assembly.data.QueryPath;
 13  
 import org.kuali.student.common.assembly.data.Data.Property;
 14  
 import org.kuali.student.common.dto.DtoConstants;
 15  
 import org.kuali.student.common.ui.client.application.Application;
 16  
 import org.kuali.student.common.ui.client.configurable.mvc.FieldDescriptorReadOnly;
 17  
 import org.kuali.student.common.ui.client.configurable.mvc.binding.ListToTextBinding;
 18  
 import org.kuali.student.common.ui.client.configurable.mvc.binding.ModelWidgetBinding;
 19  
 import org.kuali.student.common.ui.client.configurable.mvc.layouts.MenuSectionController;
 20  
 import org.kuali.student.common.ui.client.configurable.mvc.multiplicity.MultiplicityConfiguration;
 21  
 import org.kuali.student.common.ui.client.configurable.mvc.multiplicity.MultiplicityFieldConfiguration;
 22  
 import org.kuali.student.common.ui.client.configurable.mvc.sections.WarnContainer;
 23  
 import org.kuali.student.common.ui.client.configurable.mvc.views.VerticalSectionView;
 24  
 import org.kuali.student.common.ui.client.mvc.Callback;
 25  
 import org.kuali.student.common.ui.client.mvc.Controller;
 26  
 import org.kuali.student.common.ui.client.mvc.DataModel;
 27  
 import org.kuali.student.common.ui.client.mvc.DataModelDefinition;
 28  
 import org.kuali.student.common.ui.client.widgets.KSButton;
 29  
 import org.kuali.student.common.ui.client.widgets.KSLabel;
 30  
 import org.kuali.student.common.ui.client.widgets.KSButtonAbstract.ButtonStyle;
 31  
 import org.kuali.student.common.ui.client.widgets.field.layout.element.MessageKeyInfo;
 32  
 import org.kuali.student.common.ui.client.widgets.menus.KSListPanel;
 33  
 import org.kuali.student.common.ui.client.widgets.progress.BlockingTask;
 34  
 import org.kuali.student.common.ui.client.widgets.table.summary.ShowRowConditionCallback;
 35  
 import org.kuali.student.common.ui.client.widgets.table.summary.SummaryTableFieldBlock;
 36  
 import org.kuali.student.common.ui.client.widgets.table.summary.SummaryTableFieldRow;
 37  
 import org.kuali.student.common.ui.client.widgets.table.summary.SummaryTableSection;
 38  
 import org.kuali.student.common.validation.dto.ValidationResultInfo;
 39  
 import org.kuali.student.common.validation.dto.ValidationResultInfo.ErrorLevel;
 40  
 import org.kuali.student.core.document.ui.client.widgets.documenttool.DocumentList;
 41  
 import org.kuali.student.core.document.ui.client.widgets.documenttool.DocumentListBinding;
 42  
 import org.kuali.student.core.statement.dto.StatementTreeViewInfo;
 43  
 import org.kuali.student.core.statement.dto.StatementTypeInfo;
 44  
 import org.kuali.student.core.statement.ui.client.widgets.rules.SubrulePreviewWidget;
 45  
 import org.kuali.student.core.workflow.ui.client.widgets.WorkflowEnhancedNavController;
 46  
 import org.kuali.student.lum.common.client.lo.TreeStringBinding;
 47  
 import org.kuali.student.lum.common.client.lu.LUUIConstants;
 48  
 import org.kuali.student.lum.common.client.widgets.AppLocations;
 49  
 import org.kuali.student.lum.lu.assembly.data.client.constants.base.AcademicSubjectOrgInfoConstants;
 50  
 import org.kuali.student.lum.lu.assembly.data.client.constants.base.MetaInfoConstants;
 51  
 import org.kuali.student.lum.lu.assembly.data.client.constants.base.RichTextInfoConstants;
 52  
 import org.kuali.student.lum.lu.assembly.data.client.constants.orch.AffiliatedOrgInfoConstants;
 53  
 import org.kuali.student.lum.lu.assembly.data.client.constants.orch.CreditCourseActivityConstants;
 54  
 import org.kuali.student.lum.lu.assembly.data.client.constants.orch.CreditCourseConstants;
 55  
 import org.kuali.student.lum.lu.assembly.data.client.constants.orch.CreditCourseDurationConstants;
 56  
 import org.kuali.student.lum.lu.assembly.data.client.constants.orch.CreditCourseExpenditureInfoConstants;
 57  
 import org.kuali.student.lum.lu.assembly.data.client.constants.orch.CreditCourseFormatConstants;
 58  
 import org.kuali.student.lum.lu.assembly.data.client.constants.orch.CreditCourseJointsConstants;
 59  
 import org.kuali.student.lum.lu.assembly.data.client.constants.orch.CreditCourseProposalConstants;
 60  
 import org.kuali.student.lum.lu.assembly.data.client.constants.orch.CreditCourseProposalInfoConstants;
 61  
 import org.kuali.student.lum.lu.assembly.data.client.constants.orch.CreditCourseRevenueInfoConstants;
 62  
 import org.kuali.student.lum.lu.assembly.data.client.constants.orch.FeeInfoConstants;
 63  
 import org.kuali.student.lum.lu.assembly.data.client.constants.orch.LearningObjectiveConstants;
 64  
 import org.kuali.student.lum.lu.ui.course.client.configuration.CourseConfigurer.CourseSections;
 65  
 import org.kuali.student.lum.lu.ui.course.client.configuration.ViewCourseConfigurer.ViewCourseSections;
 66  
 import org.kuali.student.lum.lu.ui.course.client.controllers.CourseProposalController;
 67  
 import org.kuali.student.lum.lu.ui.course.client.controllers.VersionsController;
 68  
 import org.kuali.student.lum.lu.ui.course.client.requirements.CourseRequirementsSummaryView;
 69  
 import org.kuali.student.lum.lu.ui.course.client.requirements.HasRequirements;
 70  
 
 71  
 import com.google.gwt.core.client.GWT;
 72  
 import com.google.gwt.event.dom.client.ClickEvent;
 73  
 import com.google.gwt.event.dom.client.ClickHandler;
 74  
 import com.google.gwt.user.client.ui.Anchor;
 75  
 import com.google.gwt.user.client.ui.FlowPanel;
 76  
 import com.google.gwt.user.client.ui.HTML;
 77  
 import com.google.gwt.user.client.ui.Widget;
 78  
 
 79  0
 public class CourseSummaryConfigurer implements
 80  
         CreditCourseProposalConstants,
 81  
         CreditCourseProposalInfoConstants,
 82  
         CreditCourseConstants,
 83  
         CreditCourseFormatConstants,
 84  
         CreditCourseActivityConstants,
 85  
         MetaInfoConstants,
 86  
         CreditCourseDurationConstants,
 87  
         FeeInfoConstants,
 88  
         LearningObjectiveConstants,
 89  
         AcademicSubjectOrgInfoConstants,
 90  
         AffiliatedOrgInfoConstants,
 91  
         CreditCourseRevenueInfoConstants,
 92  
         CreditCourseExpenditureInfoConstants
 93  
 {
 94  
     //Override paths for course and proposal so they are root
 95  
     public static final String PROPOSAL = "";
 96  
     public static final String COURSE = "";
 97  
     public static final String PROPOSAL_TITLE_PATH = "proposal/name";
 98  0
     private List<ValidationResultInfo> validationInfos = new ArrayList<ValidationResultInfo>();
 99  0
     private boolean showingValidation = false;
 100  
     private static final String OPTIONAL = "o";
 101  
 
 102  0
     protected String type = "course";
 103  0
     protected String state = DtoConstants.STATE_DRAFT;
 104  
     protected String groupName;
 105  
     protected DataModelDefinition modelDefinition;
 106  
     private List<StatementTypeInfo> stmtTypes;
 107  
 
 108  
     private Controller controller;
 109  
     private SummaryTableSection tableSection;
 110  
     private String modelId;
 111  
 
 112  0
         private BlockingTask loadDataTask = new BlockingTask("Retrieving Data");
 113  
     
 114  
     private class EditHandler implements ClickHandler{
 115  
 
 116  
             Enum<?> view;
 117  
 
 118  0
             public EditHandler(Enum<?> view){
 119  0
                     this.view = view;
 120  0
             }
 121  
 
 122  
                 @Override
 123  
                 public void onClick(ClickEvent event) {
 124  0
                         controller.showView(view);
 125  0
                 }
 126  
     }
 127  
 
 128  
     public CourseSummaryConfigurer(String type, String state,
 129  0
             String groupName, DataModelDefinition modelDefinition, List<StatementTypeInfo> stmtTypes, Controller controller, String modelId) {
 130  0
         this.type = type;
 131  0
         this.state = state;
 132  0
         this.groupName = groupName;
 133  0
         this.modelDefinition = modelDefinition;
 134  0
         this.stmtTypes = stmtTypes;
 135  0
         this.controller = controller;
 136  0
         this.modelId = modelId;
 137  0
         tableSection = new SummaryTableSection((Controller)controller);
 138  0
     }
 139  
 
 140  
     protected VerticalSectionView initSectionView (Enum<?> viewEnum, String labelKey) {
 141  0
         VerticalSectionView section = new VerticalSectionView(viewEnum, getLabel(labelKey), modelId);
 142  0
         section.addStyleName(LUUIConstants.STYLE_SECTION);
 143  0
         return section;
 144  
     }
 145  
     protected String getLabel(String labelKey) {
 146  0
         return Application.getApplicationContext().getUILabel(groupName, type, state, labelKey);
 147  
     }
 148  
     protected MessageKeyInfo generateMessageInfo(String labelKey) {
 149  0
         return new MessageKeyInfo(groupName, type, state, labelKey);
 150  
     }
 151  
     protected SummaryTableFieldRow getFieldRow(String fieldKey, MessageKeyInfo messageKey) {
 152  0
         return getFieldRow(fieldKey, messageKey, null, null, null, null, false);
 153  
     }
 154  
     protected SummaryTableFieldRow getFieldRow(String fieldKey, MessageKeyInfo messageKey, boolean optional) {
 155  0
         return getFieldRow(fieldKey, messageKey, null, null, null, null, optional);
 156  
     }
 157  
 
 158  
     protected SummaryTableFieldRow getFieldRow(String fieldKey, MessageKeyInfo messageKey, Widget widget, Widget widget2, String parentPath, ModelWidgetBinding<?> binding, boolean optional) {
 159  0
         QueryPath path = QueryPath.concat(parentPath, fieldKey);
 160  0
         Metadata meta = modelDefinition.getMetadata(path);
 161  
 
 162  0
         FieldDescriptorReadOnly fd = new FieldDescriptorReadOnly(path.toString(), messageKey, meta);
 163  0
         if (widget != null) {
 164  0
             fd.setFieldWidget(widget);
 165  
         }
 166  0
         if(binding != null){
 167  0
                 fd.setWidgetBinding(binding);
 168  
         }
 169  0
         fd.setOptional(optional);
 170  
 
 171  0
         FieldDescriptorReadOnly fd2 = new FieldDescriptorReadOnly(path.toString(), messageKey, meta);
 172  0
         if (widget2 != null) {
 173  0
             fd2.setFieldWidget(widget2);
 174  
         }
 175  0
         if(binding != null){
 176  0
                 fd2.setWidgetBinding(binding);
 177  
         }
 178  0
         fd2.setOptional(optional);
 179  
 
 180  0
         SummaryTableFieldRow fieldRow = new SummaryTableFieldRow(fd,fd2);
 181  
 
 182  0
         return fieldRow;
 183  
     }
 184  
 
 185  
         public VerticalSectionView generateProposalSummarySection(boolean canEditSections){
 186  0
         tableSection.setEditable(canEditSections);
 187  0
         tableSection.addSummaryTableFieldBlock(generateCourseInformationForProposal());
 188  0
         tableSection.addSummaryTableFieldBlock(generateGovernanceSection());
 189  0
         tableSection.addSummaryTableFieldBlock(generateCourseLogisticsSection());
 190  0
         tableSection.addSummaryTableFieldBlock(generateLearningObjectivesSection());
 191  0
         tableSection.addSummaryTableFieldBlock(generateRequirementsSection());
 192  0
         tableSection.addSummaryTableFieldBlock(generateActiveDatesSection());
 193  0
         tableSection.addSummaryTableFieldBlock(generateFeesSection());
 194  0
         tableSection.addSummaryTableFieldBlock(generateProposalDocumentsSection());
 195  
         
 196  0
         if(controller instanceof WorkflowEnhancedNavController){
 197  
                 final WarnContainer infoContainer1;
 198  
                 final WarnContainer infoContainer2;
 199  
 
 200  0
                 infoContainer1 = generateWorkflowWidgetContainer(((WorkflowEnhancedNavController)controller).getWfUtilities().getWorkflowActionsWidget());
 201  0
                 infoContainer2 = generateWorkflowWidgetContainer(((WorkflowEnhancedNavController)controller).getWfUtilities().getWorkflowActionsWidget());
 202  
 
 203  0
                 ((WorkflowEnhancedNavController)controller).getWfUtilities().addSubmitCallback(new Callback<Boolean>(){
 204  
 
 205  
                                 @Override
 206  
                                 public void exec(Boolean result) {
 207  0
                                         if(result){
 208  0
                                                 tableSection.setEditable(false);
 209  0
                                                 if(controller instanceof MenuSectionController){
 210  0
                                                         ((MenuSectionController) controller).removeMenuNavigation();
 211  
                                                 }
 212  
                                         }
 213  
 
 214  0
                                 }
 215  
                         });
 216  
                 //Override beforeShow for summary section here to allow for custom validation mechanism on the table
 217  0
                 VerticalSectionView verticalSection = new VerticalSectionView(CourseSections.SUMMARY, getLabel(LUUIConstants.SUMMARY_LABEL_KEY), modelId){
 218  
                         @Override
 219  
                         public void beforeShow(final Callback<Boolean> onReadyCallback) {
 220  
 
 221  0
                                 super.beforeShow(new Callback<Boolean>(){
 222  
 
 223  
                                                 @Override
 224  
                                                 public void exec(final Boolean result) {
 225  0
                                                         if(result){
 226  
                                                                 //Make sure workflow actions and status updated before showing.
 227  0
                                                                 ((WorkflowEnhancedNavController)controller).getWfUtilities().refresh();
 228  
                                                                 
 229  
                                                                 //Show validation error if they exist
 230  0
                                                                 ((WorkflowEnhancedNavController)controller).getWfUtilities().doValidationCheck(new Callback<List<ValidationResultInfo>>(){
 231  
 
 232  
                                                                         @Override
 233  
                                                                         public void exec(
 234  
                                                                                         List<ValidationResultInfo> validationResult) {
 235  
                                                                                 //validationInfos = validationResult;
 236  0
                                                                                 tableSection.enableValidation(showingValidation);
 237  
                                                                                 
 238  
                                                                                 //FIXME: Handle validation warnings
 239  0
                                                                                 ErrorLevel isValid = tableSection.processValidationResults(validationResult, true);
 240  
 
 241  0
                                                                                 validationInfos = validationResult;
 242  0
                                                         if(isValid == ErrorLevel.OK){
 243  0
                                                                         infoContainer1.showWarningLayout(false);
 244  0
                                                                         infoContainer2.showWarningLayout(false);
 245  0
                                                                         ((WorkflowEnhancedNavController)controller).getWfUtilities().enableWorkflowActionsWidgets(true);
 246  
                                                         }
 247  
                                                         else{
 248  0
                                                                 infoContainer1.showWarningLayout(true);
 249  0
                                                                 infoContainer2.showWarningLayout(true);
 250  0
                                                                 ((WorkflowEnhancedNavController)controller).getWfUtilities().enableWorkflowActionsWidgets(false);
 251  
                                                         }
 252  0
                                                                                 onReadyCallback.exec(result);
 253  
 
 254  0
                                                                         }});
 255  
                                                         }
 256  
                                                         else{
 257  0
                                                                 onReadyCallback.exec(result);
 258  
                                                         }
 259  0
                                                 }});
 260  
 
 261  0
                         }
 262  
                 };
 263  
 
 264  0
                 verticalSection.addWidget(infoContainer1);
 265  0
                 verticalSection.addSection(tableSection);
 266  0
                 verticalSection.addWidget(infoContainer2);
 267  0
                 return verticalSection;
 268  
         }
 269  
         else{
 270  0
                 VerticalSectionView verticalSection = new VerticalSectionView(CourseSections.SUMMARY, getLabel(LUUIConstants.SUMMARY_LABEL_KEY), modelId);
 271  0
                 verticalSection.addSection(tableSection);
 272  0
                 GWT.log("CourseSummaryConfigurer - Summary table needs a workflow controller to provide submit/validation mechanism");
 273  0
                 return verticalSection;
 274  
         }
 275  
 
 276  
 
 277  
     }
 278  
 
 279  
     private SummaryTableFieldBlock generateProposalDocumentsSection() {
 280  0
             SummaryTableFieldBlock block = new SummaryTableFieldBlock();
 281  0
         block.addEditingHandler(new EditHandler(CourseSections.DOCUMENTS));
 282  0
         block.setTitle(getLabel(LUUIConstants.TOOL_DOCUMENTS_LABEL_KEY));
 283  0
             block.addSummaryTableFieldRow(getFieldRow("proposal/id", generateMessageInfo(LUUIConstants.TOOL_DOCUMENTS_LABEL_KEY),
 284  
                          new DocumentList(LUUIConstants.REF_DOC_RELATION_PROPOSAL_TYPE,false, false), new DocumentList(LUUIConstants.REF_DOC_RELATION_PROPOSAL_TYPE,false, false), null, new DocumentListBinding("proposal/id"), false));
 285  0
                 return block;
 286  
         }
 287  
 
 288  0
         private List<Anchor> validateLinks = new ArrayList<Anchor>();
 289  
     private WarnContainer generateWorkflowWidgetContainer(Widget w){
 290  0
             WarnContainer warnContainer = new WarnContainer();
 291  0
         warnContainer.add(w);
 292  0
         w.addStyleName("ks-button-spacing");
 293  0
         warnContainer.add(new KSButton("Return to Curriculum Management", ButtonStyle.DEFAULT_ANCHOR, new ClickHandler(){
 294  
 
 295  
                         @Override
 296  
                         public void onClick(ClickEvent event) {
 297  0
                                 Application.navigate(AppLocations.Locations.CURRICULUM_MANAGEMENT.getLocation());
 298  0
                         }
 299  
                 }));
 300  
         //TODO use messages here
 301  0
         KSLabel label = new KSLabel("This proposal has missing fields.  ");
 302  0
         final String showText = "Show what's missing.";
 303  0
         final String hideText = "Hide error highlighting.";
 304  0
         final Anchor link = new Anchor(showText);
 305  0
         validateLinks.add(link);
 306  0
         link.addClickHandler(new ClickHandler(){
 307  
 
 308  
                         @Override
 309  
                         public void onClick(ClickEvent event) {
 310  0
                                 if(!showingValidation){
 311  0
                                         for(int i=0; i< validateLinks.size(); i++){
 312  0
                                                 validateLinks.get(i).setText(hideText);
 313  
                                         }
 314  0
                                         showingValidation = true;
 315  0
                                         tableSection.enableValidation(showingValidation);
 316  
                                         //FIXME: Handle validation warnings
 317  0
                                         tableSection.processValidationResults(validationInfos, true);
 318  
                                 }
 319  
                                 else{
 320  0
                                         for(int i=0; i< validateLinks.size(); i++){
 321  0
                                                 validateLinks.get(i).setText(showText);
 322  
                                         }
 323  0
                                         showingValidation = false;
 324  0
                                         tableSection.enableValidation(showingValidation);
 325  0
                                         tableSection.removeValidationHighlighting();
 326  
                                 }
 327  0
                         }
 328  
                 });
 329  0
         warnContainer.addWarnWidget(label);
 330  0
         warnContainer.addWarnWidget(link);
 331  0
         return warnContainer;
 332  
     }
 333  
 
 334  
         public VerticalSectionView generateCourseSummarySection(){
 335  0
         tableSection.setEditable(false);
 336  0
         tableSection.addSummaryTableFieldBlock(generateCourseInformation());
 337  0
         tableSection.addSummaryTableFieldBlock(generateGovernanceSection());
 338  0
         tableSection.addSummaryTableFieldBlock(generateCourseLogisticsSection());
 339  0
         tableSection.addSummaryTableFieldBlock(generateLearningObjectivesSection());
 340  0
         tableSection.addSummaryTableFieldBlock(generateRequirementsSection());
 341  0
         tableSection.addSummaryTableFieldBlock(generateActiveDatesSection());
 342  0
         tableSection.addSummaryTableFieldBlock(generateFeesSection());
 343  
 
 344  0
         VerticalSectionView verticalSection = new VerticalSectionView(ViewCourseSections.DETAILED, getLabel(LUUIConstants.SUMMARY_LABEL_KEY), modelId, false);
 345  0
         verticalSection.addSection(tableSection);
 346  
 
 347  0
         return verticalSection;
 348  
     }
 349  
 
 350  
         @SuppressWarnings("unchecked")
 351  
         public SummaryTableFieldBlock generateCourseInformationForProposal(){
 352  0
         SummaryTableFieldBlock block = new SummaryTableFieldBlock();
 353  0
         block.addEditingHandler(new EditHandler(CourseSections.COURSE_INFO));
 354  0
         block.setTitle(getLabel(LUUIConstants.INFORMATION_LABEL_KEY));
 355  0
         block.addSummaryTableFieldRow(getFieldRow(PROPOSAL_TITLE_PATH, generateMessageInfo(LUUIConstants.PROPOSAL_TITLE_LABEL_KEY)));
 356  0
         block.addSummaryTableFieldRow(getFieldRow(COURSE + "/" + COURSE_TITLE, generateMessageInfo(LUUIConstants.COURSE_TITLE_LABEL_KEY)));
 357  0
         block.addSummaryTableFieldRow(getFieldRow(COURSE + "/" + TRANSCRIPT_TITLE, generateMessageInfo(LUUIConstants.SHORT_TITLE_LABEL_KEY)));
 358  0
         block.addSummaryTableFieldRow(getFieldRow(COURSE + "/" + SUBJECT_AREA, generateMessageInfo(LUUIConstants.SUBJECT_CODE_LABEL_KEY)));
 359  0
         block.addSummaryTableFieldRow(getFieldRow(COURSE + "/" + COURSE_NUMBER_SUFFIX, generateMessageInfo(LUUIConstants.COURSE_NUMBER_LABEL_KEY)));
 360  0
         block.addSummaryTableFieldRow(getFieldRow(COURSE + "/" + INSTRUCTORS, generateMessageInfo(LUUIConstants.INSTRUCTORS_LABEL_KEY), null, null, null, new KeyListModelWigetBinding("personId"), false));
 361  
 
 362  0
         block.addSummaryMultiplicity(getMultiplicityConfig(COURSE + QueryPath.getPathSeparator() + CROSS_LISTINGS,
 363  
                         LUUIConstants.CROSS_LISTED_ITEM_LABEL_KEY,
 364  
                         Arrays.asList(
 365  
                                 Arrays.asList(SUBJECT_AREA, LUUIConstants.SUBJECT_CODE_LABEL_KEY),
 366  
                                 Arrays.asList(COURSE_NUMBER_SUFFIX, LUUIConstants.COURSE_NUMBER_LABEL_KEY))));
 367  0
         block.addSummaryMultiplicity(getMultiplicityConfig(COURSE + QueryPath.getPathSeparator() + JOINTS,
 368  
                         LUUIConstants.JOINT_OFFER_ITEM_LABEL_KEY,
 369  
                         Arrays.asList(
 370  
                                 Arrays.asList(CreditCourseJointsConstants.COURSE_ID, LUUIConstants.COURSE_NUMBER_OR_TITLE_LABEL_KEY))));
 371  0
         block.addSummaryMultiplicity(getMultiplicityConfig(COURSE + QueryPath.getPathSeparator() + VERSIONS,
 372  
                         LUUIConstants.VERSION_CODE_LABEL_KEY,
 373  
                         Arrays.asList(
 374  
                                 Arrays.asList("variationCode", LUUIConstants.VERSION_CODE_LABEL_KEY),
 375  
                                 Arrays.asList("variationTitle", LUUIConstants.TITLE_LABEL_KEY))));
 376  
 
 377  0
         block.addSummaryTableFieldRow(getFieldRow(COURSE + "/" + PROPOSAL_DESCRIPTION + "/" + RichTextInfoConstants.PLAIN, generateMessageInfo(LUUIConstants.DESCRIPTION_LABEL_KEY)));
 378  0
         block.addSummaryTableFieldRow(getFieldRow("proposal/rationale", generateMessageInfo(LUUIConstants.PROPOSAL_RATIONALE_LABEL_KEY)));
 379  
 
 380  
 
 381  0
         return block;
 382  
     }
 383  
 
 384  
     public SummaryTableFieldBlock generateCourseInformation(){
 385  0
         SummaryTableFieldBlock block = new SummaryTableFieldBlock();
 386  0
         block.addEditingHandler(new EditHandler(CourseSections.COURSE_INFO));
 387  0
         block.setTitle(getLabel(LUUIConstants.INFORMATION_LABEL_KEY));
 388  
         //block.addSummaryTableFieldRow(getFieldRow(PROPOSAL_TITLE_PATH, generateMessageInfo(LUConstants.PROPOSAL_TITLE_LABEL_KEY)));
 389  0
         block.addSummaryTableFieldRow(getFieldRow(COURSE + "/" + COURSE_TITLE, generateMessageInfo(LUUIConstants.COURSE_TITLE_LABEL_KEY)));
 390  0
         block.addSummaryTableFieldRow(getFieldRow(COURSE + "/" + TRANSCRIPT_TITLE, generateMessageInfo(LUUIConstants.SHORT_TITLE_LABEL_KEY)));
 391  0
         block.addSummaryTableFieldRow(getFieldRow(COURSE + "/" + SUBJECT_AREA, generateMessageInfo(LUUIConstants.SUBJECT_CODE_LABEL_KEY)));
 392  0
         block.addSummaryTableFieldRow(getFieldRow(COURSE + "/" + COURSE_NUMBER_SUFFIX, generateMessageInfo(LUUIConstants.COURSE_NUMBER_LABEL_KEY)));
 393  0
         block.addSummaryTableFieldRow(getFieldRow(COURSE + "/" + INSTRUCTORS, generateMessageInfo(LUUIConstants.INSTRUCTORS_LABEL_KEY), null, null, null, new KeyListModelWigetBinding("personId"), false));
 394  
 
 395  0
         block.addSummaryMultiplicity(getMultiplicityConfig(COURSE + QueryPath.getPathSeparator() + CROSS_LISTINGS,
 396  
                         LUUIConstants.CROSS_LISTED_ITEM_LABEL_KEY,
 397  
                         Arrays.asList(
 398  
                                 Arrays.asList(SUBJECT_AREA, LUUIConstants.SUBJECT_CODE_LABEL_KEY),
 399  
                                 Arrays.asList(COURSE_NUMBER_SUFFIX, LUUIConstants.COURSE_NUMBER_LABEL_KEY))));
 400  0
         block.addSummaryMultiplicity(getMultiplicityConfig(COURSE + QueryPath.getPathSeparator() + JOINTS,
 401  
                         LUUIConstants.JOINT_OFFER_ITEM_LABEL_KEY,
 402  
                         Arrays.asList(
 403  
                                 Arrays.asList(CreditCourseJointsConstants.COURSE_ID, LUUIConstants.COURSE_NUMBER_OR_TITLE_LABEL_KEY))));
 404  0
         block.addSummaryMultiplicity(getMultiplicityConfig(COURSE + QueryPath.getPathSeparator() + VERSIONS,
 405  
                         LUUIConstants.VERSION_CODE_LABEL_KEY,
 406  
                         Arrays.asList(
 407  
                                 Arrays.asList("variationCode", LUUIConstants.VERSION_CODE_LABEL_KEY),
 408  
                                 Arrays.asList("variationTitle", LUUIConstants.TITLE_LABEL_KEY))));
 409  
 
 410  0
         block.addSummaryTableFieldRow(getFieldRow(COURSE + "/" + PROPOSAL_DESCRIPTION + "/" + RichTextInfoConstants.PLAIN, generateMessageInfo(LUUIConstants.DESCRIPTION_LABEL_KEY)));
 411  
 
 412  0
         return block;
 413  
     }
 414  
 
 415  
     public SummaryTableFieldBlock generateGovernanceSection(){
 416  0
             SummaryTableFieldBlock block = new SummaryTableFieldBlock();
 417  0
             block.addEditingHandler(new EditHandler(CourseSections.GOVERNANCE));
 418  0
         block.setTitle(getLabel(LUUIConstants.GOVERNANCE_LABEL_KEY));
 419  0
         block.addSummaryTableFieldRow(getFieldRow(COURSE + "/" + CAMPUS_LOCATIONS, generateMessageInfo(LUUIConstants.CAMPUS_LOCATION_LABEL_KEY)));
 420  0
         block.addSummaryTableFieldRow(getFieldRow(COURSE + "/" + CURRICULUM_OVERSIGHT_ORGS_, generateMessageInfo(LUUIConstants.ACADEMIC_SUBJECT_ORGS_KEY)));
 421  0
         block.addSummaryTableFieldRow(getFieldRow(COURSE + "/" + ADMIN_ORGS, generateMessageInfo(LUUIConstants.ADMIN_ORG_LABEL_KEY)));
 422  0
         return block;
 423  
     }
 424  
 
 425  
     @SuppressWarnings("unchecked")
 426  
         public SummaryTableFieldBlock generateCourseLogisticsSection(){
 427  0
             SummaryTableFieldBlock block = new SummaryTableFieldBlock();
 428  0
             block.addEditingHandler(new EditHandler(CourseSections.COURSE_LOGISTICS));
 429  0
         block.setTitle(getLabel(LUUIConstants.LOGISTICS_LABEL_KEY));
 430  0
         block.addSummaryTableFieldRow(getFieldRow(COURSE + "/" + TERMS_OFFERED, generateMessageInfo(LUUIConstants.TERMS_OFFERED_LABEL_KEY)));
 431  0
         block.addSummaryTableFieldRow(getFieldRow(COURSE + "/" + GRADING_OPTIONS, generateMessageInfo(LUUIConstants.LEARNING_RESULT_ASSESSMENT_SCALE_LABEL_KEY)));
 432  0
         block.addSummaryTableFieldRow(getFieldRow(COURSE + "/" + CreditCourseConstants.DURATION + "/" + "atpDurationTypeKey", generateMessageInfo(LUUIConstants.DURATION_TYPE_LABEL_KEY)));
 433  0
         block.addSummaryTableFieldRow(getFieldRow(COURSE + "/" + CreditCourseConstants.DURATION + "/" + "timeQuantity", generateMessageInfo(LUUIConstants.DURATION_QUANTITY_LABEL_KEY)));
 434  0
         block.addSummaryTableFieldRow(getFieldRow(COURSE + "/" + PASS_FAIL, generateMessageInfo(LUUIConstants.LEARNING_RESULT_PASS_FAIL_LABEL_KEY)));
 435  0
         block.addSummaryTableFieldRow(getFieldRow(COURSE + "/" + AUDIT, generateMessageInfo(LUUIConstants.LEARNING_RESULT_AUDIT_LABEL_KEY)));
 436  
 
 437  0
         block.addSummaryTableFieldRow(getFieldRow(COURSE + "/" + CreditCourseConstants.FINAL_EXAM, generateMessageInfo(LUUIConstants.FINAL_EXAM_STATUS_LABEL_KEY)));
 438  0
         block.addSummaryTableFieldRow(getFieldRow(COURSE + "/" + CreditCourseConstants.FINAL_EXAM_RATIONALE, generateMessageInfo(LUUIConstants.FINAL_EXAM_RATIONALE_LABEL_KEY), true));
 439  
 
 440  
         //Outcomes
 441  0
         Map<String, ModelWidgetBinding> customBindings = new HashMap<String, ModelWidgetBinding>();
 442  0
         ListToTextBinding resultValuesBinding = new ListToTextBinding();
 443  0
         customBindings.put("resultValues", resultValuesBinding);
 444  0
         String outcomesKey = COURSE + QueryPath.getPathSeparator() + CREDIT_OPTIONS;
 445  0
         MultiplicityConfiguration outcomesConfig = getMultiplicityConfig(outcomesKey,
 446  
                         LUUIConstants.LEARNING_RESULT_OUTCOME_LABEL_KEY,
 447  
                         Arrays.asList(
 448  
                                 Arrays.asList(CreditCourseConstants.TYPE, LUUIConstants.LEARNING_RESULT_OUTCOME_TYPE_LABEL_KEY),
 449  
                                 Arrays.asList(CREDIT_OPTION_FIXED_CREDITS, LUUIConstants.CREDIT_VALUE_LABEL_KEY, OPTIONAL),
 450  
                                 Arrays.asList(CREDIT_OPTION_MIN_CREDITS, LUUIConstants.CREDIT_OPTION_MIN_CREDITS_LABEL_KEY, OPTIONAL),
 451  
                                 Arrays.asList(CREDIT_OPTION_MAX_CREDITS, LUUIConstants.CREDIT_OPTION_MAX_CREDITS_LABEL_KEY, OPTIONAL),
 452  
                                 Arrays.asList("resultValues", LUUIConstants.CREDIT_OPTION_FIXED_CREDITS_LABEL_KEY, OPTIONAL)),
 453  
                                 customBindings);
 454  
 
 455  
         //Massive workaround for result values problem where we dont want to show them on certain selections,
 456  
         //in most cases you want to just use the optional flag and have it be based on empty/null data
 457  
         //but since this data is sometimes not empty/null when we dont want to show it, it requires a show
 458  
         //condition callback
 459  0
         tableSection.addShowRowCallback(new ShowRowConditionCallback(){
 460  
                         @Override
 461  
                         public void processShowConditions(SummaryTableFieldRow row,
 462  
                                         DataModel column1, DataModel column2) {
 463  0
                                 if(row.getFieldDescriptor1() != null &&
 464  
                                                 row.getFieldDescriptor1().getFieldKey().contains(CREDIT_OPTIONS) &&
 465  
                                                 row.getFieldDescriptor1().getFieldKey().contains("resultValues")){
 466  0
                                     String type = row.getFieldDescriptor1().getFieldKey().replace("resultValues", CreditCourseConstants.TYPE);
 467  0
                                     Object data1 = null;
 468  0
                                     Object data2 = null;
 469  0
                                     if(column1 != null){
 470  0
                                             data1 = column1.get(type);
 471  
                                     }
 472  0
                                     if(column2 != null){
 473  0
                                             data2 = column2.get(type);
 474  
                                     }
 475  
 
 476  0
                                     if(data1 != null && data1 instanceof String){
 477  0
                                             if(!((String)data1).equals("kuali.resultComponentType.credit.degree.multiple")){
 478  0
                                                     row.setShown(false);
 479  
                                             }
 480  
                                     }
 481  0
                                     else if(data2 != null && data2 instanceof String){
 482  0
                                             if(!((String)data2).equals("kuali.resultComponentType.credit.degree.multiple")){
 483  0
                                                     row.setShown(false);
 484  
                                             }
 485  
                                     }
 486  
                             }
 487  0
                         }
 488  
                 });
 489  
 
 490  0
         block.addSummaryMultiplicity(outcomesConfig);
 491  
 
 492  
         //Formats
 493  0
         MultiplicityConfiguration formatsConfig = getMultiplicityConfig(COURSE + QueryPath.getPathSeparator() + FORMATS,
 494  
                         LUUIConstants.FORMAT_LABEL_KEY,
 495  
                         null);
 496  0
         MultiplicityConfiguration activitiesConfig = getMultiplicityConfig(COURSE + QueryPath.getPathSeparator() + FORMATS + QueryPath.getPathSeparator()
 497  
                         + QueryPath.getWildCard() + QueryPath.getPathSeparator() + ACTIVITIES,
 498  
                         LUUIConstants.ACTIVITY_LITERAL_LABEL_KEY,
 499  
                         Arrays.asList(
 500  
                                 Arrays.asList(ACTIVITY_TYPE, LUUIConstants.ACTIVITY_TYPE_LABEL_KEY),
 501  
                                 Arrays.asList(CONTACT_HOURS + "/" + "unitQuantity", LUUIConstants.CONTACT_HOURS_LABEL_KEY),
 502  
                                 Arrays.asList(CONTACT_HOURS + "/" + "unitType", LUUIConstants.CONTACT_HOURS_FREQUENCY_LABEL_KEY),
 503  
                                 Arrays.asList(CreditCourseActivityConstants.DURATION + "/" + "atpDurationTypeKey", LUUIConstants.DURATION_TYPE_LABEL_KEY),
 504  
                                 Arrays.asList(CreditCourseActivityConstants.DURATION + "/" + "timeQuantity", LUUIConstants.DURATION_LITERAL_LABEL_KEY),
 505  
                                 Arrays.asList(DEFAULT_ENROLLMENT_ESTIMATE, LUUIConstants.CLASS_SIZE_LABEL_KEY)));
 506  0
         formatsConfig.setNestedConfig(activitiesConfig);
 507  0
         block.addSummaryMultiplicity(formatsConfig);
 508  
 
 509  0
         return block;
 510  
     }
 511  
 
 512  
     public SummaryTableFieldBlock generateLearningObjectivesSection(){
 513  0
             SummaryTableFieldBlock block = new SummaryTableFieldBlock();
 514  0
             block.addEditingHandler(new EditHandler(CourseSections.LEARNING_OBJECTIVES));
 515  0
         block.setTitle(getLabel(LUUIConstants.LEARNING_OBJECTIVES_LABEL_KEY));
 516  0
         SummaryTableFieldRow loRow = getFieldRow(COURSE + "/" + CreditCourseConstants.COURSE_SPECIFIC_LOS, generateMessageInfo(LUUIConstants.LEARNING_OBJECTIVES_LABEL_KEY),
 517  
                         new KSListPanel(), new KSListPanel(), null, new TreeStringBinding(), false);
 518  0
         loRow.addContentCellStyleName("summaryTable-lo-cell");
 519  0
         block.addSummaryTableFieldRow(loRow);
 520  
 
 521  0
         return block;
 522  
     }
 523  
 
 524  
     public SummaryTableFieldBlock generateActiveDatesSection(){
 525  0
             SummaryTableFieldBlock block = new SummaryTableFieldBlock();
 526  0
             block.addEditingHandler(new EditHandler(CourseSections.ACTIVE_DATES));
 527  0
         block.setTitle(getLabel(LUUIConstants.ACTIVE_DATES_LABEL_KEY));
 528  0
         block.addSummaryTableFieldRow(getFieldRow(COURSE + "/" + START_TERM, generateMessageInfo(LUUIConstants.START_TERM_LABEL_KEY)));
 529  0
         block.addSummaryTableFieldRow(getFieldRow(COURSE + "/" + END_TERM, generateMessageInfo(LUUIConstants.END_TERM_LABEL_KEY)));
 530  
         //Probably wrong - checkbox
 531  0
         block.addSummaryTableFieldRow(getFieldRow(COURSE + "/" + PILOT_COURSE, generateMessageInfo(LUUIConstants.PILOT_COURSE_LABEL_KEY)));
 532  0
         return block;
 533  
     }
 534  
 
 535  
     public SummaryTableFieldBlock generateFeesSection() {
 536  0
             SummaryTableFieldBlock block = new SummaryTableFieldBlock();
 537  0
             block.addEditingHandler(new EditHandler(CourseSections.FINANCIALS));
 538  0
         block.setTitle(getLabel(LUUIConstants.FINANCIALS_LABEL_KEY));
 539  0
         block.addSummaryTableFieldRow(getFieldRow(COURSE + "/" + "feeJustification" + "/" + RichTextInfoConstants.PLAIN, generateMessageInfo(LUUIConstants.JUSTIFICATION_FEE)));
 540  
         //Fees
 541  0
         MultiplicityConfiguration feesConfig = getMultiplicityConfig(COURSE + QueryPath.getPathSeparator() + FEES,
 542  
                         LUUIConstants.FEE,
 543  
                         Arrays.asList(
 544  
                                 Arrays.asList("rateType", "Rate Type"),
 545  
                                 Arrays.asList("feeType", "Fee Type")));
 546  
         //Note the use of empty string to remove the additional row from display in the summary table
 547  0
         MultiplicityConfiguration amountsConfig = getMultiplicityConfig(COURSE + QueryPath.getPathSeparator() + FEES + QueryPath.getPathSeparator()
 548  
                         + QueryPath.getWildCard() + QueryPath.getPathSeparator() + "feeAmounts",
 549  
                         "",
 550  
                         Arrays.asList(
 551  
                                 Arrays.asList("currencyQuantity", "Amount")));
 552  0
                 feesConfig.setNestedConfig(amountsConfig);
 553  0
                 block.addSummaryMultiplicity(feesConfig);
 554  
 
 555  
                 //Revenue
 556  0
                 MultiplicityConfiguration revenueConfig = getMultiplicityConfig(COURSE + QueryPath.getPathSeparator() + "revenues",
 557  
                                 LUUIConstants.REVENUE,
 558  
                         Arrays.asList(
 559  
                                         Arrays.asList("affiliatedOrgs/0/orgId", "Organization"),
 560  
                                 Arrays.asList("affiliatedOrgs/0/percentage", "Percentage")));
 561  0
                 block.addSummaryMultiplicity(revenueConfig);
 562  
 
 563  
                 //Expenditure
 564  0
                 MultiplicityConfiguration expenditureConfig = getMultiplicityConfig(COURSE + QueryPath.getPathSeparator() + "expenditure"
 565  
                                 + QueryPath.getPathSeparator() + "affiliatedOrgs",
 566  
                                 LUUIConstants.EXPENDITURE,
 567  
                         Arrays.asList(
 568  
                                 Arrays.asList("orgId", "Organization"),
 569  
                                 Arrays.asList("percentage", "Percentage")));
 570  0
                 block.addSummaryMultiplicity(expenditureConfig);
 571  
 
 572  0
         return block;
 573  
         }
 574  
 
 575  
     public SummaryTableFieldBlock generateRequirementsSection(){
 576  
 
 577  0
             final SummaryTableFieldBlock block = new SummaryTableFieldBlock();
 578  0
             block.addEditingHandler(new EditHandler(CourseSections.COURSE_REQUISITES));
 579  0
         block.setTitle(getLabel(LUUIConstants.REQUISITES_LABEL_KEY));
 580  
 
 581  
         //one row per requirement type
 582  0
         for (StatementTypeInfo stmtType : stmtTypes) {
 583  
                 SummaryTableFieldRow arow;
 584  0
                 if (controller instanceof VersionsController || controller instanceof CourseProposalController)
 585  0
                         arow = new SummaryTableFieldRow(addRequisiteField(new FlowPanel(), stmtType), addRequisiteFieldComp(new FlowPanel(), stmtType));
 586  
                 else
 587  0
                         arow = new SummaryTableFieldRow(addRequisiteField(new FlowPanel(), stmtType), addRequisiteField(new FlowPanel(), stmtType));
 588  0
                 block.addSummaryTableFieldRow(arow);
 589  0
         }
 590  
 
 591  0
         return block;
 592  
     }
 593  
 
 594  
     private FieldDescriptorReadOnly addRequisiteField(final FlowPanel panel, final StatementTypeInfo stmtType) {
 595  
 
 596  0
         final ModelWidgetBinding<FlowPanel> widgetBinding = new ModelWidgetBinding<FlowPanel>() {
 597  
 
 598  
             @Override
 599  
             public void setModelValue(FlowPanel panel, DataModel model, String path) {
 600  0
             }
 601  
 
 602  
             @Override
 603  
             public void setWidgetValue(final FlowPanel panel, DataModel model, String path) {
 604  0
                 panel.clear();
 605  0
                 if (controller instanceof HasRequirements) {
 606  0
                     HasRequirements requirementsController = (HasRequirements) controller;
 607  0
                     List<StatementTreeViewInfo> statementTreeViewInfos = requirementsController.getReqDataModel().getCourseReqInfo(stmtType.getId());
 608  0
                     for (StatementTreeViewInfo rule : statementTreeViewInfos) {
 609  0
                         SubrulePreviewWidget ruleWidget = new SubrulePreviewWidget(rule, true, CourseRequirementsSummaryView.getCluSetWidgetList(rule));
 610  0
                         panel.add(ruleWidget);
 611  0
                     }
 612  
                 }
 613  0
             }
 614  
         };
 615  
 
 616  0
         FieldDescriptorReadOnly requisiteField = new FieldDescriptorReadOnly(COURSE + "/" + CreditCourseConstants.ID, new MessageKeyInfo(stmtType.getName()), null, panel);
 617  0
         requisiteField.setWidgetBinding(widgetBinding);
 618  
 
 619  0
         return requisiteField;
 620  
     }
 621  
 
 622  
     private FieldDescriptorReadOnly addRequisiteFieldComp(final FlowPanel panel, final StatementTypeInfo stmtType) {
 623  
 
 624  0
         final ModelWidgetBinding<FlowPanel> widgetBinding = new ModelWidgetBinding<FlowPanel>() {
 625  
 
 626  
             @Override
 627  
             public void setModelValue(FlowPanel panel, DataModel model, String path) {
 628  0
             }
 629  
 
 630  
             @Override
 631  
             public void setWidgetValue(final FlowPanel panel, DataModel model, String path) {
 632  0
                 panel.clear();
 633  0
                 List<StatementTreeViewInfo> statementTreeViewInfos = null;
 634  
 
 635  0
                 if (controller instanceof VersionsController) 
 636  0
                     statementTreeViewInfos = ((VersionsController) controller).getReqDataModelComp().getCourseReqInfo(stmtType.getId());
 637  0
                 else if (controller instanceof CourseProposalController)   
 638  0
                         statementTreeViewInfos = ((CourseProposalController) controller).getReqDataModelComp().getCourseReqInfo(stmtType.getId());
 639  
 
 640  0
                 for (StatementTreeViewInfo rule : statementTreeViewInfos) {
 641  0
                     SubrulePreviewWidget ruleWidget = new SubrulePreviewWidget(rule, true, CourseRequirementsSummaryView.getCluSetWidgetList(rule));
 642  0
                     panel.add(ruleWidget);
 643  0
                 }
 644  0
             }
 645  
         };
 646  
 
 647  0
         FieldDescriptorReadOnly requisiteField = new FieldDescriptorReadOnly(COURSE + "/" + CreditCourseConstants.ID, new MessageKeyInfo(stmtType.getName()), null, panel);
 648  0
         requisiteField.setWidgetBinding(widgetBinding);
 649  
 
 650  0
         return requisiteField;
 651  
     } 
 652  
 
 653  
     private MultiplicityConfiguration getMultiplicityConfig(String path,
 654  
             String itemLabelMessageKey, List<List<String>> fieldKeysAndLabels){
 655  0
             return getMultiplicityConfig(path, itemLabelMessageKey, fieldKeysAndLabels, null);
 656  
     }
 657  
 
 658  
         private MultiplicityConfiguration getMultiplicityConfig(String path,
 659  
             String itemLabelMessageKey, List<List<String>> fieldKeysAndLabels, Map<String, ModelWidgetBinding> customBindings){
 660  0
             QueryPath parentPath = QueryPath.concat(path);
 661  0
         MultiplicityConfiguration config = new MultiplicityConfiguration(MultiplicityConfiguration.MultiplicityType.TABLE,
 662  
                 MultiplicityConfiguration.StyleType.TOP_LEVEL_GROUP, modelDefinition.getMetadata(parentPath));
 663  0
         config.setItemLabel(getLabel(itemLabelMessageKey));
 664  0
         config.setUpdateable(false);
 665  0
         config.setShowHeaders(true);
 666  
 
 667  0
         FieldDescriptorReadOnly parentFd = buildFieldDescriptor(path, getLabel(itemLabelMessageKey), null);
 668  0
         config.setParent(parentFd);
 669  
 
 670  0
         if (fieldKeysAndLabels != null) {
 671  0
             for (List<String> fieldKeyAndLabel : fieldKeysAndLabels) {
 672  0
                     MultiplicityFieldConfiguration fd = buildMultiplicityFD(fieldKeyAndLabel.get(0),
 673  
                         fieldKeyAndLabel.get(1), parentPath.toString());
 674  0
                     if(fieldKeyAndLabel.size() == 3 && fieldKeyAndLabel.get(2).equals(OPTIONAL)){
 675  0
                             fd.setOptional(true);
 676  
                     }
 677  0
                     if(customBindings != null && customBindings.containsKey(fieldKeyAndLabel.get(0))){
 678  0
                             fd.setModelWidgetBinding(customBindings.get(fieldKeyAndLabel.get(0)));
 679  
                     }
 680  0
                 config.addFieldConfiguration(fd);
 681  0
             }
 682  
         }
 683  
 
 684  0
         return config;
 685  
     }
 686  
 
 687  
 
 688  
     //TODO next 3 methods below should be moved into some kind of multiplicity helper class
 689  
     private MultiplicityFieldConfiguration buildMultiplicityFD(
 690  
             String fieldKey, String labelKey, String parentPath) {
 691  
 
 692  0
         QueryPath fieldPath = QueryPath.concat(parentPath, QueryPath.getWildCard(), fieldKey);
 693  0
         Metadata meta = modelDefinition.getMetadata(fieldPath);
 694  
 
 695  0
         MultiplicityFieldConfiguration fd = new MultiplicityFieldConfiguration(
 696  
                 fieldPath.toString(), generateMessageInfo(labelKey), meta, null);
 697  
 
 698  
 
 699  0
         return fd;
 700  
 
 701  
     }
 702  
 
 703  
     private FieldDescriptorReadOnly buildFieldDescriptor(String fieldKey, String messageKey,String parentPath) {
 704  0
         return buildFieldDescriptor(fieldKey, messageKey, parentPath, null, null);
 705  
     }
 706  
 
 707  
     private FieldDescriptorReadOnly buildFieldDescriptor(String fieldKey, String messageKey, String parentPath, Widget widget, ModelWidgetBinding<?> binding) {
 708  
 
 709  0
         QueryPath path = QueryPath.concat(parentPath, fieldKey);
 710  0
         Metadata meta = modelDefinition.getMetadata(path);
 711  
 
 712  0
         FieldDescriptorReadOnly fd = new FieldDescriptorReadOnly(path.toString(), generateMessageInfo(messageKey), meta);
 713  0
         if (widget != null) {
 714  0
             fd.setFieldWidget(widget);
 715  
         }
 716  0
         if (binding != null) {
 717  0
             fd.setWidgetBinding(binding);
 718  
         }
 719  0
         return fd;
 720  
     }
 721  
 
 722  
         public VerticalSectionView generateCourseBriefSection() {
 723  0
                 SummaryTableSection courseBriefSection = new SummaryTableSection(controller);
 724  0
                 courseBriefSection.setEditable(false);
 725  0
                 SummaryTableFieldBlock block = new SummaryTableFieldBlock();
 726  0
         block.addSummaryTableFieldRow(getFieldRow(COURSE + "/" + COURSE_TITLE, generateMessageInfo(LUUIConstants.COURSE_TITLE_LABEL_KEY)));
 727  0
         block.addSummaryTableFieldRow(getFieldRow(COURSE + "/" + "code", generateMessageInfo(LUUIConstants.COURSE_NUMBER_LABEL_KEY)));
 728  0
         block.addSummaryTableFieldRow(getFieldRow(COURSE + "/" + ADMIN_ORGS, generateMessageInfo(LUUIConstants.ADMIN_ORG_LABEL_KEY)));
 729  0
         block.addSummaryTableFieldRow(getFieldRow(COURSE + "/" + PROPOSAL_DESCRIPTION + "/" + RichTextInfoConstants.PLAIN, generateMessageInfo(LUUIConstants.DESCRIPTION_LABEL_KEY)));
 730  0
         block.addSummaryTableFieldRow(getFieldRow(COURSE + "/" + CURRICULUM_OVERSIGHT_ORGS_, generateMessageInfo(LUUIConstants.ACADEMIC_SUBJECT_ORGS_KEY)));
 731  0
         block.addSummaryTableFieldRow(getFieldRow(COURSE + "/" + CAMPUS_LOCATIONS, generateMessageInfo(LUUIConstants.CAMPUS_LOCATION_LABEL_KEY)));
 732  
 
 733  0
         Map<String, ModelWidgetBinding> customBindings = new HashMap<String, ModelWidgetBinding>();
 734  0
         ListToTextBinding resultValuesBinding = new ListToTextBinding();
 735  0
         customBindings.put("resultValues", resultValuesBinding);
 736  0
         String outcomesKey = COURSE + QueryPath.getPathSeparator() + CREDIT_OPTIONS;
 737  0
         MultiplicityConfiguration outcomesConfig = getMultiplicityConfig(outcomesKey,
 738  
                         LUUIConstants.LEARNING_RESULT_OUTCOME_LABEL_KEY,
 739  
                         Arrays.asList(
 740  
                                 Arrays.asList(CreditCourseConstants.TYPE, LUUIConstants.LEARNING_RESULT_OUTCOME_TYPE_LABEL_KEY),
 741  
                                 Arrays.asList(CREDIT_OPTION_FIXED_CREDITS, LUUIConstants.CONTACT_HOURS_LABEL_KEY, OPTIONAL),
 742  
                                 Arrays.asList(CREDIT_OPTION_MIN_CREDITS, LUUIConstants.CREDIT_OPTION_MIN_CREDITS_LABEL_KEY, OPTIONAL),
 743  
                                 Arrays.asList(CREDIT_OPTION_MAX_CREDITS, LUUIConstants.CREDIT_OPTION_MAX_CREDITS_LABEL_KEY, OPTIONAL),
 744  
                                 Arrays.asList("resultValues", LUUIConstants.CREDIT_OPTION_FIXED_CREDITS_LABEL_KEY, OPTIONAL)),
 745  
                                 customBindings);
 746  
 
 747  
         //Massive workaround for result values problem where we dont want to show them on certain selections,
 748  
         //in most cases you want to just use the optional flag and have it be based on empty/null data
 749  
         //but since this data is sometimes not empty/null when we dont want to show it, it requires a show
 750  
         //condition callback
 751  0
         courseBriefSection.addShowRowCallback(new ShowRowConditionCallback(){
 752  
                         @Override
 753  
                         public void processShowConditions(SummaryTableFieldRow row,
 754  
                                         DataModel column1, DataModel column2) {
 755  0
                                 if(row.getFieldDescriptor1() != null &&
 756  
                                                 row.getFieldDescriptor1().getFieldKey().contains(CREDIT_OPTIONS) &&
 757  
                                                 row.getFieldDescriptor1().getFieldKey().contains("resultValues")){
 758  0
                                     String type = row.getFieldDescriptor1().getFieldKey().replace("resultValues", CreditCourseConstants.TYPE);
 759  0
                                     Object data1 = null;
 760  0
                                     Object data2 = null;
 761  0
                                     if(column1 != null){
 762  0
                                             data1 = column1.get(type);
 763  
                                     }
 764  0
                                     if(column2 != null){
 765  0
                                             data2 = column2.get(type);
 766  
                                     }
 767  
 
 768  0
                                     if(data1 != null && data1 instanceof String){
 769  0
                                             if(!((String)data1).equals("kuali.resultComponentType.credit.degree.multiple")){
 770  0
                                                     row.setShown(false);
 771  
                                             }
 772  
                                     }
 773  0
                                     else if(data2 != null && data2 instanceof String){
 774  0
                                             if(!((String)data2).equals("kuali.resultComponentType.credit.degree.multiple")){
 775  0
                                                     row.setShown(false);
 776  
                                             }
 777  
                                     }
 778  
                             }
 779  0
                         }
 780  
                 });
 781  0
         block.addSummaryMultiplicity(outcomesConfig);
 782  
 
 783  0
         block.addSummaryTableFieldRow(getFieldRow(COURSE + "/" + TERMS_OFFERED, generateMessageInfo(LUUIConstants.TERMS_OFFERED_LABEL_KEY)));
 784  0
         block.addSummaryTableFieldRow(getFieldRow(COURSE + "/" + GRADING_OPTIONS, generateMessageInfo(LUUIConstants.LEARNING_RESULT_ASSESSMENT_SCALE_LABEL_KEY)));
 785  0
         block.addSummaryTableFieldRow(getFieldRow(COURSE + "/" + PASS_FAIL, generateMessageInfo(LUUIConstants.LEARNING_RESULT_PASS_FAIL_LABEL_KEY), true));
 786  0
         block.addSummaryTableFieldRow(getFieldRow(COURSE + "/" + AUDIT, generateMessageInfo(LUUIConstants.LEARNING_RESULT_AUDIT_LABEL_KEY), true));
 787  0
         MultiplicityConfiguration formatsConfig = getMultiplicityConfig(COURSE + QueryPath.getPathSeparator() + FORMATS,
 788  
                         LUUIConstants.FORMAT_LABEL_KEY,
 789  
                         null);
 790  0
         MultiplicityConfiguration activitiesConfig = getMultiplicityConfig(COURSE + QueryPath.getPathSeparator() + FORMATS + QueryPath.getPathSeparator()
 791  
                         + QueryPath.getWildCard() + QueryPath.getPathSeparator() + ACTIVITIES,
 792  
                         LUUIConstants.ACTIVITY_LITERAL_LABEL_KEY,
 793  
                         Arrays.asList(
 794  
                                 Arrays.asList(ACTIVITY_TYPE, LUUIConstants.ACTIVITY_TYPE_LABEL_KEY),
 795  
                                 Arrays.asList(CONTACT_HOURS + "/" + "unitQuantity", LUUIConstants.CONTACT_HOURS_LABEL_KEY),
 796  
                                 Arrays.asList(CONTACT_HOURS + "/" + "unitType", "per"),
 797  
                                 Arrays.asList(CreditCourseActivityConstants.DURATION + "/" + "atpDurationTypeKey", LUUIConstants.DURATION_TYPE_LABEL_KEY),
 798  
                                 Arrays.asList(CreditCourseActivityConstants.DURATION + "/" + "timeQuantity", LUUIConstants.DURATION_LITERAL_LABEL_KEY),
 799  
                                 Arrays.asList(DEFAULT_ENROLLMENT_ESTIMATE, LUUIConstants.CLASS_SIZE_LABEL_KEY)));
 800  0
         formatsConfig.setNestedConfig(activitiesConfig);
 801  0
         block.addSummaryMultiplicity(formatsConfig);
 802  
         //Fees
 803  0
         MultiplicityConfiguration feesConfig = getMultiplicityConfig(COURSE + QueryPath.getPathSeparator() + FEES,
 804  
                         LUUIConstants.FEE,
 805  
                         Arrays.asList(
 806  
                                 Arrays.asList("rateType", "Rate Type"),
 807  
                                 Arrays.asList("feeType", "Fee Type")));
 808  
         //Note the use of empty string to remove the additional row from display in the summary table
 809  0
         MultiplicityConfiguration amountsConfig = getMultiplicityConfig(COURSE + QueryPath.getPathSeparator() + FEES + QueryPath.getPathSeparator()
 810  
                         + QueryPath.getWildCard() + QueryPath.getPathSeparator() + "feeAmounts",
 811  
                         "",
 812  
                         Arrays.asList(
 813  
                                 Arrays.asList("currencyQuantity", "Amount")));
 814  0
                 feesConfig.setNestedConfig(amountsConfig);
 815  0
                 block.addSummaryMultiplicity(feesConfig);
 816  
 /*        block.addSummaryMultiplicity(getMultiplicityConfig(COURSE + QueryPath.getPathSeparator() + CROSS_LISTINGS,
 817  
                         LUConstants.CROSS_LISTED_ITEM_LABEL_KEY,
 818  
                         Arrays.asList(
 819  
                                 Arrays.asList(SUBJECT_AREA, LUConstants.SUBJECT_CODE_LABEL_KEY),
 820  
                                 Arrays.asList(COURSE_NUMBER_SUFFIX, LUConstants.COURSE_NUMBER_LABEL_KEY))));
 821  
         block.addSummaryMultiplicity(getMultiplicityConfig(COURSE + QueryPath.getPathSeparator() + JOINTS,
 822  
                         LUConstants.JOINT_OFFER_ITEM_LABEL_KEY,
 823  
                         Arrays.asList(
 824  
                                 Arrays.asList(CreditCourseJointsConstants.COURSE_ID, LUConstants.COURSE_NUMBER_OR_TITLE_LABEL_KEY))));
 825  
         block.addSummaryMultiplicity(getMultiplicityConfig(COURSE + QueryPath.getPathSeparator() + VERSIONS,
 826  
                         LUConstants.VERSION_CODE_LABEL_KEY,
 827  
                         Arrays.asList(
 828  
                                 Arrays.asList("variationCode", LUConstants.VERSION_CODE_LABEL_KEY),
 829  
                                 Arrays.asList("variationTitle", LUConstants.TITLE_LABEL_KEY))));*/
 830  0
                 courseBriefSection.addSummaryTableFieldBlock(block);
 831  0
         VerticalSectionView verticalSection = new VerticalSectionView(ViewCourseSections.BRIEF, "At a Glance", modelId, false);
 832  0
         verticalSection.addSection(courseBriefSection);
 833  
 
 834  0
         return verticalSection;
 835  
         }
 836  
 
 837  
         public VerticalSectionView generateCourseCatalogSection() {
 838  0
                 VerticalSectionView verticalSection = new VerticalSectionView(ViewCourseSections.CATALOG, "Catalog View", modelId, false);
 839  0
                 FieldDescriptorReadOnly catalogField = new FieldDescriptorReadOnly("", null, null, new HTML());
 840  0
                 catalogField.hideLabel();
 841  0
                 catalogField.setWidgetBinding(new ModelWidgetBinding<HTML>(){
 842  
 
 843  
                         @Override
 844  
                         public void setModelValue(HTML widget, DataModel model, String path) {
 845  
                                 // TODO Auto-generated method stub
 846  
 
 847  0
                         }
 848  
 
 849  
                         @Override
 850  
                         public void setWidgetValue(HTML widget, DataModel model, String path) {
 851  0
                                 String code = model.get("code");
 852  0
                                 String title = model.get(COURSE + "/" + COURSE_TITLE);
 853  0
                                 String credits = "";
 854  0
                                 String outcomesKey = COURSE + QueryPath.getPathSeparator() + CREDIT_OPTIONS;
 855  0
                                 Data outcomes = model.get(outcomesKey);
 856  0
                                 if(outcomes !=null){
 857  0
                                         Iterator<Property> iter = outcomes.realPropertyIterator();
 858  0
                                         String list = "";
 859  0
                                         ListToTextBinding binding = new ListToTextBinding();
 860  0
                                         while(iter.hasNext()){
 861  0
                                                 Property prop = iter.next();
 862  0
                                                 if (prop.getKey() instanceof Integer){
 863  0
                                         Integer number = (Integer)prop.getKey();
 864  0
                                         Object value = outcomes.get(number);
 865  0
                                         if(value instanceof Data){
 866  0
                                                 list = list + binding.getStringList(model, outcomesKey + "/" + number +"/" + "resultValues") + ", ";
 867  
                                         }
 868  
                                 }
 869  0
                                         }
 870  
 
 871  0
                                         if(!list.isEmpty()){
 872  0
                                                 list = list.trim();
 873  0
                                                 list = list.substring(0, list.length() - 1);
 874  0
                                     credits = "(" + list + ")";
 875  
                             }
 876  
                                 }
 877  
 
 878  0
                                 String description = model.get(COURSE + "/" + PROPOSAL_DESCRIPTION + "/" + RichTextInfoConstants.PLAIN);
 879  0
                                 String catalogText = "<b> " + code + " " + title + " " + credits + "</b> " + description + " ";
 880  0
                                 catalogText.replace(" null ", "");
 881  0
                                 catalogText.trim();
 882  0
                                 widget.setHTML(catalogText);
 883  
 
 884  0
                         }
 885  
                 });
 886  0
                 verticalSection.addField(catalogField);
 887  
 
 888  0
                 return verticalSection;
 889  
         }
 890  
 
 891  
     public SummaryTableSection getTableSection() {
 892  0
         return tableSection;
 893  
     }
 894  
 }