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