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