Coverage Report - org.kuali.student.lum.common.client.lo.CategoryManagementTable
 
Classes in this File Line Coverage Branch Coverage Complexity
CategoryManagementTable
0%
0/177
0%
0/66
2.29
CategoryManagementTable$1
0%
0/7
0%
0/2
2.29
CategoryManagementTable$2
0%
0/10
N/A
2.29
CategoryManagementTable$CategoryRow
0%
0/7
N/A
2.29
 
 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.HashSet;
 20  
 import java.util.List;
 21  
 
 22  
 import org.kuali.student.common.ui.client.application.KSAsyncCallback;
 23  
 import org.kuali.student.common.ui.client.mvc.Callback;
 24  
 import org.kuali.student.common.ui.client.service.ServerPropertiesRpcService;
 25  
 import org.kuali.student.common.ui.client.service.ServerPropertiesRpcServiceAsync;
 26  
 import org.kuali.student.common.ui.client.widgets.searchtable.ResultRow;
 27  
 import org.kuali.student.common.ui.client.widgets.table.scroll.Column;
 28  
 import org.kuali.student.common.ui.client.widgets.table.scroll.DefaultTableModel;
 29  
 import org.kuali.student.common.ui.client.widgets.table.scroll.Row;
 30  
 import org.kuali.student.common.ui.client.widgets.table.scroll.Table;
 31  
 import org.kuali.student.lum.common.client.lo.rpc.LoCategoryRpcService;
 32  
 import org.kuali.student.lum.common.client.lo.rpc.LoCategoryRpcServiceAsync;
 33  
 import org.kuali.student.lum.lo.dto.LoCategoryInfo;
 34  
 
 35  
 import com.google.gwt.core.client.GWT;
 36  
 import com.google.gwt.user.client.Window;
 37  
 import com.google.gwt.user.client.ui.Composite;
 38  
 import com.google.gwt.user.client.ui.FlowPanel;
 39  
 import com.google.gwt.user.client.ui.VerticalPanel;
 40  
 
 41  
 /**
 42  
  * This is a description of what this class does - Gary Struthers don't forget to fill this in. 
 43  
  * 
 44  
  * @author Kuali Student Team (gstruthers@berkeley.edu)
 45  
  *
 46  
  */
 47  0
 public class CategoryManagementTable extends Composite {
 48  0
     static String NAME_COLUMN_HEADER = "Category";
 49  0
     static String TYPE_COLUMN_HEADER = "Type";
 50  0
     static String STATE_COLUMN_HEADER = "State";
 51  0
     static String ID_COLUMN_KEY = "id";
 52  0
     static String NAME_COLUMN_KEY = "name";
 53  0
     static String TYPE_COLUMN_KEY = "type";
 54  0
     static String STATE_COLUMN_KEY = "state";
 55  0
     private List<ResultRow> resultRows = new ArrayList<ResultRow>();
 56  0
     private DefaultTableModel model = new DefaultTableModel();
 57  0
     private Table table = new Table();
 58  
     //private GenericTableModel<ResultRow> tableModel = new GenericTableModel<ResultRow>(resultRows);
 59  
     //private PagingScrollTableBuilder<ResultRow> builder = new PagingScrollTableBuilder<ResultRow>();
 60  
     //protected PagingScrollTable<ResultRow> pagingScrollTable;
 61  0
     private FlowPanel layout = new FlowPanel();
 62  
     private static Boolean displayOnlyActiveCategories; // static global
 63  0
     private boolean hideInactiveCategories = false;
 64  
 
 65  0
     private LoCategoryRpcServiceAsync loCatRpcServiceAsync = GWT.create(LoCategoryRpcService.class);
 66  0
     private static ServerPropertiesRpcServiceAsync serverProperties = GWT.create(ServerPropertiesRpcService.class);
 67  
 
 68  
     // Categories to filter out after the are loaded from the backend
 69  
     // See KSLAB-1871
 70  0
     private List<LoCategoryInfo> loCategoriesToFilter = new ArrayList<LoCategoryInfo>();
 71  
     
 72  
     class CategoryRow extends Row{
 73  
             ResultRow row;
 74  
             
 75  0
             public CategoryRow(ResultRow row){
 76  0
                     this.row = row;
 77  0
             }
 78  
                 @Override
 79  
                 public Object getCellData(String columnId) {
 80  0
                         return row.getValue(columnId);
 81  
                 }
 82  
                 @Override
 83  
                 public void setCellData(String columnId, Object newValue) {
 84  0
                         row.setValue(columnId, newValue.toString());                
 85  0
                 }
 86  
                 
 87  
                 public ResultRow getResultRowData(){
 88  0
                         return row;
 89  
                 }
 90  
         }
 91  
     
 92  
     public Table getTable(){
 93  0
             return table;
 94  
     }
 95  
     
 96  
     /**
 97  
      * This method should be called before constructor so config flag is pre-set
 98  
      * only needs to be called once. It's a static flag that only changes when the 
 99  
      * server is started
 100  
      * 
 101  
      */
 102  
     public static void setDisplayOnlyActiveCategories() {
 103  0
         if (null == displayOnlyActiveCategories) {
 104  0
             serverProperties.get("ks.lum.ui.displayOnlyActiveLoCategories", new KSAsyncCallback<String>() {
 105  
                 @Override
 106  
                 public void handleFailure(Throwable caught) {
 107  0
                     GWT.log("get displayOnlyActiveLoCategories failed", caught);
 108  0
                     Window.alert("Failed to get displayOnlyActiveLoCategories setting");
 109  0
                 }
 110  
     
 111  
                 @Override
 112  
                 public void onSuccess(String result) {
 113  0
                     if (result != null) {
 114  0
                         displayOnlyActiveCategories = Boolean.parseBoolean(result);
 115  
                     }
 116  0
                 }
 117  
             });
 118  
         }  
 119  0
     }
 120  
     
 121  
     private void initCategoryManagementTable(boolean isMultiSelect){
 122  0
         layout.setWidth("100%");
 123  0
         table.setWidth("550px");
 124  0
         table.getScrollPanel().setHeight("400px");
 125  0
         initWidget(layout);
 126  0
         createColumnDefs();
 127  0
         if(isMultiSelect){
 128  0
                 model.setMultipleSelectable(true);
 129  0
                 model.installCheckBoxRowHeaderColumn();
 130  
         }
 131  
         else{
 132  0
                 model.setMultipleSelectable(false);
 133  
         }
 134  0
         table.setTableModel(model);
 135  
         
 136  0
         layout.add(table);
 137  0
     }
 138  
     public CategoryManagementTable() {
 139  0
         super();
 140  0
         initCategoryManagementTable(false);
 141  0
     }
 142  
     /**
 143  
      * Constructor that allows us to filter categories.
 144  
      * <p>
 145  
      * Currently used to filter categories that are already in the picker. 
 146  
      * <p>
 147  
      *  See KSLAB-1871
 148  
      *
 149  
      * @param hideInactiveCategories
 150  
      * @param isMultiSelect
 151  
      * @param loCategoriesToFilter categories to filter out
 152  
      */
 153  
     public CategoryManagementTable(boolean hideInactiveCategories, boolean isMultiSelect, List<LoCategoryInfo> loCategoriesToFilter) {
 154  0
         super();
 155  0
         this.hideInactiveCategories = hideInactiveCategories;
 156  0
         this.loCategoriesToFilter = loCategoriesToFilter;  // needed in constructor due to async
 157  0
         initCategoryManagementTable(isMultiSelect);
 158  0
     }
 159  
     /**
 160  
      * This constructs a CategoryManagementTable with an instance option
 161  
      * 
 162  
      * @param hideInactiveCategories
 163  
      */
 164  
     public CategoryManagementTable(boolean hideInactiveCategories, boolean isMultiSelect) {
 165  0
         super();
 166  0
         this.hideInactiveCategories = hideInactiveCategories;
 167  0
         initCategoryManagementTable(isMultiSelect);
 168  0
     }
 169  
     /**
 170  
      * Two flags control whether to show rows with inactive categories and the state column.
 171  
      * hideInactiveCategories can be set per table instance
 172  
      * displayOnlyActiveCategories is set at Lum startup
 173  
      * hideInactiveCategories overrides displayOnlyActiveCategories
 174  
      * @return true to show all rows and State column
 175  
      */
 176  
     public boolean isHideInactiveCategories() {
 177  0
         if(hideInactiveCategories){
 178  0
             return true;
 179  
         } 
 180  0
         if((displayOnlyActiveCategories == null)||( displayOnlyActiveCategories.booleanValue() == false)){
 181  0
             return false;
 182  
         }else {
 183  0
             return true;
 184  
         }
 185  
     }
 186  
     /**
 187  
      * @param show or hide inactive rows and State column 
 188  
      */
 189  
     public void setHideInactiveCategories(boolean show) {
 190  0
         this.hideInactiveCategories = show;
 191  0
     }
 192  
     public void redraw(){
 193  0
             model.clearRows();
 194  0
             for(ResultRow row: resultRows){
 195  0
                     model.addRow(new CategoryRow(row));
 196  
             }
 197  0
             model.fireTableDataChanged();
 198  0
     }
 199  
     
 200  
     public void redraw(List<ResultRow> filteredRows){
 201  0
             model.clearRows();
 202  0
             table.removeAllRows();
 203  0
             for(ResultRow row: filteredRows){
 204  0
                     model.addRow(new CategoryRow(row));
 205  
             }
 206  0
             model.setCurrentIndex(0);
 207  0
             model.fireTableDataChanged();
 208  0
     }
 209  
 
 210  
     public void clearTable(){
 211  0
         resultRows.clear();
 212  0
         redraw();        
 213  0
     }
 214  
     
 215  
     public void removeSelected(){
 216  0
         for(ResultRow r: getSelectedRows()){
 217  0
             resultRows.remove(r);
 218  
         }
 219  0
         this.redraw();
 220  0
     }
 221  
     public List<ResultRow> getAllRows(){
 222  0
         List<ResultRow> rows = new ArrayList<ResultRow>();
 223  0
         for(ResultRow r: resultRows){
 224  0
             rows.add(r);
 225  
         }
 226  0
         return rows;
 227  
     }    
 228  
     public List<ResultRow> getSelectedRows(){
 229  0
         List<ResultRow> rows = new ArrayList<ResultRow>();
 230  0
         List<Row> selectedRows = model.getSelectedRows();
 231  0
         for(Row r: selectedRows){
 232  0
             rows.add(((CategoryRow)r).getResultRowData());
 233  
         }
 234  0
         return rows;
 235  
     }
 236  
     public List<LoCategoryInfo> getSelectedLoCategoryInfos(){
 237  0
         List<LoCategoryInfo> loCategoryInfos = new ArrayList<LoCategoryInfo>();
 238  0
         List<Row> selectedRows = model.getSelectedRows();
 239  0
         if(selectedRows.isEmpty()) {
 240  0
             return loCategoryInfos;
 241  
         }
 242  0
         for(Row r: selectedRows){
 243  0
             LoCategoryInfo loCategoryInfo = new LoCategoryInfo();
 244  0
             loCategoryInfo.setId(r.getCellData(ID_COLUMN_KEY).toString());
 245  0
             loCategoryInfo.setName(r.getCellData(NAME_COLUMN_KEY).toString());
 246  0
             loCategoryInfo.setType(r.getCellData(TYPE_COLUMN_KEY).toString());
 247  0
             loCategoryInfo.setState(r.getCellData(STATE_COLUMN_KEY).toString());
 248  0
             loCategoryInfos.add(loCategoryInfo);
 249  0
         }
 250  0
         return loCategoryInfos;
 251  
     }    
 252  
 
 253  
     public String getSelectedLoCategoryInfoId(){ 
 254  0
         List<Row> selectedRows = model.getSelectedRows();
 255  0
         if(selectedRows.isEmpty()) {
 256  0
             return null;
 257  
         }
 258  0
         String id = null;
 259  0
         for(Row r: selectedRows){
 260  0
             id = r.getCellData(ID_COLUMN_KEY).toString();
 261  0
             break;
 262  
         }
 263  0
         return id;
 264  
 
 265  
     }   
 266  
     
 267  
     private void createColumnDefs() {
 268  
             
 269  0
             Column name = new Column();
 270  0
             name.setName(NAME_COLUMN_HEADER);
 271  0
             name.setId(NAME_COLUMN_KEY);
 272  0
             name.setSortable(false);
 273  0
             model.addColumn(name);
 274  0
             name.setWidth("250px");
 275  
             
 276  0
             Column type = new Column();
 277  0
             type.setName(TYPE_COLUMN_HEADER);
 278  0
             type.setId(TYPE_COLUMN_KEY);
 279  0
             type.setSortable(false);
 280  0
             model.addColumn(type);
 281  
             
 282  0
         if (!isHideInactiveCategories()) {
 283  0
                 Column state = new Column();
 284  0
                 state.setName(TYPE_COLUMN_HEADER);
 285  0
                 state.setId(TYPE_COLUMN_KEY);
 286  0
                 state.setSortable(false);
 287  0
                 model.addColumn(state);          
 288  
         }
 289  0
     }
 290  
     
 291  
     /**
 292  
      * 
 293  
      * This method will filter out categories that should be excluded 
 294  
      * from the list (e.g. those already in the picker).
 295  
      * <p>
 296  
      * It is called from the filterResults method.
 297  
      * <p>
 298  
      * See KSLAB-1871
 299  
      * 
 300  
      * @param results
 301  
      * @return
 302  
      */
 303  
     private List<LoCategoryInfo> filterResultsWithExcludedCategories(List<LoCategoryInfo> results){
 304  0
         if (loCategoriesToFilter == null || loCategoriesToFilter.size() == 0){
 305  
             // If nothing to filter just return results passed in
 306  0
             return results;
 307  
         }
 308  0
         List<LoCategoryInfo> filteredResults = new ArrayList<LoCategoryInfo>();
 309  0
         for(LoCategoryInfo result : results) {
 310  0
             boolean shouldExcludeRow = false;
 311  0
             for (LoCategoryInfo toFilter : loCategoriesToFilter) {
 312  0
                 String name = toFilter.getName();
 313  0
                 String type = toFilter.getType();
 314  0
                 if (result.getName().equals(name) && result.getType().equals(type)){
 315  0
                     shouldExcludeRow = true;
 316  0
                     break;
 317  
                 }
 318  0
             } 
 319  0
             if (!shouldExcludeRow){
 320  0
                 filteredResults.add(result);
 321  
             }
 322  0
         }
 323  0
         return filteredResults;
 324  
     }
 325  
 
 326  
     
 327  
     private List<LoCategoryInfo> filterResults(List<LoCategoryInfo> result) {
 328  
 
 329  
        // Filter if already in picker etc
 330  0
        result = filterResultsWithExcludedCategories(result);
 331  
   
 332  0
        if(isHideInactiveCategories()) {
 333  0
             List<LoCategoryInfo> filteredResult = new ArrayList<LoCategoryInfo>();
 334  0
             for(LoCategoryInfo info : result) {
 335  0
                 if (info.getState().equals("active") ) {
 336  0
                     filteredResult.add(info);
 337  
                 }
 338  
             }
 339  0
             return filteredResult;
 340  
         } 
 341  0
         return result;   
 342  
     }
 343  
     
 344  
     public void loadTable(final Callback<Boolean> callback) {
 345  0
             table.displayLoading(true);
 346  0
         loCatRpcServiceAsync.getLoCategories("kuali.loRepository.key.singleUse", new KSAsyncCallback<List<LoCategoryInfo>>() {
 347  
             @Override
 348  
             public void handleFailure(Throwable caught) {
 349  0
                 GWT.log("getLoCategories failed", caught);
 350  0
                 Window.alert("Get LoCategories failed");
 351  0
                 callback.exec(false);
 352  0
             }
 353  
 
 354  
             @Override
 355  
             public void onSuccess(List<LoCategoryInfo> results) {
 356  
 
 357  0
                 List<LoCategoryInfo> filteredResults = filterResults(results);
 358  0
                 loadTable(filteredResults);
 359  0
                 callback.exec(true);
 360  0
                 table.displayLoading(false);
 361  0
             }
 362  
         }); 
 363  0
     }
 364  
     
 365  
     private void loadTable(List<LoCategoryInfo> loCategoryInfos) {
 366  0
         resultRows.clear();
 367  0
         HashSet<String> hashSet = new HashSet<String>();
 368  0
         String id = null;
 369  0
         for(LoCategoryInfo info : loCategoryInfos) {
 370  0
             ResultRow resultRow = new ResultRow();
 371  0
             id = info.getId();
 372  0
             if(!hashSet.contains(id)) {
 373  0
                 hashSet.add(id);
 374  0
                 resultRow.setValue(ID_COLUMN_KEY, id);
 375  0
                 resultRow.setValue(NAME_COLUMN_KEY, info.getName());
 376  0
                 resultRow.setValue(TYPE_COLUMN_KEY, info.getType());
 377  0
                 resultRow.setValue(STATE_COLUMN_KEY, info.getState());
 378  0
                 resultRows.add(resultRow);                
 379  
             }
 380  0
         }
 381  0
         redraw();
 382  0
     }    
 383  
 
 384  
     public List<ResultRow> getRowsByType(String type){
 385  0
         List<ResultRow> bufferList = new ArrayList<ResultRow>();
 386  0
         for(ResultRow row : resultRows) {
 387  0
             if(row.getValue(TYPE_COLUMN_KEY).contains(type)){
 388  0
                 bufferList.add(row);
 389  
             }
 390  
         }
 391  0
         return bufferList;
 392  
     }
 393  
     
 394  
     public List<ResultRow> getRowsLikeName(String name){
 395  0
         List<ResultRow> bufferList = new ArrayList<ResultRow>();
 396  0
         for(ResultRow row : resultRows) {
 397  0
             String nameValue = row.getValue(NAME_COLUMN_KEY);
 398  0
             if(nameValue != null) {
 399  0
                 String[] words = nameValue.split("\\W");
 400  0
                 for(String word : words){
 401  0
                     if(word.toUpperCase().startsWith(name.toUpperCase())){
 402  0
                         bufferList.add(row);
 403  0
                         break;
 404  
                     }                    
 405  
                 }
 406  
             }
 407  0
         }
 408  0
         return bufferList;
 409  
     }
 410  
 }