Coverage Report - org.kuali.student.common.ui.client.configurable.mvc.multiplicity.MultiplicityGroup
 
Classes in this File Line Coverage Branch Coverage Complexity
MultiplicityGroup
0%
0/216
0%
0/82
1.857
MultiplicityGroup$1
0%
0/5
N/A
1.857
MultiplicityGroup$2
0%
0/3
N/A
1.857
MultiplicityGroup$3
0%
0/3
N/A
1.857
MultiplicityGroup$4
0%
0/3
N/A
1.857
MultiplicityGroup$ConditionChoices
0%
0/41
0%
0/4
1.857
MultiplicityGroup$SwappableFieldsHelper
0%
0/43
0%
0/20
1.857
 
 1  
 /**
 2  
  * Copyright 2010 The Kuali Foundation Licensed under the
 3  
  * Educational Community License, Version 2.0 (the "License"); you may
 4  
  * not use this file except in compliance with the License. You may
 5  
  * obtain a copy of the License at
 6  
  * <p/>
 7  
  * http://www.osedu.org/licenses/ECL-2.0
 8  
  * <p/>
 9  
  * Unless required by applicable law or agreed to in writing,
 10  
  * software distributed under the License is distributed on an "AS IS"
 11  
  * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 12  
  * or implied. See the License for the specific language governing
 13  
  * permissions and limitations under the License.
 14  
  * <p/>
 15  
  */
 16  
 package org.kuali.student.common.ui.client.configurable.mvc.multiplicity;
 17  
 
 18  
 import java.util.ArrayList;
 19  
 import java.util.HashMap;
 20  
 import java.util.List;
 21  
 import java.util.Map;
 22  
 import java.util.Set;
 23  
 import java.util.Map.Entry;
 24  
 
 25  
 import org.kuali.student.common.ui.client.configurable.mvc.FieldDescriptor;
 26  
 import org.kuali.student.common.ui.client.configurable.mvc.binding.ModelWidgetBinding;
 27  
 import org.kuali.student.common.ui.client.configurable.mvc.sections.BaseSection;
 28  
 import org.kuali.student.common.ui.client.configurable.mvc.sections.GroupSection;
 29  
 import org.kuali.student.common.ui.client.configurable.mvc.sections.MultiplicitySection;
 30  
 import org.kuali.student.common.ui.client.configurable.mvc.sections.Section;
 31  
 import org.kuali.student.common.ui.client.configurable.mvc.sections.SwapSection;
 32  
 import org.kuali.student.common.ui.client.configurable.mvc.sections.VerticalSection;
 33  
 import org.kuali.student.common.ui.client.mvc.Callback;
 34  
 import org.kuali.student.common.ui.client.mvc.DataModel;
 35  
 import org.kuali.student.common.ui.client.widgets.KSButton;
 36  
 import org.kuali.student.common.ui.client.widgets.KSButtonAbstract.ButtonStyle;
 37  
 import org.kuali.student.common.ui.client.widgets.ListOfStringWidget;
 38  
 import org.kuali.student.common.ui.client.widgets.list.KSRadioButtonList;
 39  
 import org.kuali.student.common.ui.client.widgets.list.KSSelectItemWidgetAbstract;
 40  
 import org.kuali.student.common.ui.client.widgets.list.ListItems;
 41  
 import org.kuali.student.common.ui.client.widgets.list.SelectionChangeEvent;
 42  
 import org.kuali.student.common.ui.client.widgets.list.SelectionChangeHandler;
 43  
 import org.kuali.student.common.ui.client.widgets.list.impl.KSRadioButtonListImpl;
 44  
 import org.kuali.student.common.ui.client.widgets.list.impl.SimpleListItems;
 45  
 import org.kuali.student.common.ui.client.widgets.search.KSPicker;
 46  
 import org.kuali.student.core.assembly.data.Data;
 47  
 import org.kuali.student.core.assembly.data.MetadataInterrogator;
 48  
 import org.kuali.student.core.assembly.data.QueryPath;
 49  
 
 50  
 import com.google.gwt.core.client.GWT;
 51  
 import com.google.gwt.event.dom.client.BlurHandler;
 52  
 import com.google.gwt.event.dom.client.ClickEvent;
 53  
 import com.google.gwt.event.dom.client.ClickHandler;
 54  
 import com.google.gwt.event.dom.client.FocusHandler;
 55  
 import com.google.gwt.event.shared.HandlerRegistration;
 56  
 import com.google.gwt.user.client.ui.Composite;
 57  
 import com.google.gwt.user.client.ui.FlowPanel;
 58  
 import com.google.gwt.user.client.ui.Widget;
 59  
 
 60  
 
 61  0
 public class MultiplicityGroup extends Composite {
 62  
 
 63  
     private MultiplicityConfiguration config;
 64  
 
 65  0
     private List<MultiplicityGroupItem> items = new ArrayList<MultiplicityGroupItem>();
 66  0
     private List<MultiplicityGroupItem> removed = new ArrayList<MultiplicityGroupItem>();
 67  
 
 68  0
     private FlowPanel mainPanel = new FlowPanel();
 69  0
     private FlowPanel itemsPanel = new FlowPanel();
 70  0
     private boolean loaded = false;
 71  0
     private int itemCount = 0;
 72  
     private String parentPath;
 73  0
     private boolean isDirty = false;
 74  
 
 75  
     private Map<SwapCompositeCondition, List<SwapCompositeConditionFieldConfig>> swappableFieldsDefinition;
 76  
     private List<String> deletionParentKeys;
 77  
 
 78  0
     public MultiplicityGroup() {
 79  0
     }
 80  
 
 81  
     public MultiplicityGroup(MultiplicityConfiguration config,
 82  
             Map<SwapCompositeCondition, List<SwapCompositeConditionFieldConfig>> swappableFieldsDefinition,
 83  0
             List<String> deletionParentKeys) {
 84  0
         this.config = config;
 85  0
         initWidget(mainPanel);
 86  0
         this.swappableFieldsDefinition = swappableFieldsDefinition;
 87  0
         this.deletionParentKeys = deletionParentKeys;
 88  0
     }
 89  
 
 90  
 
 91  
     /**
 92  
      * Creates an instance of a MultiplicityGroup based on the options in the MultiplicityConfiguration
 93  
      *
 94  
      * A MultiplicityGroup uses GroupSection to display data in a variable grid.  May be multiple rows and multiple fields per row based on
 95  
      * the defs in the MultiplicityConfiguration.
 96  
      *
 97  
      * May contain one or more MultiplicityItemSections based on user action, dictionary defs or data found in the model.
 98  
      *
 99  
      * @param config
 100  
      */
 101  0
     public MultiplicityGroup(MultiplicityConfiguration config){
 102  0
         this.config = config;
 103  0
         initWidget(mainPanel);
 104  0
     }
 105  
 
 106  0
     protected Callback<MultiplicityGroupItem> removeCallback = new Callback<MultiplicityGroupItem>(){
 107  
 
 108  
         public void exec(MultiplicityGroupItem itemToRemove) {
 109  0
             itemToRemove.setDeleted(true);
 110  0
             removed.add(itemToRemove);
 111  0
             itemsPanel.remove(itemToRemove);
 112  0
         }
 113  
     };
 114  
 
 115  
     public void onLoad() {
 116  0
         if (!loaded) {
 117  0
             mainPanel.add(itemsPanel);
 118  
 
 119  0
             if(config.isUpdateable()){
 120  0
                 Widget addWidget = generateAddWidget();
 121  0
                 mainPanel.add(addWidget);
 122  
             }
 123  
 
 124  0
             loaded = true;
 125  
         }
 126  
 
 127  0
         if (!loaded || itemCount == 0){
 128  0
                 Integer minOccurs = MetadataInterrogator.getLargestMinOccurs(config.getMetaData());
 129  
                 
 130  0
                 if (minOccurs != null) {
 131  0
                     for (int i=0; i < minOccurs; i++){
 132  0
                             createItem();
 133  
                     }
 134  
                 }
 135  0
                 else if(config.getDefaultItemsCreated() != 0){
 136  0
                         for (int i=0; i < config.getDefaultItemsCreated(); i++){
 137  0
                             createItem();
 138  
                     }
 139  
                 }
 140  
 
 141  
         }
 142  0
     }
 143  
 
 144  
     private Widget generateAddWidget() {
 145  
             KSButton addWidget;
 146  0
             if(config.getStyleType() == MultiplicityConfiguration.StyleType.TOP_LEVEL_GROUP){
 147  0
                     addWidget = new KSButton(config.getAddItemLabel(), ButtonStyle.FORM_LARGE);
 148  
             }
 149  
             else{
 150  0
                     addWidget = new KSButton(config.getAddItemLabel(), ButtonStyle.FORM_SMALL);
 151  
             }
 152  0
         addWidget.addClickHandler(new ClickHandler(){
 153  
             public void onClick(ClickEvent event) {
 154  0
                 createItem();
 155  0
             }
 156  
         });
 157  0
         return addWidget;
 158  
     }
 159  
 
 160  
     /**
 161  
      * This adds an empty item to the multiplicity group
 162  
      *
 163  
      * @return
 164  
      */
 165  
         public MultiplicityGroupItem createItem(){
 166  
 
 167  0
                 itemCount++;
 168  
 
 169  0
                 MultiplicityGroupItem item = new MultiplicityGroupItem(config.getItemLabel() + " " + itemCount, config.getStyleType(), config.isUpdateable());
 170  
 
 171  0
         Widget itemWidget = createWidget();
 172  
 
 173  0
             if (item != null){
 174  0
                     item.setItemKey(new Integer(itemCount -1));
 175  0
                     item.setItemWidget(itemWidget);
 176  0
                     item.setRemoveCallback(removeCallback);
 177  0
             } else if (itemWidget instanceof MultiplicityGroupItem){
 178  0
                     item = (MultiplicityGroupItem)itemWidget;
 179  0
                     item.setItemKey(new Integer(itemCount -1));
 180  
             }
 181  0
             items.add(item);
 182  0
             item.redraw();
 183  0
             itemsPanel.add(item);
 184  0
         isDirty = true;
 185  
 
 186  0
         return item;
 187  
         }
 188  
 
 189  
         public FlowPanel getItemsPanel() {
 190  0
             return itemsPanel;
 191  
         }
 192  
 
 193  
     private Widget createWidget() {
 194  
 
 195  0
                 GroupSection section = new GroupSection();
 196  0
         final SwappableFieldsHelper helper = new SwappableFieldsHelper();
 197  
         // helperFieldKeys maps the paths with asterisks into absolute paths
 198  0
         final Map<String, String> helperFieldKeys = new HashMap<String, String>();
 199  0
         SwapSection swapSection = null;
 200  
 
 201  
                 //TODO might want fields and nested multiplicities at the same time. Remove if/else
 202  
 
 203  0
                 if (config.getNestedConfig() != null) {
 204  0
             MultiplicitySection ms = new MultiplicitySection(config.getNestedConfig().copy());
 205  0
                         String p = config.getNestedConfig().getParentFd().getFieldKey().replace('*', Character.forDigit(itemCount-1, 10));
 206  0
                     ms.setParentPath(p);
 207  0
             section.addSection(ms);
 208  0
                 }
 209  
                 else {
 210  0
                         for (Integer row  : config.getFields().keySet()) {
 211  0
                                 List<MultiplicityFieldConfiguration> fieldConfigs = config.getFields().get(row);
 212  0
                                 for (MultiplicityFieldConfiguration fieldConfig : fieldConfigs) {
 213  
                     //TODO  Should copy widgets/bindings too?
 214  0
                     FieldDescriptor newfd = null;
 215  0
                     Widget fieldWidget = null;
 216  0
                     if (fieldConfig.getFieldWidgetInitializer() != null) {
 217  0
                         fieldWidget = fieldConfig.getFieldWidgetInitializer().getNewWidget();
 218  0
                         ModelWidgetBinding mwb = fieldConfig.getFieldWidgetInitializer()
 219  
                             .getModelWidgetBindingInstance();
 220  0
                         newfd = new FieldDescriptor(
 221  
                                 translatePath(fieldConfig.getFieldPath()),
 222  
                                 fieldConfig.getMessageKeyInfo(),
 223  
                                 fieldConfig.getMetadata(),
 224  
                                 fieldWidget);
 225  0
                         newfd.setWidgetBinding(mwb);
 226  0
                     } else {
 227  0
                         newfd = new FieldDescriptor(
 228  
                                 translatePath(fieldConfig.getFieldPath()),
 229  
                                 fieldConfig.getMessageKeyInfo(),
 230  
                                 fieldConfig.getMetadata());
 231  0
                         fieldWidget = newfd.getFieldWidget();
 232  
                     }
 233  0
                     newfd.getFieldElement().setRequired(fieldConfig.isRequired());
 234  0
                     section.addField(newfd);
 235  0
                     helperFieldKeys.put(fieldConfig.getFieldPath(), newfd.getFieldKey());
 236  
 
 237  
                     // add handlers to all select field that can be selected and triggers
 238  
                     // selection change event to notify the swap section to switch section.
 239  0
                     if (fieldWidget instanceof KSSelectItemWidgetAbstract) {
 240  0
                         ((KSSelectItemWidgetAbstract)fieldWidget).addSelectionChangeHandler(new SelectionChangeHandler() {
 241  
                             @Override
 242  
                             public void onSelectionChange(SelectionChangeEvent event) {
 243  0
                                 helper.updateFieldDisplay();
 244  0
                             }
 245  
                         });
 246  0
                     } else if (fieldWidget instanceof KSPicker) {
 247  0
                         Widget inputWidget = ((KSPicker)fieldWidget).getInputWidget();
 248  0
                         if (inputWidget instanceof KSSelectItemWidgetAbstract) {
 249  0
                             ((KSSelectItemWidgetAbstract)inputWidget).addSelectionChangeHandler(new SelectionChangeHandler() {
 250  
                                 @Override
 251  
                                 public void onSelectionChange(SelectionChangeEvent event) {
 252  0
                                     helper.updateFieldDisplay();
 253  0
                                 }
 254  
                             });
 255  
                         }
 256  
                     }
 257  0
                                 }
 258  0
                                 section.nextLine();
 259  0
                         }
 260  0
             if (swappableFieldsDefinition != null) {
 261  0
                 ConditionChoices conditionChoices = new ConditionChoices(
 262  
                         new ArrayList<SwapCompositeCondition>(
 263  
                                 swappableFieldsDefinition.keySet()));
 264  0
                 List<String> newDeletionParentKeys = null;
 265  0
                 swapSection = new SwapSection(conditionChoices);
 266  0
                 if (deletionParentKeys != null) {
 267  0
                     for (String deletionParentKey : deletionParentKeys) {
 268  0
                         newDeletionParentKeys = (newDeletionParentKeys == null)?
 269  
                                 new ArrayList<String>() : newDeletionParentKeys;
 270  0
                         newDeletionParentKeys.add(translatePath(deletionParentKey));
 271  
                     }
 272  
                 }
 273  0
                 swapSection.setDeletionParentKey(newDeletionParentKeys);
 274  0
                 helper.setConditionChoices(conditionChoices);
 275  
                 // go through swappableFieldsDefinition and create and add the fields
 276  
                 // into conditionSection
 277  0
                 for (Entry<SwapCompositeCondition, List<SwapCompositeConditionFieldConfig>> entry : swappableFieldsDefinition.entrySet()) {
 278  0
                     SwapCompositeCondition condition = entry.getKey();
 279  0
                     List<SwapCompositeConditionFieldConfig> fieldConfigs = entry.getValue();
 280  0
                     Section conditionSection = new VerticalSection();
 281  0
                     if (fieldConfigs != null) {
 282  0
                         for (SwapCompositeConditionFieldConfig conditionFieldConfig : fieldConfigs) {
 283  0
                             if (conditionFieldConfig.useMultiplicity()) {
 284  0
                                 MultiplicityConfiguration newSubMultiplicityConfig =
 285  
                                     configSwappableMultiplicitySection(
 286  
                                             conditionFieldConfig.getMultiplicityConfiguration());
 287  0
                                 MultiplicitySection subMultiplicitySection =
 288  
                                     new MultiplicitySection(newSubMultiplicityConfig);
 289  0
                                 conditionSection.addSection(subMultiplicitySection);
 290  0
                             } else {
 291  0
                                 MultiplicityFieldConfiguration fieldConfig =
 292  
                                     conditionFieldConfig.getMultiplicityFieldConfiguration();
 293  0
                                 FieldDescriptor concreteFieldDescriptor = new FieldDescriptor(
 294  
                                         translatePath(fieldConfig.getFieldPath()),
 295  
                                         fieldConfig.getMessageKeyInfo(),
 296  
                                         fieldConfig.getMetadata());
 297  0
                                 concreteFieldDescriptor.getFieldElement().setRequired(fieldConfig.isRequired());
 298  0
                                 if (fieldConfig.getFieldWidgetInitializer() != null) {
 299  0
                                     Widget fieldWidget = fieldConfig.getFieldWidgetInitializer().getNewWidget();
 300  0
                                     ModelWidgetBinding mwb = fieldConfig.getFieldWidgetInitializer()
 301  
                                         .getModelWidgetBindingInstance();
 302  0
                                     concreteFieldDescriptor.setFieldWidget(fieldWidget);
 303  0
                                     if(fieldWidget instanceof ListOfStringWidget){
 304  0
                                             ((ListOfStringWidget)fieldWidget).setFd(concreteFieldDescriptor);
 305  
                                     }
 306  
 
 307  0
                                     concreteFieldDescriptor.setWidgetBinding(mwb);
 308  
                                 }
 309  0
                                 conditionSection.addField(concreteFieldDescriptor);
 310  0
                                 helperFieldKeys.put(fieldConfig.getFieldPath(), translatePath(fieldConfig.getFieldPath()));
 311  0
                             }
 312  
                         }
 313  
                     }
 314  0
                     swapSection.addSection(conditionSection, condition.getConditionId());
 315  0
                 }
 316  0
                 section.addWidget(conditionChoices);
 317  0
                 section.addSection(swapSection);
 318  0
                 helper.setSwapSection(swapSection);
 319  
             }
 320  
 
 321  0
             helper.setParentSection(section);
 322  0
             helper.setSwappableFieldsDefinition(swappableFieldsDefinition);
 323  0
             helper.setHelperFieldKeys(helperFieldKeys);
 324  
         }
 325  0
                 return section;
 326  
         }
 327  
 
 328  
     public MultiplicityConfiguration configSwappableMultiplicitySection(MultiplicityConfiguration origConfig) {
 329  0
         MultiplicityConfiguration newSubMultiplicityConfig =
 330  
             origConfig.copy();
 331  
 
 332  0
         FieldDescriptor parentFd = origConfig.getParentFd();
 333  0
         FieldDescriptor subMultParentConfig =
 334  
             new FieldDescriptor(
 335  
                     translatePath(parentFd.getFieldKey()),
 336  
                     parentFd.getMessageKey(),
 337  
                     parentFd.getMetadata());
 338  0
         subMultParentConfig.getFieldElement().setRequired(parentFd.getFieldElement().isRequired());
 339  0
         newSubMultiplicityConfig.setParent(subMultParentConfig);
 340  0
         Map<Integer, List<MultiplicityFieldConfiguration>> fieldConfigsMap = newSubMultiplicityConfig.getFields();
 341  0
         Map<Integer, List<MultiplicityFieldConfiguration>> newFieldsMap = new HashMap<Integer, List<MultiplicityFieldConfiguration>>();
 342  0
         int lineCounter = 0;
 343  0
         if (fieldConfigsMap != null) {
 344  0
             for (List<MultiplicityFieldConfiguration> fieldConfigsInLine : fieldConfigsMap.values()) {
 345  0
                 List<MultiplicityFieldConfiguration> newFieldConfigs = new ArrayList<MultiplicityFieldConfiguration>();
 346  0
                 for (MultiplicityFieldConfiguration fieldConfig : fieldConfigsInLine) {
 347  0
                     String configParentKey = (parentFd.getFieldKey() == null)? "" : parentFd.getFieldKey();
 348  0
                     String configFieldKey = (fieldConfig.getFieldPath() == null)? "" : fieldConfig.getFieldPath();
 349  0
                     String trimmedFieldKey = null;
 350  0
                     MultiplicityFieldConfiguration newFieldConfig = null;
 351  0
                     trimmedFieldKey = configFieldKey.substring(configParentKey.length());
 352  
 
 353  0
                     QueryPath fieldPath = QueryPath.concat(subMultParentConfig.getFieldKey(),
 354  
                             trimmedFieldKey);;
 355  0
                     newFieldConfig = new MultiplicityFieldConfiguration(
 356  
                             fieldPath.toString(), fieldConfig.getMessageKeyInfo(), fieldConfig.getMetadata(),
 357  
                             fieldConfig.getFieldWidgetInitializer());
 358  0
                     newFieldConfig.setRequired(fieldConfig.isRequired());
 359  0
                     newFieldConfigs.add(newFieldConfig);
 360  
 
 361  0
                 }
 362  0
                 newFieldsMap.put(Integer.valueOf(lineCounter), newFieldConfigs);
 363  0
                 lineCounter++;
 364  0
             }
 365  
         }
 366  0
         newSubMultiplicityConfig.setFields(newFieldsMap);
 367  
 
 368  0
         return newSubMultiplicityConfig;
 369  
     }
 370  
 
 371  
     public String translatePath(String path) {
 372  
         String fieldPath;
 373  0
         if (parentPath != null) {
 374  0
             QueryPath parent = QueryPath.concat(parentPath);
 375  0
             int i = parent.size();
 376  
 
 377  0
             QueryPath subPath = QueryPath.concat(path);
 378  0
             String itemPath =  subPath.subPath(i, subPath.size()).toString();
 379  
 
 380  0
             QueryPath qp = QueryPath.concat(parentPath, itemPath);
 381  0
             fieldPath = qp.toString();
 382  0
         }
 383  
         else {
 384  0
             fieldPath = path;
 385  
         }
 386  
 
 387  0
         fieldPath = fieldPath.replace('*', Character.forDigit(itemCount-1, 10));
 388  0
         return fieldPath;
 389  
     }
 390  
 
 391  
 
 392  
     public void clear(){
 393  0
         itemsPanel.clear();
 394  0
         items.clear();
 395  0
         removed.clear();
 396  0
         itemCount = 0;
 397  0
     }
 398  
 
 399  
     public void redraw(){
 400  0
         for (MultiplicityGroupItem item:items){
 401  0
             item.redraw();
 402  
         }
 403  0
     }
 404  
 
 405  
     public void incrementItemKey(){
 406  0
                 itemCount++;
 407  0
         }
 408  
 
 409  
     /**
 410  
          * This returns the index key for the model for the item currently being added by addItem
 411  
          * This is useful, if you need to refer to the index in the createItem method
 412  
          * @return
 413  
          */
 414  
         public int getAddItemKey(){
 415  0
                 return itemCount-1;
 416  
         }
 417  
 
 418  
 
 419  
     public List<MultiplicityGroupItem> getItems() {
 420  0
         return items;
 421  
     }
 422  
 
 423  
     public List<MultiplicityGroupItem> getRemovedItems() {
 424  0
         return removed;
 425  
     }
 426  
 
 427  
         public int getItemCount() {
 428  0
                 return itemCount;
 429  
         }
 430  
 
 431  
         public void setItemCount(int itemCount) {
 432  0
                 this.itemCount = itemCount;
 433  0
         }
 434  
 
 435  
         public String getParentPath() {
 436  0
                 return parentPath;
 437  
         }
 438  
 
 439  
     /**
 440  
      * Allows the parentpath for this instance to be set, e.g. course/formats/0/activities
 441  
      *
 442  
      * @param parentPath
 443  
      */
 444  
     public void setParentPath(String parentPath) {
 445  0
                 this.parentPath = parentPath;
 446  0
         }
 447  
 
 448  
         public MultiplicityConfiguration getConfig() {
 449  0
                 return config;
 450  
         }
 451  
 
 452  
         public void setConfig(MultiplicityConfiguration config) {
 453  0
                 this.config = config;
 454  0
         }
 455  
 
 456  
     public void resetDirtyFlags() {
 457  0
             isDirty = false;
 458  0
                 for (MultiplicityGroupItem item:items){
 459  0
                         item.resetDirtyFlags();
 460  0
                         Widget itemWidget = item.getItemWidget();
 461  0
                         if (itemWidget instanceof BaseSection){
 462  0
                                 ((BaseSection)itemWidget).resetDirtyFlags();
 463  
                         }
 464  0
                 }
 465  0
     }
 466  
 
 467  
         public boolean isDirty(){
 468  0
         isDirty = false;
 469  0
                 for (MultiplicityGroupItem item:items){
 470  0
                         if (item.isDirty()){
 471  0
                                 isDirty = true;
 472  0
                                 break;
 473  
                         } else {
 474  0
                                 Widget itemWidget = item.getItemWidget();
 475  0
                                 if (itemWidget instanceof BaseSection && ((BaseSection)itemWidget).isDirty()){
 476  0
                                         isDirty = true;
 477  0
                                         break;
 478  
                                 }
 479  0
                         }
 480  
                 }
 481  0
                 return isDirty;
 482  
         }
 483  
 
 484  
         public void setIsDirty(boolean dirty){
 485  0
                 isDirty = dirty;
 486  0
         }
 487  
 
 488  
     public class ConditionChoices extends KSRadioButtonList{
 489  0
         private KSRadioButtonListImpl selectItemWidget = GWT.create(KSRadioButtonListImpl.class);
 490  0
         public ConditionChoices(List<SwapCompositeCondition> conditions){
 491  0
             SimpleListItems choices = new SimpleListItems();
 492  0
             if (conditions != null) {
 493  0
                 for (SwapCompositeCondition condition : conditions) {
 494  0
                     choices.addItem(condition.getConditionId(), condition.getConditionId());
 495  
                 }
 496  
             }
 497  0
             selectItemWidget.setListItems(choices);
 498  0
         }
 499  
 
 500  
         /**
 501  
          * @see org.kuali.student.common.ui.client.widgets.list.KSSelectItemWidgetAbstract#deSelectItem(java.lang.String)
 502  
          */
 503  
         public void deSelectItem(String id) {
 504  0
             selectItemWidget.deSelectItem(id);
 505  0
         }
 506  
 
 507  
         /**
 508  
          * @see org.kuali.student.common.ui.client.widgets.list.KSSelectItemWidgetAbstract#getSelectedItems()
 509  
          */
 510  
         public List<String> getSelectedItems() {
 511  0
             return selectItemWidget.getSelectedItems();
 512  
         }
 513  
 
 514  
         /**
 515  
          * @see org.kuali.student.common.ui.client.widgets.list.KSSelectItemWidgetAbstract#selectItem(java.lang.String)
 516  
          */
 517  
         public void selectItem(String id) {
 518  0
             selectItemWidget.selectItem(id);
 519  0
         }
 520  
 
 521  
         public void setListItems(ListItems listItems) {
 522  0
             selectItemWidget.setListItems(listItems);
 523  0
         }
 524  
 
 525  
         /**
 526  
          * Use to set number of columns to use when displaying list
 527  
          *
 528  
          */
 529  
         public void setColumnSize(int cols){
 530  0
             selectItemWidget.setColumnSize(cols);
 531  0
         }
 532  
 
 533  0
         public void setMultipleSelect(boolean isMultipleSelect) {}
 534  
 
 535  
         /**
 536  
          * This overridden method is not used
 537  
          *
 538  
          * @see org.kuali.student.common.ui.client.widgets.list.KSSelectItemWidgetAbstract#onLoad()
 539  
          */
 540  
         @Override
 541  0
         public void onLoad() {}
 542  
 
 543  
         public HandlerRegistration addSelectionChangeHandler(SelectionChangeHandler handler) {
 544  0
             return selectItemWidget.addSelectionChangeHandler(handler);
 545  
         }
 546  
 
 547  
         public ListItems getListItems() {
 548  0
             return selectItemWidget.getListItems();
 549  
         }
 550  
 
 551  
         public String getName() {
 552  0
             return selectItemWidget.getName();
 553  
         }
 554  
 
 555  
         public void setName(String name) {
 556  0
             selectItemWidget.setName(name);
 557  0
         }
 558  
 
 559  
         @Override
 560  
         public void setEnabled(boolean b) {
 561  0
             selectItemWidget.setEnabled(b);
 562  0
         }
 563  
 
 564  
         @Override
 565  
         public boolean isEnabled() {
 566  0
             return selectItemWidget.isEnabled();
 567  
         }
 568  
 
 569  
         @Override
 570  
         public boolean isMultipleSelect() {
 571  0
             return selectItemWidget.isMultipleSelect();
 572  
         }
 573  
 
 574  
         @Override
 575  
         public void redraw() {
 576  0
             selectItemWidget.redraw();
 577  0
         }
 578  
 
 579  
         @Override
 580  
         public void clear() {
 581  0
             selectItemWidget.clear();
 582  0
         }
 583  
 
 584  
         @Override
 585  
         public HandlerRegistration addBlurHandler(BlurHandler handler) {
 586  0
             return selectItemWidget.addBlurHandler(handler);
 587  
         }
 588  
 
 589  
         @Override
 590  
         public HandlerRegistration addFocusHandler(FocusHandler handler) {
 591  0
             return selectItemWidget.addFocusHandler(handler);
 592  
         }
 593  
 
 594  
         public void addWidgetReadyCallback(Callback<Widget> callback) {
 595  0
             selectItemWidget.addWidgetReadyCallback(callback);
 596  0
         }
 597  
 
 598  
         public boolean isInitialized() {
 599  0
             return selectItemWidget.isInitialized();
 600  
         }
 601  
 
 602  
         public void setInitialized(boolean initialized) {
 603  0
             selectItemWidget.setInitialized(initialized);
 604  0
         }
 605  
 
 606  
         /**
 607  
          * By default if the list items used by the checkbox has multiple attributes, the checkbox
 608  
          * generated will display all attributes as columns. Set this property to true if this
 609  
          * behavior is not desired.
 610  
          *
 611  
          * @param ignoreMultiple
 612  
          */
 613  
         public void setIgnoreMultipleAttributes(boolean ignoreMultiple){
 614  0
             selectItemWidget.setIgnoreMultipleAttributes(ignoreMultiple);
 615  0
         }
 616  
     }
 617  
 
 618  0
     public class SwappableFieldsHelper {
 619  
 
 620  
         private GroupSection parentSection;
 621  0
         private Map<SwapCompositeCondition, List<SwapCompositeConditionFieldConfig>> swappableFieldsDefinition =
 622  
             new HashMap<SwapCompositeCondition, List<SwapCompositeConditionFieldConfig>>();
 623  
         private Map<String, String> helperFieldKeys;
 624  
         private ConditionChoices conditionChoices;
 625  
         private SwapSection swapSection;
 626  
         public void updateFieldDisplay() {
 627  0
             Set<Entry<SwapCompositeCondition, List<SwapCompositeConditionFieldConfig>>> entries =
 628  
                 (swappableFieldsDefinition == null)? null : swappableFieldsDefinition.entrySet();
 629  0
             if (parentSection == null) {
 630  0
                 throw new RuntimeException("parentSection cannot be null");
 631  
             }
 632  0
             if (entries != null) {
 633  0
                 for (Entry<SwapCompositeCondition, List<SwapCompositeConditionFieldConfig>> entry : entries) {
 634  0
                     SwapCompositeCondition condition = entry.getKey();
 635  0
                     if (condition.evaluate(parentSection, helperFieldKeys)) {
 636  
                         // clear values in the widgets
 637  0
                         List<Section> deletedSections = swapSection.getDeletedSections();
 638  0
                         List<FieldDescriptor> fields = null;
 639  0
                         if (deletedSections != null) {
 640  0
                             for (Section deletedSection : deletedSections) {
 641  0
                                 fields = (fields == null)? new ArrayList() : fields;
 642  0
                                 fields.addAll(deletedSection.getFields());
 643  
                             }
 644  
                         }
 645  0
                         if (fields != null) {
 646  0
                             for (FieldDescriptor field : fields) {
 647  0
                                 Widget fieldWidget = field.getFieldWidget();
 648  0
                                 DataModel dataModel = new DataModel();
 649  0
                                 dataModel.setRoot(new Data());
 650  0
                                 ((ModelWidgetBinding)field.getModelWidgetBinding())
 651  
                                 .setWidgetValue(fieldWidget,
 652  
                                         dataModel, field.getFieldKey());
 653  0
                             }
 654  
                         }
 655  
                         // trigger SectionChangeEvent to notify the selection widget
 656  
                         // that the selected condition has changed.
 657  0
                         SelectionChangeEvent selectionChangeEvent =
 658  
                             new SelectionChangeEvent(conditionChoices);
 659  0
                         selectionChangeEvent.setUserInitiated(true);
 660  0
                         conditionChoices.selectItem(condition.getConditionId());
 661  0
                         conditionChoices.fireEvent(selectionChangeEvent);
 662  
                     }
 663  0
                 }
 664  
             }
 665  0
         }
 666  
         public GroupSection getParentSection() {
 667  0
             return parentSection;
 668  
         }
 669  
         public void setParentSection(GroupSection parentSection) {
 670  0
             this.parentSection = parentSection;
 671  0
         }
 672  
         public Map<SwapCompositeCondition, List<SwapCompositeConditionFieldConfig>> getSwappableFieldsDefinition() {
 673  0
             return swappableFieldsDefinition;
 674  
         }
 675  
         public void setSwappableFieldsDefinition(Map<SwapCompositeCondition, List<SwapCompositeConditionFieldConfig>> swappableFieldsDefinition) {
 676  0
             this.swappableFieldsDefinition = swappableFieldsDefinition;
 677  0
         }
 678  
         public Map<String, String> getHelperFieldKeys() {
 679  0
             return helperFieldKeys;
 680  
         }
 681  
         public void setHelperFieldKeys(Map<String, String> helperFieldKeys) {
 682  0
             this.helperFieldKeys = helperFieldKeys;
 683  0
         }
 684  
         public ConditionChoices getConditionChoices() {
 685  0
             return conditionChoices;
 686  
         }
 687  
         public void setConditionChoices(ConditionChoices conditionChoices) {
 688  0
             this.conditionChoices = conditionChoices;
 689  0
         }
 690  
         public SwapSection getSwapSection() {
 691  0
             return swapSection;
 692  
         }
 693  
         public void setSwapSection(SwapSection swapSection) {
 694  0
             this.swapSection = swapSection;
 695  0
         }
 696  
     }
 697  
 
 698  
 }