Coverage Report - org.kuali.student.lum.common.client.lo.LOCategoryBuilder
 
Classes in this File Line Coverage Branch Coverage Complexity
LOCategoryBuilder
0%
0/104
0%
0/34
1.569
LOCategoryBuilder$1
0%
0/3
N/A
1.569
LOCategoryBuilder$2
0%
0/21
N/A
1.569
LOCategoryBuilder$2$1
0%
0/6
0%
0/2
1.569
LOCategoryBuilder$2$2
0%
0/3
N/A
1.569
LOCategoryBuilder$3
0%
0/6
N/A
1.569
LOCategoryBuilder$4
0%
0/13
0%
0/2
1.569
LOCategoryBuilder$4$1
0%
0/11
0%
0/3
1.569
LOCategoryBuilder$4$1$1
0%
0/14
0%
0/4
1.569
LOCategoryBuilder$5
0%
0/8
0%
0/2
1.569
LOCategoryBuilder$6
0%
0/1
N/A
1.569
LOCategoryBuilder$CategoryDataParser
0%
0/13
0%
0/4
1.569
LOCategoryBuilder$CreateLoCancelGroup
0%
0/16
N/A
1.569
LOCategoryBuilder$CreateLoCancelGroup$1
0%
0/3
N/A
1.569
LOCategoryBuilder$CreateLoCancelGroup$2
0%
0/3
N/A
1.569
LOCategoryBuilder$LOCategoryListNew
0%
0/49
0%
0/10
1.569
LOCategoryBuilder$LOCategoryListNew$1
0%
0/6
N/A
1.569
LOCategoryBuilder$LOCategoryListNew$2
0%
0/7
0%
0/2
1.569
LOCategoryBuilder$LOCategoryPicker
0%
0/33
N/A
1.569
LOCategoryBuilder$LOCategoryTypeInfoList
0%
0/16
0%
0/6
1.569
LOCategoryBuilder$LoCancelEnum
0%
0/9
0%
0/3
1.569
 
 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  
  *
 7  
  * http://www.osedu.org/licenses/ECL-2.0
 8  
  *
 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  
  */
 15  
 
 16  
 package org.kuali.student.lum.common.client.lo;
 17  
 
 18  
 import java.util.ArrayList;
 19  
 import java.util.Arrays;
 20  
 import java.util.HashMap;
 21  
 import java.util.List;
 22  
 import java.util.Map;
 23  
 
 24  
 import org.kuali.student.common.assembly.data.Data;
 25  
 import org.kuali.student.common.assembly.data.Data.DataValue;
 26  
 import org.kuali.student.common.ui.client.application.Application;
 27  
 import org.kuali.student.common.ui.client.application.KSAsyncCallback;
 28  
 import org.kuali.student.common.ui.client.configurable.mvc.SectionTitle;
 29  
 import org.kuali.student.common.ui.client.mvc.Callback;
 30  
 import org.kuali.student.common.ui.client.service.DataSaveResult;
 31  
 import org.kuali.student.common.ui.client.util.DebugIdUtils;
 32  
 import org.kuali.student.common.ui.client.util.UtilConstants;
 33  
 import org.kuali.student.common.ui.client.widgets.DataHelper;
 34  
 import org.kuali.student.common.ui.client.widgets.KSButton;
 35  
 import org.kuali.student.common.ui.client.widgets.KSDropDown;
 36  
 import org.kuali.student.common.ui.client.widgets.KSItemLabel;
 37  
 import org.kuali.student.common.ui.client.widgets.KSLabel;
 38  
 import org.kuali.student.common.ui.client.widgets.KSLightBox;
 39  
 import org.kuali.student.common.ui.client.widgets.KSTextBox;
 40  
 import org.kuali.student.common.ui.client.widgets.KSButtonAbstract.ButtonStyle;
 41  
 import org.kuali.student.common.ui.client.widgets.buttongroups.ButtonGroup;
 42  
 import org.kuali.student.common.ui.client.widgets.buttongroups.ButtonEnumerations.ButtonEnum;
 43  
 import org.kuali.student.common.ui.client.widgets.buttonlayout.ButtonRow;
 44  
 import org.kuali.student.common.ui.client.widgets.field.layout.element.AbbrButton;
 45  
 import org.kuali.student.common.ui.client.widgets.field.layout.element.LabelPanel;
 46  
 import org.kuali.student.common.ui.client.widgets.field.layout.element.AbbrButton.AbbrButtonType;
 47  
 import org.kuali.student.common.ui.client.widgets.field.layout.layouts.FieldLayoutComponent;
 48  
 import org.kuali.student.common.ui.client.widgets.focus.FocusGroup;
 49  
 import org.kuali.student.common.ui.client.widgets.list.ListItems;
 50  
 import org.kuali.student.common.ui.client.widgets.list.SelectionChangeHandler;
 51  
 import org.kuali.student.common.ui.client.widgets.notification.KSNotification;
 52  
 import org.kuali.student.common.ui.client.widgets.notification.KSNotifier;
 53  
 import org.kuali.student.common.ui.client.widgets.progress.BlockingTask;
 54  
 import org.kuali.student.common.ui.client.widgets.progress.KSBlockingProgressIndicator;
 55  
 import org.kuali.student.common.ui.client.widgets.suggestbox.KSSuggestBox;
 56  
 import org.kuali.student.common.ui.client.widgets.suggestbox.SearchSuggestOracle;
 57  
 import org.kuali.student.common.ui.client.widgets.suggestbox.SuggestPicker;
 58  
 import org.kuali.student.lum.common.client.lo.rpc.LoCategoryRpcService;
 59  
 import org.kuali.student.lum.common.client.lo.rpc.LoCategoryRpcServiceAsync;
 60  
 import org.kuali.student.lum.common.client.lu.LUUIConstants;
 61  
 import org.kuali.student.lum.lo.dto.LoCategoryInfo;
 62  
 import org.kuali.student.lum.lo.dto.LoCategoryTypeInfo;
 63  
 
 64  
 import com.google.gwt.core.client.GWT;
 65  
 import com.google.gwt.event.dom.client.BlurHandler;
 66  
 import com.google.gwt.event.dom.client.ClickEvent;
 67  
 import com.google.gwt.event.dom.client.ClickHandler;
 68  
 import com.google.gwt.event.dom.client.FocusHandler;
 69  
 import com.google.gwt.event.logical.shared.CloseEvent;
 70  
 import com.google.gwt.event.logical.shared.CloseHandler;
 71  
 import com.google.gwt.event.logical.shared.ValueChangeEvent;
 72  
 import com.google.gwt.event.logical.shared.ValueChangeHandler;
 73  
 import com.google.gwt.event.shared.GwtEvent;
 74  
 import com.google.gwt.event.shared.HandlerRegistration;
 75  
 import com.google.gwt.user.client.Window;
 76  
 import com.google.gwt.user.client.ui.Anchor;
 77  
 import com.google.gwt.user.client.ui.Composite;
 78  
 import com.google.gwt.user.client.ui.FlexTable;
 79  
 import com.google.gwt.user.client.ui.FlowPanel;
 80  
 import com.google.gwt.user.client.ui.HTMLPanel;
 81  
 import com.google.gwt.user.client.ui.HasValue;
 82  
 import com.google.gwt.user.client.ui.HorizontalPanel;
 83  
 import com.google.gwt.user.client.ui.VerticalPanel;
 84  
 
 85  
 /**
 86  
  * This class allows a user to select and remove LO categories within the context of
 87  
  * LO creation. New categories can be added 'on the fly' and are persisted in the database
 88  
  * independently of LO creation
 89  
  *
 90  
  * @author Kuali Rice Team (kuali-rice@googlegroups.com)
 91  
  */
 92  0
 public class LOCategoryBuilder extends Composite implements HasValue<List<LoCategoryInfo>> {        //KSLAB-2091:  One instance for each LO entry box
 93  
 
 94  
     private String type;
 95  
     private String state;
 96  
     private String repoKey;
 97  
     private String messageGroup;
 98  
 
 99  
     private LoCategoryRpcServiceAsync loCatRpcServiceAsync;
 100  
     private LOCategoryPicker picker;
 101  0
     private AbbrButton help = new AbbrButton(AbbrButtonType.HELP);
 102  
 
 103  
     LOCategoryListNew categoryList;
 104  
     Map<String, LoCategoryTypeInfo> categoryTypeMap;
 105  
 
 106  0
     VerticalPanel root = new VerticalPanel();
 107  
 
 108  0
     private KSButton addButton = new KSButton("Add", ButtonStyle.SECONDARY);
 109  
 
 110  
     private KSLightBox createCategoryWindow;
 111  
     Anchor browseCategoryLink;
 112  0
     private final BlockingTask saving = new BlockingTask("Saving");
 113  
 
 114  
     public LOCategoryBuilder(String messageGroup, String type, String state, String loRepoKey) {
 115  0
         super();
 116  
 
 117  0
         this.type = type;
 118  0
         this.state = state;
 119  0
         this.repoKey = loRepoKey;
 120  0
         this.messageGroup = messageGroup;
 121  
 
 122  0
         loCatRpcServiceAsync = GWT.create(LoCategoryRpcService.class);
 123  0
         picker = new LOCategoryPicker();
 124  0
         categoryList = new LOCategoryListNew();
 125  
 
 126  0
         initWidget(root);
 127  
 
 128  0
         final FlowPanel selectedPanel = new FlowPanel();
 129  0
         selectedPanel.setStyleName("KS-LOSelectedCategories");
 130  0
         addButton.addClickHandler(new ClickHandler() {
 131  
             @Override
 132  
             public void onClick(ClickEvent event) {
 133  0
                 addEnteredCategory();
 134  0
             }
 135  
         });
 136  0
         browseCategoryLink = new Anchor(getLabelText(LUUIConstants.LO_CATEGORY_BROWSE_LABEL_KEY));
 137  0
         browseCategoryLink.addClickHandler(new ClickHandler() {
 138  
             @Override
 139  
             public void onClick(ClickEvent event) {
 140  
                // Filter out any categories already in the picker
 141  0
                 List<LoCategoryInfo> categoriesInPicker = categoryList.getValue();
 142  
                 /*Category Management has a CategoryManagementTable -> has a DefaultTableModel -> has rowList 
 143  
                  *                                                                                                                                                                                    of category rows that go in mainPanel FlowPanel
 144  
                  *                                                                                                                                                                                                                                  in 'Select Categories' pop KSLightBox*/
 145  0
                 final CategoryManagement categoryManagement = new CategoryManagement(true, true, categoriesInPicker);        
 146  0
                 categoryManagement.setDeleteButtonEnabled(false);
 147  0
                 categoryManagement.setInsertButtonEnabled(false);
 148  0
                 categoryManagement.setUpdateButtonEnabled(false);
 149  
 
 150  0
                 final KSLightBox pop = new KSLightBox();
 151  0
                 pop.setMaxWidth(600);
 152  0
                 pop.setMaxHeight(750);
 153  0
                 KSButton addButton = new KSButton("Add");
 154  0
                 KSButton cancelButton = new KSButton("Cancel", ButtonStyle.ANCHOR_LARGE_CENTERED);
 155  
 
 156  0
                 pop.addButton(addButton);
 157  0
                 pop.addButton(cancelButton);
 158  
 
 159  0
                 pop.setNonCaptionHeader(SectionTitle.generateH2Title(getLabelText(LUUIConstants.LO_CATEGORY_BROWSE_POPUP_LABEL_KEY)));
 160  0
                 FlowPanel mainPanel = new FlowPanel();
 161  0
                 mainPanel.add(categoryManagement);
 162  
 
 163  0
                 addButton.addClickHandler(new ClickHandler() {
 164  
                     @Override
 165  
                     public void onClick(ClickEvent event) {
 166  0
                         List<LoCategoryInfo> list = categoryManagement.getSelectedCategoryList();
 167  0
                         for (LoCategoryInfo info : list) {
 168  0
                             addCategory(info);        //I think this adds categories selected from choices in 'Select Categories' pop KSLightBox to an LO
 169  
                         }
 170  0
                         pop.hide();
 171  0
                     }
 172  
                 });
 173  
 
 174  0
                 cancelButton.addClickHandler(new ClickHandler() {
 175  
                     @Override
 176  
                     public void onClick(ClickEvent event) {
 177  0
                         pop.hide();
 178  0
                     }
 179  
                 });
 180  
 
 181  
 
 182  0
                 pop.setWidget(mainPanel);
 183  0
                 pop.show();
 184  
 
 185  
 
 186  0
             }
 187  
         });
 188  
 
 189  0
         VerticalPanel main = new VerticalPanel();
 190  0
         HorizontalPanel suggestPanel = new HorizontalPanel();
 191  0
         suggestPanel.add(picker);
 192  0
         suggestPanel.add(addButton);
 193  
 
 194  0
         VerticalPanel suggestAndBrowsePanel = new VerticalPanel();
 195  0
         suggestAndBrowsePanel.add(suggestPanel);
 196  0
         suggestAndBrowsePanel.add(browseCategoryLink);
 197  
 
 198  
 
 199  0
         selectedPanel.add(categoryList);
 200  
 
 201  0
         String fieldHTMLId = HTMLPanel.createUniqueId();
 202  0
         String title = getLabelText(LUUIConstants.LO_CATEGORY_KEY);
 203  0
         String helpText = getLabelText(LUUIConstants.LO_CATEGORY_KEY + FieldLayoutComponent.HELP_MESSAGE_KEY);
 204  0
         LabelPanel fieldTitle = new LabelPanel(title, fieldHTMLId);
 205  
 
 206  0
         if (helpText != null) {
 207  0
             setHelp(helpText);
 208  
         } else {
 209  0
             help.setVisible(false);
 210  
         }
 211  
 
 212  0
         fieldTitle.add(help);
 213  0
         main.add(fieldTitle);
 214  0
         main.add(suggestAndBrowsePanel);
 215  0
         main.add(selectedPanel);
 216  0
         root.add(main);
 217  
 
 218  0
         main.addStyleName("KS-LOCategoryPicker");
 219  0
         addButton.addStyleName("KS-LOCategoryPicker-Button");
 220  
 
 221  0
     }
 222  
 
 223  
     public void setHelp(final String html) {
 224  0
         if (html != null && !html.trim().equals("")) {
 225  0
             help.setVisible(true);
 226  0
             help.setHoverHTML(html);
 227  
             /*help.addClickHandler(new ClickHandler(){
 228  
 
 229  
                 @Override
 230  
                 public void onClick(ClickEvent event) {
 231  
                     //TODO show actual help window
 232  
                     Window.alert(html);
 233  
 
 234  
                 }
 235  
             });*/
 236  
         } else {
 237  0
             help.setVisible(false);
 238  
         }
 239  0
     }
 240  
 
 241  
     private void addEnteredCategory() {
 242  
 
 243  0
         if (categoryList == null)
 244  0
             categoryList = new LOCategoryListNew();
 245  
 
 246  0
         String selectedId = picker.getSelectedId();
 247  0
         if (selectedId.trim().equals("") || selectedId.equals(UtilConstants.IMPOSSIBLE_CHARACTERS)) {
 248  0
             showNewCategoryWindow();
 249  
         } else {
 250  0
             loCatRpcServiceAsync.getData(picker.getSelectedId(), new KSAsyncCallback<Data>() {
 251  
 
 252  
                 @Override
 253  
                 public void handleFailure(Throwable caught) {
 254  0
                     Window.alert("getLoCategory failed " + caught.getMessage());
 255  0
                 }
 256  
 
 257  
                 @Override
 258  
                 public void onSuccess(Data result) {
 259  0
                     final LoCategoryInfo newCategory = CategoryDataUtil.toLoCategoryInfo(result);
 260  0
                     addCategory(newCategory);
 261  
 
 262  0
                 }
 263  
             });
 264  
         }
 265  0
     }
 266  
 
 267  
     private void showNewCategoryWindow() {
 268  
 
 269  0
         final VerticalPanel main = new VerticalPanel();
 270  0
         final KSDropDown typesDropDown = new KSDropDown();
 271  0
         createCategoryWindow = new KSLightBox();
 272  
 
 273  0
         FlexTable layoutTable = new FlexTable();
 274  0
         final KSTextBox nameTextBox = new KSTextBox();
 275  0
         nameTextBox.setText(picker.getText());//+ enteredWord);
 276  
 
 277  0
         layoutTable.setWidget(0, 0, new KSLabel("Category"));
 278  0
         layoutTable.setWidget(0, 1, new KSLabel("Type"));
 279  0
         layoutTable.setWidget(1, 0, nameTextBox);
 280  0
         layoutTable.setWidget(1, 1, typesDropDown);
 281  
 
 282  0
         SectionTitle sectionTitle = SectionTitle.generateH2Title("Create New Category");
 283  
         //KSThinTitleBar titleBar = new KSThinTitleBar("Create New Category");
 284  0
         createCategoryWindow.setNonCaptionHeader(sectionTitle);
 285  0
         main.add(layoutTable);
 286  
 
 287  0
         loCatRpcServiceAsync.getLoCategoryTypes(new KSAsyncCallback<List<LoCategoryTypeInfo>>() {
 288  
 
 289  
             @Override
 290  
             public void handleFailure(Throwable caught) {
 291  0
                 Window.alert("getLoCategoryTypes failed " + caught.getMessage());
 292  0
             }
 293  
 
 294  
             @Override
 295  
             public void onSuccess(List<LoCategoryTypeInfo> result) {
 296  0
                 final LOCategoryTypeInfoList list = new LOCategoryTypeInfoList(result);
 297  0
                 typesDropDown.setListItems(list);
 298  0
                 if (categoryTypeMap == null) {
 299  0
                     loadCategoryTypes(result);
 300  
                 }
 301  
 
 302  0
                 CreateLoCancelGroup buttonPanel = new CreateLoCancelGroup(new Callback<LoCancelEnum>() {
 303  
 
 304  
                     @Override
 305  
                     public void exec(LoCancelEnum result) {
 306  0
                         switch (result) {
 307  
                             case CREATE:
 308  
 
 309  0
                                 LoCategoryInfoHelper catHelper = new LoCategoryInfoHelper(new Data());
 310  0
                                 catHelper.setName(nameTextBox.getText());
 311  0
                                 catHelper.setState("active");
 312  0
                                 catHelper.setLoRepository(repoKey);
 313  0
                                 catHelper.setType(typesDropDown.getSelectedItem());
 314  
 
 315  0
                                 loCatRpcServiceAsync.saveData(catHelper.getData(), new KSAsyncCallback<DataSaveResult>() {
 316  
                                     @Override
 317  
                                     public void handleFailure(Throwable caught) {
 318  0
                                         Window.alert("Create LO Category failed: " + caught.getMessage());
 319  0
                                     }
 320  
                                     
 321  
                                     @Override
 322  
                                     public void handleVersionMismatch(Throwable caught) {
 323  0
                                         super.handleVersionMismatch(caught);
 324  0
                                         KSBlockingProgressIndicator.removeTask(saving);
 325  0
                                     }
 326  
 
 327  
                                     @Override
 328  
                                     public void onSuccess(DataSaveResult result) {
 329  0
                                         KSBlockingProgressIndicator.removeTask(saving);
 330  
 
 331  0
                                         if (result.getValidationResults() != null && !result.getValidationResults().isEmpty()) {
 332  0
                                             Window.alert("Create LO Category failed: " + result.getValidationResults().get(0).getMessage());
 333  
                                         } else {
 334  
 
 335  0
                                             final LoCategoryInfo newCategory = CategoryDataUtil.toLoCategoryInfo(result.getValue());
 336  0
                                             addCategory(newCategory);
 337  0
                                             createCategoryWindow.hide();
 338  0
                                             KSNotifier.add(new KSNotification("Create LO Category Successful", false, 3000));
 339  
                                         }
 340  0
                                     }
 341  
                                 });
 342  0
                                 break;
 343  
                             case CANCEL:
 344  0
                                 createCategoryWindow.hide();
 345  
                                 break;
 346  
                         }
 347  0
                     }
 348  
                 });
 349  
 
 350  0
                 main.add(buttonPanel);
 351  0
                 main.setPixelSize(300, 300);
 352  0
                 createCategoryWindow.setWidget(main);
 353  0
                 createCategoryWindow.show();
 354  0
             }
 355  
 
 356  
 
 357  
         });
 358  0
     }
 359  
 
 360  
     private void loadCategoryTypes(List<LoCategoryTypeInfo> categoryTypes) {
 361  0
         if (categoryTypeMap == null) {
 362  0
             categoryTypeMap = new HashMap<String, LoCategoryTypeInfo>();
 363  
         }
 364  0
         if (categoryTypes != null) {
 365  0
             for (LoCategoryTypeInfo i : categoryTypes) {
 366  0
                 categoryTypeMap.put(i.getId(), i);
 367  
             }
 368  
         }
 369  0
     }
 370  
 
 371  
     /**
 372  
      * This method will check if an LO category is already in the picker box
 373  
      * and prevent it from being added to the picker.
 374  
      * <p>
 375  
      * 
 376  
      * @param categoryToCheck category to check if it is already in the picker box
 377  
      * @return true if the category is already in the picker box
 378  
      */
 379  
     private boolean isCategoryAlreadyAddedToPicker(LoCategoryInfo categoryToCheck){
 380  
         // TODO: do we need null checks?
 381  0
         List<LoCategoryInfo> categoriesInPicker = categoryList.getValue();
 382  0
         if (categoriesInPicker != null && categoryToCheck != null){
 383  0
             for (LoCategoryInfo pickerCategory : categoriesInPicker) {
 384  0
                 boolean namesMatch = pickerCategory.getName().equalsIgnoreCase(categoryToCheck.getName());
 385  0
                 boolean typesMatch = pickerCategory.getType().equalsIgnoreCase(categoryToCheck.getType());
 386  0
                 if (namesMatch && typesMatch){
 387  0
                     return true;
 388  
                 }
 389  0
             }
 390  
         }
 391  0
         return false;
 392  
     }
 393  
     private void addCategory(final LoCategoryInfo category) {
 394  0
         if (categoryTypeMap == null) {
 395  0
             categoryTypeMap = new HashMap<String, LoCategoryTypeInfo>();
 396  
         }
 397  
 
 398  0
         if (categoryTypeMap.containsKey(category.getType())) {
 399  
             // check if category is already added to picker.  only add it once.
 400  0
             if (!isCategoryAlreadyAddedToPicker(category)){
 401  0
                 categoryList.addItem(category);
 402  
             }
 403  0
             picker.reset();
 404  
         } else {
 405  0
             loCatRpcServiceAsync.getLoCategoryType(category.getType(), new KSAsyncCallback<LoCategoryTypeInfo>() {
 406  
 
 407  
                 @Override
 408  
                 public void handleFailure(Throwable caught) {
 409  0
                     Window.alert("getLoCategoryType failed " + caught.getMessage());
 410  0
                 }
 411  
 
 412  
                 @Override
 413  
                 public void onSuccess(LoCategoryTypeInfo result) {
 414  0
                     categoryTypeMap.put(result.getId(), result);
 415  
                     // check if category is already added to picker.  only add it once.
 416  0
                     if (!isCategoryAlreadyAddedToPicker(category)){
 417  0
                          categoryList.addItem(category);
 418  
                     } 
 419  0
                     picker.reset();
 420  
 
 421  0
                 }
 422  
 
 423  
             });
 424  
         }
 425  
 
 426  0
     }
 427  
 
 428  
     private String getLabelText(String labelKey) {
 429  0
         return Application.getApplicationContext().getUILabel(messageGroup, type, state, labelKey);
 430  
     }
 431  
 
 432  
     @Override
 433  
     public void setValue(List<LoCategoryInfo> categories) {
 434  0
         categoryList.setValue(categories);
 435  
 
 436  0
     }
 437  
 
 438  
     @Override
 439  
     public void setValue(List<LoCategoryInfo> value, boolean fireEvents) {
 440  0
         setValue(value);
 441  0
     }
 442  
 
 443  
     /**
 444  
      * @see com.google.gwt.user.client.ui.HasValue#getValue()
 445  
      */
 446  
     @Override
 447  
     public List<LoCategoryInfo> getValue() {
 448  0
         return categoryList.getValue();
 449  
     }
 450  
 
 451  
     /**
 452  
      * @see com.google.gwt.event.logical.shared.HasValueChangeHandlers#addValueChangeHandler(com.google.gwt.event.logical.shared.ValueChangeHandler)
 453  
      */
 454  
     @Override
 455  
     public HandlerRegistration addValueChangeHandler(ValueChangeHandler<List<LoCategoryInfo>> handler) {
 456  0
         return categoryList.addValueChangeHandler(handler);
 457  
     }
 458  
 
 459  
     /**
 460  
      * This class provides a suggest box for existing LO categories backed by a search on category name
 461  
      *
 462  
      * @author Kuali Rice Team (kuali-rice@googlegroups.com)
 463  
      */
 464  0
     private class LOCategoryPicker extends Composite implements SuggestPicker {
 465  
 
 466  
         //FIXME:   [KSCOR-225] Class needs to be rewritten to use KSPicker instead of SuggestPicker and use lookup config through metadata
 467  
 
 468  0
         final SearchSuggestOracle loSearchOracle = new SearchSuggestOracle(
 469  
                 "lo.search.loCategories",
 470  
                 "lo.queryParam.loOptionalCategoryName",
 471  
                 "lo.queryParam.loCategoryId",
 472  
                 "lo.resultColumn.categoryId",
 473  
                 "lo.resultColumn.categoryNameAndType");
 474  
 
 475  0
         final KSSuggestBox suggestBox = new KSSuggestBox(loSearchOracle);
 476  
 
 477  0
         private final FocusGroup focus = new FocusGroup(this);
 478  
 
 479  0
         private VerticalPanel main = new VerticalPanel();
 480  
 
 481  0
         protected LOCategoryPicker() {
 482  0
             super();
 483  0
             init();
 484  0
         }
 485  
 
 486  
         public String getSelectedId() {
 487  0
             return suggestBox.getSelectedId();
 488  
         }
 489  
 
 490  
         private void init() {
 491  0
             focus.addWidget(suggestBox);
 492  0
             loSearchOracle.setTextWidget(suggestBox.getTextBox());
 493  0
             main.add(suggestBox);
 494  0
             initWidget(main);
 495  0
         }
 496  
 
 497  
         @Override
 498  
         public String getValue() {
 499  0
             return suggestBox.getSelectedId();
 500  
         }
 501  
 
 502  
         @Override
 503  
         public void setValue(String value) {
 504  0
             setValue(value, true);
 505  0
         }
 506  
 
 507  
         @Override
 508  
         public void setValue(String value, boolean fireEvents) {
 509  0
             suggestBox.reset();
 510  0
             suggestBox.setValue(value, fireEvents);
 511  0
         }
 512  
 
 513  
 
 514  
         @Override
 515  
         public HandlerRegistration addValueChangeHandler(ValueChangeHandler<String> handler) {
 516  0
             return suggestBox.addValueChangeHandler(handler);
 517  
         }
 518  
 
 519  
         @Override
 520  
         public void fireEvent(GwtEvent<?> event) {
 521  0
             super.fireEvent(event);
 522  0
         }
 523  
 
 524  
         public void reset() {
 525  0
             suggestBox.reset();
 526  0
         }
 527  
 
 528  
         @Override
 529  
         public HandlerRegistration addFocusHandler(FocusHandler handler) {
 530  0
             return focus.addFocusHandler(handler);
 531  
         }
 532  
 
 533  
         @Override
 534  
         public HandlerRegistration addBlurHandler(BlurHandler handler) {
 535  0
             return focus.addBlurHandler(handler);
 536  
         }
 537  
 
 538  
         public String getText() {
 539  0
             return suggestBox.getText();
 540  
         }
 541  
 
 542  
         @Override
 543  
         public HandlerRegistration addSelectionChangeHandler(SelectionChangeHandler handler) {
 544  0
             return suggestBox.addSelectionChangeHandler(handler);
 545  
         }
 546  
 
 547  
         @Override
 548  
         protected void onEnsureDebugId(String baseID) {
 549  0
             super.onEnsureDebugId(baseID);
 550  0
             suggestBox.getTextBox().ensureDebugId(baseID);
 551  0
         }
 552  
         
 553  
     }
 554  
 
 555  
     private class LOCategoryTypeInfoList implements ListItems {
 556  0
         Map<String, LoCategoryTypeInfo> loTypeMap = new HashMap<String, LoCategoryTypeInfo>();
 557  
 
 558  0
         public LOCategoryTypeInfoList(List<LoCategoryTypeInfo> loTypes) {
 559  0
             for (LoCategoryTypeInfo type : loTypes) {
 560  0
                 loTypeMap.put(type.getId(), type);
 561  
             }
 562  0
         }
 563  
 
 564  
         public List<String> getAttrKeys() {
 565  0
             return Arrays.asList("Name");
 566  
         }
 567  
 
 568  
         public String getItemAttribute(String id, String attrkey) {
 569  0
             LoCategoryTypeInfo lo = loTypeMap.get(id);
 570  
 
 571  0
             if (attrkey.equals("Name")) {
 572  0
                 return lo.getName();
 573  
             }
 574  
 
 575  0
             return null;
 576  
         }
 577  
 
 578  
         public int getItemCount() {
 579  0
             return loTypeMap.size();
 580  
         }
 581  
 
 582  
         public List<String> getItemIds() {
 583  0
             List<String> keys = new ArrayList<String>();
 584  
 
 585  0
             for (String s : loTypeMap.keySet()) {
 586  0
                 keys.add(s);
 587  
             }
 588  
 
 589  0
             return keys;
 590  
         }
 591  
 
 592  
         public String getItemText(String id) {
 593  0
             return ((LoCategoryTypeInfo) loTypeMap.get(id)).getName();
 594  
         }
 595  
     }
 596  
 
 597  0
     public class LOCategoryListNew extends Composite implements HasValue<List<LoCategoryInfo>> {
 598  
         private static final String CATEGORY_TYPE_SEPARATOR = " - ";
 599  
         private VerticalPanel listPanel;
 600  0
         private VerticalPanel main = new VerticalPanel();
 601  0
         protected List<LoCategoryInfo> categories = new ArrayList<LoCategoryInfo>();
 602  
 
 603  0
         final CloseHandler<KSItemLabel> deleteHandler = new CloseHandler<KSItemLabel>() {
 604  
             @Override
 605  
             public void onClose(CloseEvent<KSItemLabel> event) {
 606  0
                 KSItemLabel itemLabel = event.getTarget();
 607  0
                 String itemText = itemLabel.getDeletedKey();
 608  0
                 categoryList.removeItem(itemText);
 609  0
                 categoryList.redraw();
 610  0
             }
 611  
         };
 612  
 
 613  0
         public LOCategoryListNew() {
 614  0
             listPanel = new VerticalPanel();
 615  0
             main.add(listPanel);
 616  0
             super.initWidget(main);
 617  0
         }
 618  
 
 619  
         public HandlerRegistration addValueChangeHandler(ValueChangeHandler<List<LoCategoryInfo>> handler) {
 620  0
             return addHandler(handler, ValueChangeEvent.getType());
 621  
         }
 622  
 
 623  
         private void fireChangeEvent() {
 624  0
             ValueChangeEvent.fire(this, categories);
 625  0
         }
 626  
 
 627  
         public void redraw() {
 628  
 
 629  0
             if (null == categoryTypeMap || categoryTypeMap.isEmpty()) {
 630  
 
 631  0
                 loCatRpcServiceAsync.getLoCategoryTypes(new KSAsyncCallback<List<LoCategoryTypeInfo>>() {
 632  
 
 633  
                     @Override
 634  
                     public void handleFailure(Throwable caught) {
 635  0
                         Window.alert("getLoCategoryTypes failed " + caught.getMessage());
 636  0
                     }
 637  
 
 638  
                     @Override
 639  
                     public void onSuccess(List<LoCategoryTypeInfo> result) {
 640  0
                         if (categoryTypeMap == null) {
 641  0
                             loadCategoryTypes(result);
 642  
                         }
 643  0
                         redrawCategoryTable();
 644  0
                     }
 645  
 
 646  
                 });
 647  
             } else {
 648  0
                 redrawCategoryTable();
 649  
             }
 650  0
         }
 651  
 
 652  
         private void redrawCategoryTable() {
 653  0
             listPanel.clear();
 654  
 
 655  0
             for (int i = 0; i < categories.size(); i++) {
 656  0
                 String name = categories.get(i).getName();
 657  0
                 String typeKey = categories.get(i).getType();
 658  
                 // TODO - need to somehow ensure that categoryTypeMap is initialized before redraw()
 659  0
                 KSItemLabel newItemLabel = new KSItemLabel(true, new CategoryDataParser());
 660  0
                 Data categoryData = CategoryDataUtil.toData(categories.get(i));
 661  0
                 newItemLabel.setValue(new DataValue(categoryData));
 662  0
                 newItemLabel.addCloseHandler(deleteHandler);
 663  
 
 664  0
                 listPanel.add(newItemLabel);
 665  
 //               String name = categories.get(i).getName();
 666  
 //               String typeKey = categories.get(i).getType();
 667  
 //               // TODO - need to somehow ensure that categoryTypeMap is initialized before redraw() 
 668  
 //               String typeName = "ERROR: uninitialized categoryTypeMap";
 669  
 //               if (null != categoryTypeMap) {
 670  
 //                   typeName = categoryTypeMap.get(typeKey).getName();
 671  
 //               } 
 672  
 //               categoryTable.setWidget(row, col++, new KSLabel(name + CATEGORY_TYPE_SEPARATOR + typeName));
 673  
 //               KSLabel deleteLabel = new KSLabel("[x]");
 674  
 //               deleteLabel.addStyleName("KS-LOBuilder-Search-Link");
 675  
 //               deleteLabel.addClickHandler(deleteHandler);
 676  
 //               categoryTable.setWidget(row, col++, deleteLabel);
 677  
 //               row++;
 678  
 //               col = 0;                                
 679  
             }
 680  0
         }
 681  
 
 682  
         public List<LoCategoryInfo> getValue() {
 683  0
             return categories;
 684  
         }
 685  
 
 686  
         public void setValue(List<LoCategoryInfo> categories) {
 687  0
             this.categories = categories;
 688  0
             redraw();
 689  0
         }
 690  
 
 691  
         @Override
 692  
         public void setValue(List<LoCategoryInfo> value, boolean fireEvents) {
 693  0
             setValue(value);
 694  0
         }
 695  
 
 696  
 
 697  
         public void removeItem(String text) {
 698  
 
 699  0
             int a = text.indexOf(CATEGORY_TYPE_SEPARATOR);
 700  0
             text = text.substring(0, a);
 701  
 
 702  0
             int i = 0;
 703  0
             for (LoCategoryInfo catInfo : categories) {
 704  0
                 String name = catInfo.getName();
 705  
 
 706  0
                 if (name.equals(text)) {
 707  0
                     categories.remove(i);
 708  0
                     fireChangeEvent();
 709  0
                     break;
 710  
                 }
 711  0
                 i++;
 712  0
             }
 713  0
             redraw();
 714  0
         }
 715  
 
 716  
         public void addItem(LoCategoryInfo category) {
 717  0
             categories.add(category);
 718  0
             fireChangeEvent();
 719  0
             redraw();
 720  0
         }
 721  
     }
 722  
 
 723  
     public class CategoryDataParser implements DataHelper {
 724  
 
 725  0
         public CategoryDataParser() {
 726  0
         }
 727  
 
 728  
         ;
 729  
 
 730  
         @Override
 731  
         public String getKey(Data data) {
 732  0
             return parse(data);
 733  
         }
 734  
 
 735  
         @Override
 736  
         public String parse(Data data) {
 737  0
             String result = null;
 738  0
             if (data != null) {
 739  0
                 LoCategoryInfo loCategoryInfo = CategoryDataUtil.toLoCategoryInfo(data);
 740  0
                 String typeName = "ERROR: uninitialized categoryTypeMap";
 741  0
                 if (null != categoryTypeMap) {
 742  0
                     typeName = categoryTypeMap.get(loCategoryInfo.getType()).getName();
 743  
                 }
 744  0
                 result = loCategoryInfo.getName() +
 745  
                         LOCategoryBuilder.LOCategoryListNew.CATEGORY_TYPE_SEPARATOR + typeName;
 746  0
             } else {
 747  0
                 result = "";
 748  
             }
 749  0
             return result;
 750  
         }
 751  
 
 752  
     }
 753  
 
 754  0
     public class CreateLoCancelGroup extends ButtonGroup<LoCancelEnum> {
 755  0
         public CreateLoCancelGroup(Callback<LoCancelEnum> callback) {
 756  0
             layout = new ButtonRow();
 757  0
             this.addCallback(callback);
 758  
 
 759  0
             addButton(LoCancelEnum.CANCEL);
 760  0
             addButtonToSecondaryGroup(LoCancelEnum.CREATE);
 761  
 
 762  0
             this.initWidget(layout);
 763  0
         }
 764  
 
 765  
         private void addButton(final LoCancelEnum type) {
 766  0
             KSButton button = new KSButton(type.getText(), new ClickHandler() {
 767  
 
 768  
                 @Override
 769  
                 public void onClick(ClickEvent event) {
 770  0
                     sendCallbacks(type);
 771  0
                 }
 772  
             });
 773  0
             layout.addButton(button);
 774  0
             buttonMap.put(type, button);
 775  0
         }
 776  
 
 777  
         private void addButtonToSecondaryGroup(final LoCancelEnum type) {
 778  0
             KSButton button = new KSButton(type.getText(), new ClickHandler() {
 779  
 
 780  
                 @Override
 781  
                 public void onClick(ClickEvent event) {
 782  0
                     sendCallbacks(type);
 783  0
                 }
 784  
             });
 785  0
             ((ButtonRow) layout).addButtonToSecondaryGroup(button);
 786  0
             buttonMap.put(type, button);
 787  0
         }
 788  
     }
 789  
 
 790  0
     public static enum LoCancelEnum implements ButtonEnum {
 791  0
         CREATE, CANCEL;
 792  
 
 793  
         @Override
 794  
         public ButtonEnum getActionType() {
 795  0
             return CREATE;
 796  
         }
 797  
 
 798  
         @Override
 799  
         public ButtonEnum getCancelType() {
 800  0
             return CANCEL;
 801  
         }
 802  
 
 803  
         @Override
 804  
         public ButtonStyle getStyle() {
 805  0
             return ButtonStyle.PRIMARY;
 806  
         }
 807  
 
 808  
         @Override
 809  
         public String getText() {
 810  0
             switch (this) {
 811  
                 case CREATE:
 812  0
                     return "Create";
 813  
                 case CANCEL:
 814  0
                     return "Cancel";
 815  
             }
 816  0
             return null;
 817  
         }
 818  
     }
 819  
 
 820  
     @Override
 821  
     protected void onEnsureDebugId(String baseID) {
 822  0
         super.onEnsureDebugId(baseID);
 823  0
         picker.ensureDebugId(baseID);
 824  0
         addButton.ensureDebugId(baseID + "-Add");
 825  0
         browseCategoryLink.ensureDebugId(DebugIdUtils.createWebDriverSafeDebugId(baseID + "-" + browseCategoryLink.getText()));
 826  0
     }
 827  
     
 828  
     
 829  
 }