Coverage Report - org.kuali.student.lum.common.client.widgets.CluSetEditorWidget
 
Classes in this File Line Coverage Branch Coverage Complexity
CluSetEditorWidget
0%
0/204
0%
0/103
2.38
CluSetEditorWidget$1
0%
0/9
0%
0/2
2.38
CluSetEditorWidget$2
0%
0/15
0%
0/4
2.38
CluSetEditorWidget$2$1
0%
0/3
N/A
2.38
CluSetEditorWidget$3
0%
0/5
0%
0/4
2.38
CluSetEditorWidget$4
0%
0/4
N/A
2.38
CluSetEditorWidget$5
0%
0/3
N/A
2.38
CluSetEditorWidget$6
0%
0/3
N/A
2.38
CluSetEditorWidget$7
0%
0/6
0%
0/4
2.38
CluSetEditorWidget$8
0%
0/1
N/A
2.38
CluSetEditorWidget$CluSetBinding
0%
0/6
N/A
2.38
CluSetEditorWidget$CluSetEditOptionDropdown
0%
0/14
0%
0/8
2.38
CluSetEditorWidget$CluSetManagementField
0%
0/2
N/A
2.38
CluSetEditorWidget$CluSetRangeBinding
0%
0/30
0%
0/12
2.38
CluSetEditorWidget$CluSetRangeBinding$1
0%
0/3
N/A
2.38
CluSetEditorWidget$KSItemLabelPanelPair
0%
0/10
N/A
2.38
CluSetEditorWidget$KSSelectedListPanelPair
0%
0/10
N/A
2.38
CluSetEditorWidget$Picker
0%
0/13
N/A
2.38
 
 1  
 package org.kuali.student.lum.common.client.widgets;
 2  
 
 3  
 import java.util.ArrayList;
 4  
 import java.util.HashMap;
 5  
 import java.util.List;
 6  
 import java.util.Map;
 7  
 import java.util.Set;
 8  
 
 9  
 import org.kuali.student.common.ui.client.configurable.mvc.FieldDescriptor;
 10  
 import org.kuali.student.common.ui.client.configurable.mvc.WidgetConfigInfo;
 11  
 import org.kuali.student.common.ui.client.configurable.mvc.binding.HasDataValueBinding;
 12  
 import org.kuali.student.common.ui.client.configurable.mvc.binding.ModelWidgetBindingSupport;
 13  
 import org.kuali.student.common.ui.client.configurable.mvc.sections.Section;
 14  
 import org.kuali.student.common.ui.client.configurable.mvc.sections.VerticalSection;
 15  
 import org.kuali.student.common.ui.client.configurable.mvc.views.VerticalSectionView;
 16  
 import org.kuali.student.common.ui.client.mvc.Callback;
 17  
 import org.kuali.student.common.ui.client.mvc.DataModel;
 18  
 import org.kuali.student.common.ui.client.mvc.DataModelDefinition;
 19  
 import org.kuali.student.common.ui.client.mvc.HasDataValue;
 20  
 import org.kuali.student.common.ui.client.widgets.KSDropDown;
 21  
 import org.kuali.student.common.ui.client.widgets.KSItemLabel;
 22  
 import org.kuali.student.common.ui.client.widgets.KSLabel;
 23  
 import org.kuali.student.common.ui.client.widgets.field.layout.element.MessageKeyInfo;
 24  
 import org.kuali.student.common.ui.client.widgets.layout.VerticalFlowPanel;
 25  
 import org.kuali.student.common.ui.client.widgets.list.KSSelectedList;
 26  
 import org.kuali.student.common.ui.client.widgets.list.SelectionChangeEvent;
 27  
 import org.kuali.student.common.ui.client.widgets.list.SelectionChangeHandler;
 28  
 import org.kuali.student.common.ui.client.widgets.list.impl.SimpleListItems;
 29  
 import org.kuali.student.common.ui.client.widgets.menus.KSListPanel;
 30  
 import org.kuali.student.common.ui.client.widgets.progress.BlockingTask;
 31  
 import org.kuali.student.common.ui.client.widgets.progress.KSBlockingProgressIndicator;
 32  
 import org.kuali.student.common.ui.client.widgets.search.KSPicker;
 33  
 import org.kuali.student.core.assembly.data.Data;
 34  
 import org.kuali.student.core.assembly.data.LookupMetadata;
 35  
 import org.kuali.student.core.assembly.data.LookupParamMetadata;
 36  
 import org.kuali.student.core.assembly.data.Metadata;
 37  
 import org.kuali.student.core.assembly.data.QueryPath;
 38  
 import org.kuali.student.core.assembly.data.Data.DataValue;
 39  
 import org.kuali.student.core.assembly.data.Data.Value;
 40  
 import org.kuali.student.core.search.dto.SearchParam;
 41  
 import org.kuali.student.core.search.dto.SearchRequest;
 42  
 import org.kuali.student.lum.lu.dto.MembershipQueryInfo;
 43  
 
 44  
 import com.google.gwt.dom.client.Style;
 45  
 import com.google.gwt.event.dom.client.ClickEvent;
 46  
 import com.google.gwt.event.dom.client.ClickHandler;
 47  
 import com.google.gwt.event.logical.shared.CloseEvent;
 48  
 import com.google.gwt.event.logical.shared.CloseHandler;
 49  
 import com.google.gwt.event.shared.HandlerRegistration;
 50  
 import com.google.gwt.user.client.Timer;
 51  
 import com.google.gwt.user.client.Window;
 52  
 import com.google.gwt.user.client.ui.HTML;
 53  
 import com.google.gwt.user.client.ui.Panel;
 54  
 import com.google.gwt.user.client.ui.Widget;
 55  
 
 56  0
 public class CluSetEditorWidget extends VerticalSectionView {
 57  
 
 58  0
     private List<KSSelectedListPanelPair> selectedListPanelPairs = new ArrayList<KSSelectedListPanelPair>();
 59  
     private DataModelDefinition modelDefinition;
 60  
 //    private final List<HandlerRegistration> showClusetDetailsHandlerRegs = new ArrayList<HandlerRegistration>(); 
 61  0
     private final Map<String, HandlerRegistration> showCluRangeDetailsHandlerRegs = new HashMap<String, HandlerRegistration>();
 62  0
     private List<KSItemLabelPanelPair> itemLabelPanelPairs = new ArrayList<KSItemLabelPanelPair>();
 63  
     private String cluSetType;
 64  
     private String metadataId;
 65  0
     private static Map<String, DataModelDefinition> modelDefinitionCache = new HashMap<String, DataModelDefinition>();
 66  0
     private BlockingTask initializeTask = new BlockingTask("Initializing");
 67  
     private boolean singularCluOnly;
 68  
     private KSSelectedList approvedClusSelection;
 69  
     
 70  0
     private enum CluSetManagementField {
 71  0
         APPROVED, PROPOSED, CLUSETS, RANGE
 72  
     }
 73  
 
 74  
     public CluSetEditorWidget(CluSetRetriever cluSetRetriever, Enum<?> viewEnum,
 75  
             String name, String modelId, boolean showTitle,
 76  
             final Callback<Boolean> onReady, String cluSetType, boolean singularCluOnly) {
 77  0
         super(viewEnum, name, modelId, showTitle);
 78  0
         this.cluSetType = cluSetType;
 79  0
         this.singularCluOnly = singularCluOnly;
 80  0
         if (cluSetType != null && cluSetType.equals("kuali.cluSet.type.Program")) {
 81  0
             this.metadataId = "programSet";
 82  
         } else {
 83  0
             this.metadataId = "courseSet";
 84  
         }
 85  0
         KSBlockingProgressIndicator.addTask(initializeTask);
 86  0
         if (modelDefinitionCache.get(metadataId) == null) {
 87  0
             cluSetRetriever.getMetadata(metadataId, new Callback<Metadata>(){
 88  
                 @Override
 89  
                 public void exec(Metadata result) {
 90  0
                     DataModelDefinition def = new DataModelDefinition(result);
 91  0
                     modelDefinitionCache.put(metadataId, def);
 92  0
                     setDef(def);
 93  0
                     setupEditor();
 94  0
                     if (onReady != null) {
 95  0
                         onReady.exec(new Boolean(true));
 96  
                     }
 97  0
                     KSBlockingProgressIndicator.removeTask(initializeTask);                
 98  0
                 }
 99  
             });
 100  
         } else {
 101  0
             DataModelDefinition def = modelDefinitionCache.get(metadataId);
 102  0
             setDef(def);
 103  0
             setupEditor();
 104  0
             if (onReady != null) {
 105  0
                 onReady.exec(new Boolean(true));
 106  
             }
 107  0
             KSBlockingProgressIndicator.removeTask(initializeTask);                
 108  
         }
 109  0
     }
 110  
     
 111  
     private void setDef(DataModelDefinition def) {
 112  0
         this.modelDefinition = def;
 113  0
     }
 114  
     
 115  
     public void setupEditor() {
 116  0
         String labelType = null;
 117  0
         if (cluSetType == null || !cluSetType.equals("kuali.cluSet.type.Program")) {
 118  0
             labelType = "Course";
 119  
         } else {
 120  0
             labelType = "Program";
 121  
         }
 122  0
         final CluSetEditOptionDropdown chooser = new CluSetEditOptionDropdown();
 123  0
         SwitchSection clusetDetails = new SwitchSection(
 124  
                 chooser,
 125  
                 null);
 126  0
         clusetDetails.enableConfirmation(false);
 127  
         // ****** Add Approved Clus *******
 128  0
         Section approvedClusSection = new VerticalSection();
 129  0
         FieldDescriptor approvedClusFd = addField(approvedClusSection, 
 130  
                 CommonWidgetConstants.CLU_SET_APPROVED_CLUS_FIELD, 
 131  
                 generateMessageInfo(CommonWidgetConstants.NEW_CLU_SET_CONTENT_APPROVED + labelType),
 132  
                 null,
 133  
                 null);
 134  0
         approvedClusSelection = (KSSelectedList) approvedClusFd.getFieldWidget();
 135  0
         KSListPanel approvedClusListPanel = approvedClusSelection.separateValuesPanel();
 136  0
         clusetDetails.addSection(approvedClusSection, CommonWidgetConstants.CLU_SET_SWAP_APPROVED_CLUS);
 137  
         // END OF items related to Add Approved Clus
 138  
 
 139  
         // ****** Add Proposed Clus *******
 140  0
         Section proposedClusSection = new VerticalSection();
 141  0
         FieldDescriptor proposedClusFd = addField(proposedClusSection, 
 142  
                 CommonWidgetConstants.CLU_SET_PROPOSED_CLUS_FIELD, 
 143  
                 generateMessageInfo(CommonWidgetConstants.NEW_CLU_SET_CONTENT_PROPOSED + labelType),
 144  
                 null,
 145  
                 null);
 146  0
         final KSSelectedList proposedClusSelection = (KSSelectedList) proposedClusFd.getFieldWidget();
 147  0
         KSListPanel proposedClusListPanel = proposedClusSelection.separateValuesPanel();
 148  0
         clusetDetails.addSection(proposedClusSection, CommonWidgetConstants.CLU_SET_SWAP_PROPOSED_CLUS);
 149  
         // END OF items related to Add Approved Clus
 150  
 
 151  
         // ****** Add Clu Range *******
 152  0
         KSItemLabel clusetRangeLabel = null;
 153  0
         if (displayField(CluSetManagementField.RANGE)) {
 154  0
             Section cluRangeSection = new VerticalSection();
 155  0
             final Picker cluSetRangePicker = configureSearch(CommonWidgetConstants.CLU_SET_CLU_SET_RANGE_EDIT_FIELD);
 156  0
             addField(cluRangeSection, 
 157  
                     CommonWidgetConstants.CLU_SET_CLU_SET_RANGE_EDIT_FIELD, 
 158  
                     generateMessageInfo(CommonWidgetConstants.NEW_CLU_SET_CONTENT_RANGE + labelType),
 159  
                     cluSetRangePicker,
 160  
                     null);
 161  0
             final CluSetRangeDataHelper clusetRangeModelHelper = new CluSetRangeDataHelper();
 162  0
             clusetRangeLabel = new KSItemLabel(true, true, clusetRangeModelHelper);
 163  0
             final KSItemLabel theClusetRangeLabel = clusetRangeLabel;
 164  0
             clusetRangeLabel.getElement().getStyle().setProperty("border", "solid 1px #cdcdcd");
 165  0
             clusetRangeLabel.getElement().getStyle().setProperty("width", "354px");
 166  0
             final FieldDescriptor cluRangeFieldDescriptor = addField(
 167  
                     cluRangeSection, 
 168  
                     CommonWidgetConstants.CLU_SET_CLU_SET_RANGE_FIELD, 
 169  
                     null, 
 170  
                     clusetRangeLabel,
 171  
                     null);
 172  0
             cluRangeFieldDescriptor.setWidgetBinding(new CluSetRangeBinding(clusetRangeModelHelper));
 173  0
             cluSetRangePicker.getSearchWindow().addActionCompleteCallback(new Callback<Boolean>() {
 174  
                 @Override
 175  
                 public void exec(Boolean result) {
 176  0
                     cluSetRangePicker.getSearchWindow().hide();
 177  
 //                  ((ModelWidgetBinding)cluRangeFieldDescriptor.getModelWidgetBinding()).setWidgetValue(widget, model, path)
 178  
 //                  CluSetHelper cluSetHelper = CluSetHelper.wrap(model.getRoot());
 179  
 //                  cluSetHelper.setCluRangeParams(value)
 180  0
                     final SearchRequest searchRequest = cluSetRangePicker.getSearchWindow().getSearchRequest();
 181  0
                     String selectedSearchKey = searchRequest.getSearchKey();
 182  0
                     Data searchRequestData = CluSetRangeModelUtil.INSTANCE.toData(searchRequest, null);
 183  0
                     LookupMetadata lookupMetadata = null;
 184  
 
 185  
                     // look for the lookupMetaData corresponding to the searchRequest
 186  0
                     List<LookupMetadata> lookupMDs = new ArrayList<LookupMetadata>();
 187  0
                     lookupMDs.add(cluSetRangePicker.getInitLookupMetadata());
 188  0
                     lookupMetadata = findLookupMetadataByLookupId(selectedSearchKey, 
 189  
                             lookupMDs, searchRequest.getParams());
 190  0
                     if (lookupMetadata == null || 
 191  
                             !nullSafeEquals(lookupMetadata.getSearchTypeId(), 
 192  
                                     selectedSearchKey)) {
 193  0
                         lookupMetadata = findLookupMetadataByLookupId(selectedSearchKey, 
 194  
                                 cluSetRangePicker.getAdditionalLookupMetadata(),
 195  
                                 searchRequest.getParams());
 196  
                     }
 197  
 
 198  0
                     addClusetItemViewHandler(clusetRangeModelHelper,
 199  
                             theClusetRangeLabel,
 200  
                             lookupMetadata,
 201  
                             searchRequestData,
 202  
                             searchRequest);
 203  0
                     theClusetRangeLabel.setHighlighted(true);
 204  0
                     new Timer() {
 205  
                         @Override
 206  
                         public void run() {
 207  0
                             theClusetRangeLabel.setHighlighted(false);
 208  0
                         }
 209  
                     }.schedule(5000);
 210  0
                 }
 211  
             });
 212  0
             clusetDetails.addSection(cluRangeSection, CommonWidgetConstants.CLU_SET_SWAP_CLU_SET_RANGE);
 213  
         }
 214  
         // END OF items related to Add Clu Range
 215  
 
 216  
         // ****** Add cluSets *******
 217  0
         KSListPanel cluSetsListPanel = null;
 218  0
         KSSelectedList cluSetsSelection = null;
 219  0
         if (displayField(CluSetManagementField.CLUSETS)) {
 220  0
             Section cluSetSection = new VerticalSection();
 221  0
             FieldDescriptor cluSetsTempFd = getFieldDescriptor( 
 222  
                     CommonWidgetConstants.CLU_SET_CLU_SETS_FIELD, 
 223  
                     generateMessageInfo(CommonWidgetConstants.NEW_CLU_SET_CONTENT_CLUSET + labelType),
 224  
                     null,
 225  
                     null);
 226  0
             KSSelectedList tempCluSetsSelection = (KSSelectedList) cluSetsTempFd.getFieldWidget();
 227  0
             WidgetConfigInfo config = tempCluSetsSelection.getConfig();
 228  0
             cluSetsSelection = new KSSelectedList(config, false);
 229  0
             cluSetsListPanel = cluSetsSelection.separateValuesPanel();
 230  0
             final FieldDescriptor cluSetsFd = addField(
 231  
                     cluSetSection, 
 232  
                     CommonWidgetConstants.CLU_SET_CLU_SETS_FIELD, 
 233  
                     generateMessageInfo(CommonWidgetConstants.NEW_CLU_SET_CONTENT_CLUSET + labelType),
 234  
                     cluSetsSelection, 
 235  
                     null);
 236  0
             cluSetsFd.setWidgetBinding(new CluSetBinding());
 237  0
             clusetDetails.addSection(cluSetSection, CommonWidgetConstants.CLU_SET_SWAP_CLU_SETS);
 238  
         }
 239  
         // END OF items related to Add CluSets
 240  
 
 241  
         // display item type title if the list selected items is populated
 242  
         // hide if the list becomes empty (thus the close listeners for each item
 243  0
         String contextName = (cluSetType != null && cluSetType.equals("kuali.cluSet.type.Program"))?
 244  
                 "PROGRAMS" : "COURSES";
 245  0
         VerticalFlowPanel selectedValuesPanel = new VerticalFlowPanel();
 246  0
         selectedValuesPanel.getElement().getStyle().setPaddingTop(20, Style.Unit.PX);
 247  0
         VerticalFlowPanel approvedClusPanel = prepareValuesPanel(approvedClusListPanel, "APPROVED " + contextName);
 248  0
         approvedClusPanel.getElement().getStyle().setPaddingTop(15, Style.Unit.PX);
 249  0
         VerticalFlowPanel proposedClusPanel = prepareValuesPanel(proposedClusListPanel, "PROPOSED " + contextName);
 250  0
         proposedClusPanel.getElement().getStyle().setPaddingTop(15, Style.Unit.PX);
 251  0
         VerticalFlowPanel rangePanel = null;
 252  0
         if (displayField(CluSetManagementField.RANGE)) {
 253  0
             rangePanel = prepareValuesPanel(clusetRangeLabel, contextName + " RANGE");
 254  0
             rangePanel.getElement().getStyle().setPaddingTop(15, Style.Unit.PX);
 255  
         }
 256  0
         VerticalFlowPanel cluSetsPanel = null;
 257  0
         if (displayField(CluSetManagementField.CLUSETS)) {
 258  0
             cluSetsPanel = prepareValuesPanel(cluSetsListPanel, contextName + " SETS");
 259  0
             cluSetsPanel.getElement().getStyle().setPaddingTop(15, Style.Unit.PX);
 260  
         }
 261  
         
 262  0
         selectedValuesPanel.add(approvedClusPanel);
 263  0
         selectedValuesPanel.add(proposedClusPanel);
 264  0
         if (displayField(CluSetManagementField.RANGE)) {
 265  0
             selectedValuesPanel.add(rangePanel);
 266  
         }
 267  0
         if (displayField(CluSetManagementField.CLUSETS)) {
 268  0
             selectedValuesPanel.add(cluSetsPanel);
 269  
         }
 270  
 
 271  0
         addVisibilityHandlers(approvedClusSelection, approvedClusPanel);
 272  0
         addVisibilityHandlers(proposedClusSelection, proposedClusPanel);
 273  0
         if (displayField(CluSetManagementField.RANGE)) {
 274  0
             addVisibilityHandlers(clusetRangeLabel, rangePanel);
 275  
         }
 276  0
         if (displayField(CluSetManagementField.CLUSETS)) {
 277  0
             addVisibilityHandlers(cluSetsSelection, cluSetsPanel);
 278  
         }
 279  
         
 280  0
         selectedListPanelPairs.add(new KSSelectedListPanelPair(approvedClusSelection, approvedClusPanel));
 281  0
         selectedListPanelPairs.add(new KSSelectedListPanelPair(proposedClusSelection, proposedClusPanel));
 282  0
         if (displayField(CluSetManagementField.CLUSETS)) {
 283  0
             selectedListPanelPairs.add(new KSSelectedListPanelPair(cluSetsSelection, cluSetsPanel));
 284  
         }
 285  0
         if (displayField(CluSetManagementField.RANGE)) {
 286  0
             itemLabelPanelPairs.add(new KSItemLabelPanelPair(clusetRangeLabel, rangePanel));
 287  
         }
 288  
         
 289  0
         final VerticalSection choosingSection = new VerticalSection();
 290  0
         choosingSection.addWidget(
 291  
                 new HTML("<b>Add a course, course set, or course range</b>"));
 292  0
         choosingSection.addWidget(chooser);
 293  0
         choosingSection.addSection(clusetDetails);
 294  0
         chooser.addSelectionChangeHandler(new SelectionChangeHandler() {
 295  
             @Override
 296  
             public void onSelectionChange(SelectionChangeEvent event) {
 297  0
                 if (chooser.getSelectedItem() != null &&
 298  
                         !chooser.getSelectedItem().trim().isEmpty()) {
 299  0
                     choosingSection.setStyleName("KS-CluSetManagement-chooser");
 300  
                 } else {
 301  0
                     choosingSection.setStyleName("KS-CluSetManagement-chooser-unselected");
 302  
                 }
 303  0
             }
 304  
         });
 305  
         
 306  0
         HTML html = new HTML("Add courses, course sets, or course ranges to your course set. You may <br/>" +
 307  
             "add any combination of courses, dynamic course ranges, or Course sets. ");
 308  0
         this.addWidget(html);
 309  0
         this.addSection(choosingSection);
 310  0
         this.addWidget(selectedValuesPanel);
 311  0
     }
 312  
     
 313  
     private boolean displayField(CluSetManagementField field) {
 314  0
         boolean result = false;
 315  0
         switch(field) {
 316  
             case APPROVED:
 317  
             case PROPOSED:
 318  0
                 result = true;
 319  0
                 break;
 320  
             case RANGE:
 321  0
                 if (!singularCluOnly && (cluSetType == null || !cluSetType.equals("kuali.cluSet.type.Program"))) {
 322  0
                     result = true;
 323  
                 } else {
 324  0
                     result = false;
 325  
                 }
 326  0
                 break;
 327  
             case CLUSETS:
 328  0
                 if (!singularCluOnly) {
 329  0
                     result = true;
 330  
                 } else {
 331  0
                     result = false;
 332  
                 }
 333  
                 break;
 334  
         }
 335  0
         return result;
 336  
     }
 337  
     
 338  
     private void addClusetItemViewHandler(CluSetRangeDataHelper clusetRangeModelHelper,
 339  
             KSItemLabel clusetRangeLabel,
 340  
             final LookupMetadata lookupMetadata,
 341  
             Data searchRequestData,
 342  
             final SearchRequest searchRequest) {
 343  0
         clusetRangeModelHelper.setLookupMetadata(lookupMetadata);
 344  0
         clusetRangeLabel.setValue(new DataValue(searchRequestData));
 345  0
         if (showCluRangeDetailsHandlerRegs != null && 
 346  
                 showCluRangeDetailsHandlerRegs.get(Integer.toString(clusetRangeLabel.instanceId)) != null) {
 347  0
             ((HandlerRegistration)showCluRangeDetailsHandlerRegs.get(Integer.toString(clusetRangeLabel.instanceId))).removeHandler();
 348  
         }
 349  0
         showCluRangeDetailsHandlerRegs.put(Integer.toString(clusetRangeLabel.instanceId), 
 350  0
                 clusetRangeLabel.addShowDetailsHandler(new ClickHandler() {
 351  
             @Override
 352  
             public void onClick(ClickEvent event) {
 353  0
                 SearchResultsLightBox srLightBox = new SearchResultsLightBox("View Course Range",
 354  
                         searchRequest, lookupMetadata);
 355  0
                 srLightBox.show();
 356  0
             }
 357  
         }));
 358  0
     }
 359  
     
 360  
     protected MessageKeyInfo generateMessageInfo(String labelKey) {
 361  0
         return new MessageKeyInfo("clusetmanagement", "clusetmanagement", "draft", labelKey);
 362  
     }
 363  
     
 364  
     private FieldDescriptor getFieldDescriptor( 
 365  
             String fieldKey, 
 366  
             MessageKeyInfo messageKey, 
 367  
             Widget widget, 
 368  
             String parentPath) {
 369  0
         QueryPath path = QueryPath.concat(parentPath, fieldKey);
 370  0
         Metadata meta = modelDefinition.getMetadata(path);
 371  
         FieldDescriptor fd;
 372  0
         if (widget != null) {
 373  0
             fd = new FieldDescriptor(path.toString(), messageKey, meta, widget);
 374  
         }
 375  
         else{
 376  0
             fd = new FieldDescriptor(path.toString(), messageKey, meta);
 377  
         }
 378  0
         return fd;
 379  
     }
 380  
 
 381  
     private FieldDescriptor addField(Section section, 
 382  
             String fieldKey, 
 383  
             MessageKeyInfo messageKey, 
 384  
             Widget widget, 
 385  
             String parentPath) {
 386  0
         FieldDescriptor fd = getFieldDescriptor(fieldKey, messageKey, widget, parentPath);
 387  0
         section.addField(fd);
 388  0
         return fd;
 389  
     }
 390  
 
 391  
     private static boolean nullSafeEquals(Object obj1, Object obj2) {
 392  0
         return (obj1 == null && obj2 == null ||
 393  
                 obj1 != null && obj2 != null && obj1.equals(obj2));
 394  
     }
 395  
     
 396  
     private VerticalFlowPanel prepareValuesPanel(Widget widget, String title) {
 397  0
         final VerticalFlowPanel valuesPanel = new VerticalFlowPanel();
 398  0
         valuesPanel.add(new KSLabel(title));
 399  0
         valuesPanel.add(widget);
 400  0
         valuesPanel.setVisible(false);
 401  0
         return valuesPanel;
 402  
     }
 403  
     
 404  
     @Override
 405  
     public void updateWidgetData(DataModel model) {
 406  0
         super.updateWidgetData(model);
 407  
         // this is to refresh the lists and item labels.
 408  0
         if (selectedListPanelPairs != null) {
 409  0
             for (KSSelectedListPanelPair selectedListPanelPair : selectedListPanelPairs) {
 410  0
                 handleSelectedListVisibility(selectedListPanelPair.getKsSelectedList(), 
 411  
                         selectedListPanelPair.getPanel());
 412  
             }
 413  
         }
 414  0
         if (itemLabelPanelPairs != null) {
 415  0
             for (KSItemLabelPanelPair itemLabelPanelPair : itemLabelPanelPairs) {
 416  0
                 handleListItemVisibility(itemLabelPanelPair.getKsItemLabel(), 
 417  
                         itemLabelPanelPair.getPanel());
 418  
             }
 419  
         }
 420  0
     }
 421  
 
 422  
     private void addVisibilityHandlers(final KSItemLabel listItem,
 423  
             final Panel selectionPanel) {
 424  0
         listItem.addValueChangeCallback(new Callback<Value>() {
 425  
             @Override
 426  
             public void exec(Value result) {
 427  0
                 handleListItemVisibility(listItem, selectionPanel);
 428  0
             }
 429  
         });
 430  0
     }
 431  
     
 432  
     private void handleListItemVisibility(KSItemLabel listItem, Panel selectionPanel) {
 433  0
         String displayText = listItem.getDisplayText();
 434  0
         if (displayText == null || displayText.equals("")) {
 435  0
             selectionPanel.setVisible(false);
 436  
         } else {
 437  0
             selectionPanel.setVisible(true);
 438  
         }
 439  0
     }
 440  
     
 441  
     private void addVisibilityHandlers(final KSSelectedList selectionList,
 442  
             final Panel selectionPanel) {
 443  0
         selectionList.addSelectionChangeHandler(
 444  0
                 new SelectionChangeHandler() {
 445  
                     @Override
 446  
                     public void onSelectionChange(SelectionChangeEvent event) {
 447  0
                         handleSelectedListVisibility(selectionList, selectionPanel);
 448  0
                     }
 449  
                 }
 450  
         );
 451  0
     }
 452  
     
 453  
     private void handleSelectedListVisibility(final KSSelectedList selectionList, final Panel selectionPanel) {
 454  0
         List<KSItemLabel> selectedItems = selectionList.getSelectedItems();
 455  0
         if (selectedItems != null && !selectedItems.isEmpty()) {
 456  
             // show item type title
 457  0
             selectionPanel.setVisible(true);
 458  0
             for (KSItemLabel selectedItem : selectedItems) {
 459  0
                 selectedItem.addCloseHandler(new CloseHandler<KSItemLabel>() {
 460  
                     @Override
 461  
                     public void onClose(CloseEvent<KSItemLabel> event) {
 462  0
                         List<KSItemLabel> newSelectedItems = 
 463  
                             selectionList.getSelectedItems();
 464  0
                         int numNewSelectedItems = (newSelectedItems == null)? 0 :
 465  
                             newSelectedItems.size();
 466  0
                         if (numNewSelectedItems == 0) {
 467  
                             //hide item type title
 468  0
                             selectionPanel.setVisible(false);
 469  
                         }
 470  0
                     }
 471  
                 });
 472  
             }
 473  
         }
 474  0
     }
 475  
 
 476  
     private Picker configureSearch(String fieldKey) {
 477  0
         QueryPath path = QueryPath.concat(null, fieldKey);
 478  0
         Metadata metaData = modelDefinition.getMetadata(path);
 479  0
         Picker picker = new Picker(metaData.getInitialLookup(), metaData.getAdditionalLookups());
 480  0
         return picker;
 481  
     }
 482  
 
 483  
     private static LookupMetadata findLookupMetadataByLookupId(String searchTypeId,
 484  
             List<LookupMetadata> lookupMetadatas,
 485  
             List<SearchParam> searchParams) {
 486  0
         LookupMetadata result = null;
 487  0
         if (lookupMetadatas != null) {
 488  0
             for (LookupMetadata lookupMetadata : lookupMetadatas) {
 489  0
                 if (nullSafeEquals(lookupMetadata.getSearchTypeId(), searchTypeId)) {
 490  
                     // search Type id matches now add up all the params meta found to the result
 491  0
                     List<LookupParamMetadata> paramMetas = lookupMetadata.getParams();
 492  0
                     List<LookupParamMetadata> resultParamMetas = null;
 493  0
                     result = (result == null)? new LookupMetadata() : result;
 494  0
                     result.setDesc(lookupMetadata.getDesc());
 495  0
                     result.setId(lookupMetadata.getId());
 496  0
                     result.setName("");
 497  0
                     resultParamMetas = result.getParams();
 498  0
                     if (resultParamMetas == null) {
 499  0
                         resultParamMetas = new ArrayList<LookupParamMetadata>();
 500  
                     }
 501  0
                     if (paramMetas != null) {
 502  0
                         for (LookupParamMetadata paramMeta : paramMetas) {
 503  0
                             boolean resultParamMetaFound = false;
 504  0
                             for (LookupParamMetadata resultParamMeta : resultParamMetas) {
 505  0
                                 if (paramMeta.getKey().equals(resultParamMeta)) {
 506  0
                                     resultParamMetaFound = true;
 507  0
                                     break;
 508  
                                 }
 509  
                             }
 510  0
                             if (!resultParamMetaFound) {
 511  0
                                 resultParamMetas.add(paramMeta);
 512  
                             }
 513  0
                         }
 514  
                     }
 515  0
                     result.setParams(resultParamMetas);
 516  0
                     result.setQosMetadata(lookupMetadata.getQosMetadata());
 517  0
                     result.setResultDisplayKey(lookupMetadata.getResultDisplayKey());
 518  0
                     result.setResultReturnKey(lookupMetadata.getResultReturnKey());
 519  0
                     result.setResults(lookupMetadata.getResults());
 520  0
                     result.setResultSortKey(lookupMetadata.getResultSortKey());
 521  0
                 }
 522  
             }
 523  
         }
 524  0
         return result;
 525  
     }
 526  
     
 527  
     @Override
 528  
     public void updateModel() {
 529  
         
 530  0
         super.updateModel();
 531  0
     }
 532  
 
 533  
 
 534  
 
 535  
     public class CluSetEditOptionDropdown extends KSDropDown {
 536  0
         public CluSetEditOptionDropdown(){
 537  0
             SimpleListItems editOptions = new SimpleListItems();
 538  
 
 539  0
             if (cluSetType != null && cluSetType.equals("kuali.cluSet.type.Program")) {
 540  0
                 editOptions.addItem(CommonWidgetConstants.CLU_SET_SWAP_APPROVED_CLUS, "Approved Programs");
 541  0
                 editOptions.addItem(CommonWidgetConstants.CLU_SET_SWAP_PROPOSED_CLUS, "Proposed Programs");
 542  0
                 if (!CluSetEditorWidget.this.singularCluOnly) {
 543  0
                     editOptions.addItem(CommonWidgetConstants.CLU_SET_SWAP_CLU_SETS, "Program Sets");
 544  
                 }
 545  
             } else {
 546  0
                 editOptions.addItem(CommonWidgetConstants.CLU_SET_SWAP_APPROVED_CLUS, "Approved Courses");
 547  0
                 editOptions.addItem(CommonWidgetConstants.CLU_SET_SWAP_PROPOSED_CLUS, "Proposed Courses");
 548  0
                 if (!CluSetEditorWidget.this.singularCluOnly) {
 549  0
                     editOptions.addItem(CommonWidgetConstants.CLU_SET_SWAP_CLU_SETS, "Course Sets");
 550  0
                     editOptions.addItem(CommonWidgetConstants.CLU_SET_SWAP_CLU_SET_RANGE, "Course Ranges (Course numbers, common learning objectives, etc)");
 551  
                 }
 552  
             }
 553  0
             super.setListItems(editOptions);
 554  0
         }
 555  
     }
 556  
 
 557  
     class KSSelectedListPanelPair {
 558  
         private KSSelectedList ksSelectedList;
 559  
         private Panel panel;
 560  0
         public KSSelectedListPanelPair(KSSelectedList ksSelectedList, Panel panel) {
 561  0
             setKsSelectedList(ksSelectedList);
 562  0
             setPanel(panel);
 563  0
         }
 564  
         public KSSelectedList getKsSelectedList() {
 565  0
             return ksSelectedList;
 566  
         }
 567  
         public void setKsSelectedList(KSSelectedList ksSelectedList) {
 568  0
             this.ksSelectedList = ksSelectedList;
 569  0
         }
 570  
         public Panel getPanel() {
 571  0
             return panel;
 572  
         }
 573  
         public void setPanel(Panel panel) {
 574  0
             this.panel = panel;
 575  0
         }
 576  
     }
 577  
     
 578  
     class KSItemLabelPanelPair {
 579  
         private KSItemLabel ksItemLabel;
 580  
         private Panel panel;
 581  0
         public KSItemLabelPanelPair(KSItemLabel ksItemLabel, Panel panel) {
 582  0
             setKsItemLabel(ksItemLabel);
 583  0
             setPanel(panel);
 584  0
         }
 585  
         public KSItemLabel getKsItemLabel() {
 586  0
             return ksItemLabel;
 587  
         }
 588  
         public void setKsItemLabel(KSItemLabel ksItemLabel) {
 589  0
             this.ksItemLabel = ksItemLabel;
 590  0
         }
 591  
         public Panel getPanel() {
 592  0
             return panel;
 593  
         }
 594  
         public void setPanel(Panel panel) {
 595  0
             this.panel = panel;
 596  0
         }
 597  
     }
 598  
     
 599  
     public static class Picker extends KSPicker {
 600  
 
 601  
         private String name;
 602  
         private LookupMetadata initLookupMetadata;
 603  
         private List<LookupMetadata> additionalLookupMetadata;
 604  
 
 605  
         public Picker(LookupMetadata inLookupMetadata, List<LookupMetadata> additionalLookupMetadata) {
 606  0
             super(inLookupMetadata, additionalLookupMetadata);
 607  0
             this.initLookupMetadata = inLookupMetadata;
 608  0
             this.additionalLookupMetadata = additionalLookupMetadata;
 609  0
         }
 610  
 
 611  
         public String getName() {
 612  0
             return name;
 613  
         }
 614  
 
 615  
         public void setName(String name) {
 616  0
             this.name = name;
 617  0
         }
 618  
 
 619  
         public LookupMetadata getInitLookupMetadata() {
 620  0
             return initLookupMetadata;
 621  
         }
 622  
 
 623  
         public void setInitLookupMetadata(LookupMetadata initLookupMetadata) {
 624  0
             this.initLookupMetadata = initLookupMetadata;
 625  0
         }
 626  
 
 627  
         public List<LookupMetadata> getAdditionalLookupMetadata() {
 628  0
             return additionalLookupMetadata;
 629  
         }
 630  
 
 631  
         public void setAdditionalLookupMetadata(List<LookupMetadata> additionalLookupMetadata) {
 632  0
             this.additionalLookupMetadata = additionalLookupMetadata;
 633  0
         }
 634  
         
 635  
     }
 636  
     
 637  0
     public class CluSetBinding extends ModelWidgetBindingSupport<HasDataValue> {
 638  0
         private HasDataValueBinding binding = HasDataValueBinding.INSTANCE;
 639  
 
 640  
         @Override
 641  
         public void setModelValue(HasDataValue widget, DataModel model, String path) {
 642  0
             binding.setModelValue(widget, model, path);
 643  0
         }
 644  
 
 645  
         @Override
 646  
         public void setWidgetValue(HasDataValue widget, DataModel model, String path) {
 647  0
             binding.setWidgetValue(widget, model, path);
 648  0
         }
 649  
     }
 650  
     
 651  0
     public class CluSetRangeBinding extends ModelWidgetBindingSupport<HasDataValue> {
 652  0
         private HasDataValueBinding binding = HasDataValueBinding.INSTANCE;
 653  0
         private CluSetRangeDataHelper clusetRangeModelHelper = null;
 654  
         
 655  0
         public CluSetRangeBinding(CluSetRangeDataHelper clusetRangeModelHelper) {
 656  0
             this.clusetRangeModelHelper = clusetRangeModelHelper;
 657  0
         }
 658  
         
 659  
         @Override
 660  
         public void setModelValue(HasDataValue widget, DataModel model, String path) {
 661  0
             binding.setModelValue(widget, model, path);
 662  0
         }
 663  
 
 664  
         @Override
 665  
         public void setWidgetValue(final HasDataValue widget, DataModel model, String path) {
 666  0
             DataModel middleManModel = new DataModel();
 667  0
             if (model != null && model.getRoot() != null) {
 668  0
                 middleManModel = new DataModel(model.getDefinition(), model.getRoot().copy());
 669  
             }
 670  0
             Metadata rangeEditMetaData = model.getMetadata(
 671  
                     QueryPath.parse(CommonWidgetConstants.CLU_SET_CLU_SET_RANGE_EDIT_FIELD));
 672  0
             Data membershipQueryData = (Data)model.get(path);
 673  0
             MembershipQueryInfo membershipQueryInfo = (membershipQueryData == null)?
 674  
                     null : CluSetRangeModelUtil.INSTANCE.toMembershipQueryInfo(membershipQueryData);
 675  0
             if (membershipQueryInfo != null) {
 676  0
                 String selectedSearchTypeKey = membershipQueryInfo.getSearchTypeKey();
 677  0
                 List<LookupMetadata> lookupMDs = new ArrayList<LookupMetadata>();
 678  0
                 lookupMDs.add(rangeEditMetaData.getInitialLookup());
 679  0
                 LookupMetadata lookupMetadata = findLookupMetadataByLookupId(selectedSearchTypeKey, 
 680  
                         lookupMDs, membershipQueryInfo.getQueryParamValueList());
 681  0
                 if (lookupMetadata == null || 
 682  
                         !nullSafeEquals(lookupMetadata.getName(), 
 683  
                                 selectedSearchTypeKey)) {
 684  0
                     lookupMetadata = findLookupMetadataByLookupId(selectedSearchTypeKey, 
 685  
                             rangeEditMetaData.getAdditionalLookups(),
 686  
                             membershipQueryInfo.getQueryParamValueList());
 687  
                 }
 688  
 
 689  0
                 SearchRequest searchRequest = new SearchRequest();
 690  0
                 searchRequest.setSearchKey(selectedSearchTypeKey);
 691  
 //              if ()
 692  0
                 searchRequest.setParams(membershipQueryInfo.getQueryParamValueList());
 693  0
                 searchRequest.setSortColumn(lookupMetadata.getResultSortKey());
 694  
                 
 695  
 //                if (showCluRangeDetailsHandlerRegs != null) {
 696  
 //                    for (HandlerRegistration showCluRangeDetailsHandlerReg : showCluRangeDetailsHandlerRegs) {
 697  
 //                        showCluRangeDetailsHandlerReg.removeHandler();
 698  
 //                    }
 699  
 //                    showCluRangeDetailsHandlerRegs.clear();
 700  
 //                }
 701  0
                 addClusetItemViewHandler(clusetRangeModelHelper,
 702  
                         (KSItemLabel)widget,
 703  
                         lookupMetadata,
 704  
                         membershipQueryData,
 705  
                         searchRequest);
 706  0
                 ((KSItemLabel)widget).setHighlighted(true);
 707  0
                 new Timer() {
 708  
                     @Override
 709  
                     public void run() {
 710  0
                         ((KSItemLabel)widget).setHighlighted(false);
 711  0
                     }
 712  
                 }.schedule(5000);
 713  
             }
 714  0
             binding.setWidgetValue(widget, middleManModel, path);
 715  0
         }
 716  
     }
 717  
 }