Coverage Report - org.kuali.rice.kew.docsearch.DocumentLookupCriteriaProcessorKEWAdapter
 
Classes in this File Line Coverage Branch Coverage Complexity
DocumentLookupCriteriaProcessorKEWAdapter
0%
0/179
0%
0/80
5.444
 
 1  
 /*
 2  
  * Copyright 2007-2009 The Kuali Foundation
 3  
  *
 4  
  * Licensed under the Educational Community License, Version 2.0 (the "License");
 5  
  * you may not use this file except in compliance with the License.
 6  
  * You may obtain a copy of the License at
 7  
  *
 8  
  * http://www.opensource.org/licenses/ecl2.php
 9  
  *
 10  
  * Unless required by applicable law or agreed to in writing, software
 11  
  * distributed under the License is distributed on an "AS IS" BASIS,
 12  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  
  * See the License for the specific language governing permissions and
 14  
  * limitations under the License.
 15  
  */
 16  
 package org.kuali.rice.kew.docsearch;
 17  
 
 18  
 import org.apache.commons.lang.StringUtils;
 19  
 import org.kuali.rice.core.util.KeyLabelPair;
 20  
 import org.kuali.rice.kew.doctype.ApplicationDocumentStatus;
 21  
 import org.kuali.rice.kew.doctype.bo.DocumentType;
 22  
 import org.kuali.rice.kew.engine.node.RouteNode;
 23  
 import org.kuali.rice.kew.lookup.valuefinder.DocumentRouteStatusValuesFinder;
 24  
 import org.kuali.rice.kew.service.KEWServiceLocator;
 25  
 import org.kuali.rice.kew.util.KEWConstants;
 26  
 import org.kuali.rice.kns.service.DataDictionaryService;
 27  
 import org.kuali.rice.kns.util.FieldUtils;
 28  
 import org.kuali.rice.kns.web.ui.Field;
 29  
 import org.kuali.rice.kns.web.ui.Row;
 30  
 
 31  
 import java.util.ArrayList;
 32  
 import java.util.List;
 33  
 import java.util.Set;
 34  
 
 35  
 /**
 36  
  * This is a description of what this class does - chris don't forget to fill this in.
 37  
  *
 38  
  * @author Kuali Rice Team (rice.collab@kuali.org)
 39  
  *
 40  
  */
 41  0
 public class DocumentLookupCriteriaProcessorKEWAdapter implements
 42  
                 DocumentLookupCriteriaProcessor {
 43  
         DocumentSearchCriteriaProcessor criteriaProcessor;
 44  
         //TODO: remove this and use service locator or try helper in WorkflowUtils if sufficient
 45  
         DataDictionaryService dataDictionaryService;
 46  
 
 47  
         /**
 48  
          * @return the criteriaProcessor
 49  
          */
 50  
         public DocumentSearchCriteriaProcessor getCriteriaProcessor() {
 51  0
                 return this.criteriaProcessor;
 52  
         }
 53  
 
 54  
         public void setCriteriaProcessor(
 55  
                         DocumentSearchCriteriaProcessor criteriaProcessor) {
 56  0
                 this.criteriaProcessor = criteriaProcessor;
 57  0
         }
 58  
 
 59  
         public void setDataDictionaryService(DataDictionaryService dataDictionaryService) {
 60  0
                 this.dataDictionaryService = dataDictionaryService;
 61  0
         }
 62  
 
 63  
         /**
 64  
          * @see org.kuali.rice.kew.docsearch.DocumentLookupCriteriaProcessor#getRows(org.kuali.rice.kew.doctype.bo.DocumentType, java.util.List, boolean, boolean)
 65  
          */
 66  
         public List<Row> getRows(DocumentType documentType, List<Row> knsRows, boolean detailed, boolean superSearch) {
 67  0
                 List<Row> rows = new ArrayList<Row>();
 68  
 
 69  0
                 List<Row> searchAttRows = new ArrayList<Row>();
 70  
                 List<List<StandardDocSearchCriteriaFieldContainer>> preSearchAttFields;
 71  0
                         if(!detailed) {
 72  0
                                  preSearchAttFields = criteriaProcessor.getBasicSearchManager().getColumnsPreSearchAttributes();
 73  
                         } else {
 74  0
                                  preSearchAttFields = criteriaProcessor.getAdvancedSearchManager().getColumnsPreSearchAttributes();
 75  
                         }
 76  0
                 List<Row> preSearchAttRows = standardNonSearchAttRows(documentType,preSearchAttFields);
 77  
 
 78  0
                 rows.addAll(preSearchAttRows);
 79  
 
 80  
 
 81  0
                 if(documentType!=null) {
 82  
 
 83  
                         //search atts
 84  0
                         searchAttRows = searchAttRows(documentType);
 85  0
                         rows.addAll(searchAttRows);
 86  
         }
 87  
 
 88  
                 //post atts
 89  
                 List<List<StandardDocSearchCriteriaFieldContainer>> postSearchAttFields;
 90  0
                 if(!detailed) {
 91  0
                         postSearchAttFields = criteriaProcessor.getBasicSearchManager().getColumnsPostSearchAttributes();
 92  
                 } else {
 93  0
                         postSearchAttFields = criteriaProcessor.getAdvancedSearchManager().getColumnsPostSearchAttributes();
 94  
                 }
 95  
 
 96  
 
 97  0
                 List<Row> postSearchAttRows = standardNonSearchAttRows(documentType,postSearchAttFields);
 98  0
                 rows.addAll(postSearchAttRows);
 99  
                 //add hidden fields
 100  0
                 Row hidrow = new Row();
 101  0
                 hidrow.setHidden(true);
 102  0
                 Field detailedField = new Field();
 103  0
                 detailedField.setPropertyName("isAdvancedSearch");
 104  0
                 detailedField.setPropertyValue(detailed?"YES":"NO");
 105  0
                 detailedField.setFieldType(Field.HIDDEN);
 106  0
                 Field superUserSearchField = new Field();
 107  0
                 superUserSearchField.setPropertyName("superUserSearch");
 108  0
                 superUserSearchField.setPropertyValue(superSearch?"YES":"NO");
 109  0
                 superUserSearchField.setFieldType(Field.HIDDEN);
 110  0
                 List<Field> hidFields = new ArrayList<Field>();
 111  0
                 hidFields.add(detailedField);
 112  0
                 hidFields.add(superUserSearchField);
 113  0
                 hidrow.setFields(hidFields);
 114  0
                 rows.add(hidrow);
 115  
 
 116  0
                 return rows;
 117  
         }
 118  
         /**
 119  
          * This method ...
 120  
          *
 121  
      * @param documentType document Type
 122  
      * @param fields containing search criteria
 123  
      * @return list of row objects
 124  
      */
 125  
         protected List<Row> standardNonSearchAttRows(DocumentType documentType, List<List<StandardDocSearchCriteriaFieldContainer>> fields) {
 126  0
                 List<Row> customPreRows = new ArrayList<Row>();
 127  0
                 for (List<StandardDocSearchCriteriaFieldContainer> list : fields) {
 128  
 
 129  
 
 130  0
                         for (StandardDocSearchCriteriaFieldContainer standardDocSearchCriteriaFieldContainer : list) {
 131  0
                                 List<StandardSearchCriteriaField> standardSearchCriteriaFields = standardDocSearchCriteriaFieldContainer.getFields();
 132  0
                                 for (StandardSearchCriteriaField standardSearchCriteriaField : standardSearchCriteriaFields) {
 133  
                                         //for now only one field per row (including for things like from/to etc)
 134  0
                                         Row row = new Row();
 135  0
                                         List<Field>knsFields = new ArrayList<Field>();
 136  0
                                         Field field = new Field();
 137  0
                                         boolean skipadd = false;
 138  
 
 139  0
                                         String propertyName = "";
 140  0
                                         if(StringUtils.contains(standardSearchCriteriaField.getProperty(), ".")) {
 141  0
                                                 propertyName = StringUtils.substringAfterLast(standardSearchCriteriaField.getProperty(), ".");
 142  
                                         } else {
 143  0
                                                 propertyName = standardSearchCriteriaField.getProperty();
 144  
                                         }
 145  
 
 146  0
                                         field.setPropertyName(propertyName);
 147  
                                         //do we care?
 148  
                                         //                                field.setBusinessObjectClassName(dataDictionaryService.getattribute);
 149  
 
 150  0
                                         String fieldType = standardSearchCriteriaField.getFieldType();
 151  
 
 152  0
                                         String lookupableImplServiceName = standardSearchCriteriaField.getLookupableImplServiceName();
 153  0
                                         if(lookupableImplServiceName!=null) {
 154  0
                                                 if(StringUtils.equals("DocumentTypeLookupableImplService", lookupableImplServiceName)) {
 155  0
                                                         fieldType = Field.TEXT; // KULRICE-2630 - doctype needs to be a text box
 156  0
                                                         field.setWebOnBlurHandler("validateDocTypeAndRefresh"); // used to call ajax dwr search for doctype
 157  
                                                         //TODO: instead of hardcoding these let's see about getting them from spring
 158  0
                                                         field.setQuickFinderClassNameImpl("org.kuali.rice.kew.doctype.bo.DocumentType");
 159  0
                                                         field.setFieldConversions("name:"+propertyName);
 160  0
                                                 } else if (StringUtils.equals("UserLookupableImplService", lookupableImplServiceName)) {
 161  0
                                                         fieldType = Field.TEXT;
 162  0
                                                         field.setQuickFinderClassNameImpl("org.kuali.rice.kim.bo.impl.PersonImpl");
 163  0
                                                         field.setFieldConversions("principalName:"+propertyName);
 164  0
                                                 } else if (StringUtils.equals("WorkGroupLookupableImplService", lookupableImplServiceName)) {
 165  0
                                                         field.setQuickFinderClassNameImpl("org.kuali.rice.kim.bo.impl.GroupImpl");
 166  0
                                                         fieldType = Field.LOOKUP_READONLY;
 167  0
                                                         field.setFieldConversions("groupName:"+propertyName+","+"groupId:"+StandardDocumentSearchCriteriaProcessor.CRITERIA_KEY_WORKGROUP_VIEWER_ID);
 168  
                                                 }
 169  
                                         }
 170  0
                                         boolean fieldHidden = standardSearchCriteriaField.isHidden();
 171  0
                                         if(fieldHidden) {
 172  0
                                                 fieldType = Field.HIDDEN;
 173  0
                                                 row.setHidden(true);
 174  
                                         }
 175  0
                                         field.setFieldType(fieldType);
 176  
 
 177  
                                         //now calling the dd to get size.
 178  0
                                         Integer maxLen = dataDictionaryService.getAttributeMaxLength(DocSearchCriteriaDTO.class, propertyName);
 179  0
                                         if(maxLen != null){
 180  0
                                                 field.setMaxLength(maxLen.intValue());
 181  
                                         }
 182  
                                         else{
 183  0
                                                 field.setMaxLength(40);
 184  
                                         }
 185  
                                         
 186  
                                         //TODO: special processing for some field types
 187  0
                                         if(StringUtils.equals(StandardSearchCriteriaField.DROPDOWN,fieldType)||
 188  
                                            StringUtils.equals(StandardSearchCriteriaField.DROPDOWN_HIDE_EMPTY, fieldType)){
 189  0
                                                 if(StringUtils.equals(StandardSearchCriteriaField.DROPDOWN_HIDE_EMPTY,fieldType)) {
 190  
 
 191  0
                                                         field.setFieldType(Field.DROPDOWN);
 192  0
                                                         field.setSkipBlankValidValue(true);
 193  
 
 194  
                                                 }
 195  
 
 196  0
                                                 if("documentRouteStatus".equalsIgnoreCase(standardSearchCriteriaField.getOptionsCollectionProperty())) {
 197  0
                                                         DocumentRouteStatusValuesFinder values = new DocumentRouteStatusValuesFinder();
 198  0
                                                         field.setFieldValidValues(values.getKeyValues());
 199  0
                                                         field.setFieldType(Field.MULTISELECT); // this is now multi select [KULRICE-2840]
 200  0
                                                         int size = (values.getKeyValues().size() > 10)?10:values.getKeyValues().size();
 201  0
                                                         field.setMaxLength(size);
 202  0
                                                 } else if("routeNodes".equalsIgnoreCase(standardSearchCriteriaField.getOptionsCollectionProperty())){
 203  0
                                                         if(documentType!=null) {
 204  
                                                                 //TODO: can these be used directly in values finder also there is an option key and value property that could probably be used by all of these
 205  0
                                                                 List<KeyLabelPair> keyValues = new ArrayList<KeyLabelPair>();
 206  0
                                                                 List<RouteNode> routeNodes = KEWServiceLocator.getRouteNodeService().getFlattenedNodes(documentType, true);
 207  0
                                                                 for (RouteNode routeNode : routeNodes) {
 208  0
                                                                         keyValues.add(new KeyLabelPair(routeNode.getRouteNodeId()+"",routeNode.getRouteNodeName()));
 209  
                                                                 }
 210  0
                                                                 field.setFieldValidValues(keyValues);
 211  
                                                                 //TODO: fix this in criteria this field shouldn't be blank values otherwise have to reset this for some reason
 212  0
                                                                 field.setSkipBlankValidValue(false);
 213  0
                                                         } else {
 214  0
                                                                 field.setFieldType(Field.READONLY);
 215  
                                                         }
 216  0
                                                 } else if("qualifierLogic".equalsIgnoreCase(standardSearchCriteriaField.getOptionsCollectionProperty())){
 217  0
                                                         if(documentType==null){
 218  
                                                                 //FIXME: definitely not the best place for this
 219  0
                                                                 skipadd=true;
 220  
                                                         }
 221  
                                                         //TODO: move to values finder class
 222  0
                                                         List<KeyLabelPair> keyValues = new ArrayList<KeyLabelPair>();
 223  0
                                                         Set<String> docStatusKeys = KEWConstants.DOC_SEARCH_ROUTE_STATUS_QUALIFIERS.keySet();
 224  0
                                                         for (String string : docStatusKeys) {
 225  0
                                                                 KeyLabelPair keyLabel = new KeyLabelPair(string,KEWConstants.DOC_SEARCH_ROUTE_STATUS_QUALIFIERS.get(string));
 226  0
                                                                 keyValues.add(keyLabel);
 227  0
                                                         }
 228  0
                                                         field.setFieldValidValues(keyValues);
 229  0
                                                 } else if("validApplicationStatuses".equalsIgnoreCase(standardSearchCriteriaField.getOptionsCollectionProperty())){
 230  0
                                                         if(documentType!=null) {
 231  
                                                                 //TODO: can these be used directly in values finder also there is an option key and value property that could probably be used by all of these
 232  0
                                                                 List<KeyLabelPair> keyValues = new ArrayList<KeyLabelPair>();
 233  0
                                                                 List<ApplicationDocumentStatus> validStatuses = documentType.getValidApplicationStatuses();
 234  0
                                                                 for (ApplicationDocumentStatus appStatus : (List<ApplicationDocumentStatus>) validStatuses) {
 235  0
                                                                         keyValues.add(new KeyLabelPair(appStatus.getStatusName(),appStatus.getStatusName()));
 236  
                                                                 }
 237  0
                                                                 field.setFieldValidValues(keyValues);
 238  
                                                                 //TODO: fix this in criteria this field shouldn't be blank values otherwise have to reset this for some reason
 239  0
                                                                 field.setSkipBlankValidValue(false);
 240  0
                                                         } else {
 241  0
                                                                 field.setFieldType(Field.READONLY);
 242  0
                                                                 skipadd=true;
 243  
                                                         }
 244  
                                                         
 245  
                                                 } else {
 246  0
                                                         field.setFieldValidValues(new ArrayList<KeyLabelPair>());
 247  
                                                 }
 248  
                                         }
 249  
 
 250  
 
 251  0
                                         if(StringUtils.isEmpty(field.getFieldLabel())) {                                                 
 252  0
                                                 String labelMessageKey = dataDictionaryService.getAttributeLabel(DocSearchCriteriaDTO.class,propertyName);
 253  0
                                                 field.setFieldLabel(labelMessageKey);
 254  
                                         }
 255  
 
 256  0
                                         boolean hasDatePicker = StringUtils.isNotEmpty(standardSearchCriteriaField.getDatePickerKey());
 257  0
                                         field.setDatePicker(hasDatePicker);
 258  
 
 259  0
                                         if(!skipadd) {
 260  0
                                                 knsFields.add(field);
 261  0
                                                 row.setFields(knsFields);
 262  0
                                                 customPreRows.add(row);
 263  
                                         }
 264  0
                                 }
 265  0
                         }
 266  
                 }
 267  0
                 return customPreRows;
 268  
         }
 269  
 
 270  
         /**
 271  
          * This method gets the search att rows and fixes them where necessary
 272  
          *
 273  
      * @param documentType seach on att rows
 274  
      * @return list of rows
 275  
      */
 276  
         protected List<Row> searchAttRows(DocumentType documentType) {
 277  0
                 List<Row> customSearchAttRows = new ArrayList<Row>();
 278  0
                 List<SearchableAttribute> searchAtts = documentType.getSearchableAttributes();
 279  0
                 for (SearchableAttribute searchableAttribute : searchAtts) {
 280  0
                         DocumentSearchContext documentSearchContext = DocSearchUtils.getDocumentSearchContext("", documentType.getName(), "");
 281  0
                         customSearchAttRows.addAll(searchableAttribute.getSearchingRows(documentSearchContext));
 282  0
                 }
 283  0
                 List<Row> fixedCustomSearchAttRows = new ArrayList<Row>();
 284  0
                 for (Row row : customSearchAttRows) {
 285  0
                         List<Field> fields = row.getFields();
 286  0
                         for (Field field : fields) {
 287  
                                 //force the max length for now if not set
 288  0
                                 if(field.getMaxLength()==0) {
 289  0
                                         field.setMaxLength(100);
 290  
                                 }
 291  0
                                 if(field.isDatePicker() && field.isRanged()) {
 292  0
                                         Field newDate = FieldUtils.createRangeDateField(field);
 293  0
                                         List<Field> newFields = new ArrayList<Field>();
 294  0
                                         newFields.add(newDate);
 295  0
                                         fixedCustomSearchAttRows.addAll(FieldUtils.wrapFields(newFields));
 296  0
                                 }
 297  
                         }
 298  0
                         fixedCustomSearchAttRows.add(row);
 299  0
                 }
 300  
                 
 301  
                 // If Application Document Status policy is in effect for this document type,
 302  
                 // add search attributes for document status, and transition dates.
 303  
                 // Note: document status field is a drop down if valid statuses are defined,
 304  
                 //       a text input field otherwise.
 305  0
                 fixedCustomSearchAttRows.addAll( buildAppDocStatusRows(documentType) );
 306  
                 
 307  0
                 return fixedCustomSearchAttRows;
 308  
         }
 309  
 
 310  
         // Add the appropriate doc search criteria rows.
 311  
         // If the document type policy DOCUMENT_STATUS_POLICY is set to "app", or "both"
 312  
         // Then display the doc search criteria fields.
 313  
         // If the documentType.validApplicationStatuses are defined, then the criteria field is a drop down.
 314  
         // If the validApplication statuses are NOT defined, then the criteria field is a text input.
 315  
         protected List<Row> buildAppDocStatusRows(DocumentType documentType){
 316  0
                 List<Row> appDocStatusRows = new ArrayList<Row>();
 317  0
                 List<List<StandardDocSearchCriteriaFieldContainer>> columnList = new ArrayList<List<StandardDocSearchCriteriaFieldContainer>>();
 318  0
                 List<StandardDocSearchCriteriaFieldContainer> columns = new ArrayList<StandardDocSearchCriteriaFieldContainer>();
 319  0
                 if (documentType.isAppDocStatusInUse()){
 320  0
                         StandardDocSearchCriteriaFieldContainer container = new StandardDocSearchCriteriaFieldContainer();
 321  
 
 322  0
                         List<ApplicationDocumentStatus> validStatuses = documentType.getValidApplicationStatuses();
 323  0
                         if (validStatuses == null || validStatuses.size() == 0){
 324  
                                 // use a text input field
 325  0
                                 container = new StandardDocSearchCriteriaFieldContainer("docSearch.DocumentSearch.criteria.label.appDocStatus", new StandardSearchCriteriaField(DocumentSearchCriteriaProcessor.CRITERIA_KEY_APP_DOC_STATUS,"criteria.appDocStatus",StandardSearchCriteriaField.TEXT,null,null,"DocSearchApplicationDocStatus",false,null,null,false));
 326  
                                 
 327  
                         } else {        
 328  
                                 // dropdown
 329  0
                                 container.setLabelMessageKey("docSearch.DocumentSearch.criteria.label.appDocStatus");
 330  0
                                 container.setFieldKey(DocumentSearchCriteriaProcessor.CRITERIA_KEY_APP_DOC_STATUS);
 331  0
                                 StandardSearchCriteriaField dropDown = new StandardSearchCriteriaField(DocumentSearchCriteriaProcessor.CRITERIA_KEY_APP_DOC_STATUS + "_VALUES","criteria.appDocStatus",StandardSearchCriteriaField.DROPDOWN_HIDE_EMPTY,null,null,"DocSearchApplicationDocStatus",false,null,null,false);
 332  
                                 
 333  0
                                 dropDown.setOptionsCollectionProperty("validApplicationStatuses");
 334  0
                                 dropDown.setCollectionKeyProperty("statusName");
 335  0
                                 dropDown.setCollectionLabelProperty("statusName");
 336  0
                                 dropDown.setEmptyCollectionMessage("Select a document status.");
 337  0
                                 container.addField(dropDown);
 338  
                                 
 339  
                         }
 340  
                         // Create Date Picker fields for AppDocStatus transitions
 341  0
                     List<StandardSearchCriteriaField> dateFields = new ArrayList<StandardSearchCriteriaField>();
 342  0
                     dateFields.add(new StandardSearchCriteriaField(DocumentSearchCriteriaProcessor.CRITERIA_KEY_STATUS_TRANSITION_DATE + DocumentSearchCriteriaProcessor.CRITERIA_KEYS_SUFFIX_RANGE_LOWER_BOUND,"fromStatusTransitionDate",StandardSearchCriteriaField.TEXT,"fromStatusTransitionDate","docSearch.DocumentSearch.criteria.label.from","DocSearchStatusTransitionDate",false,null,null,false));
 343  0
                     dateFields.add(new StandardSearchCriteriaField(DocumentSearchCriteriaProcessor.CRITERIA_KEY_STATUS_TRANSITION_DATE + DocumentSearchCriteriaProcessor.CRITERIA_KEYS_SUFFIX_RANGE_UPPER_BOUND,"toStatusTransitionDate",StandardSearchCriteriaField.TEXT,"toStatusTransitionDate","docSearch.DocumentSearch.criteria.label.to",null,false,null,null,false));
 344  0
                     StandardDocSearchCriteriaFieldContainer dateContainer = new StandardDocSearchCriteriaFieldContainer(DocumentSearchCriteriaProcessor.CRITERIA_KEY_STATUS_TRANSITION_DATE, "docSearch.DocumentSearch.criteria.label.statusTransitionDate", dateFields);
 345  
                         
 346  0
                         columns.add( container );
 347  0
                         columns.add( dateContainer );
 348  0
                         columnList.add( columns );
 349  0
                         appDocStatusRows.addAll( standardNonSearchAttRows(documentType,columnList) );
 350  
                         
 351  
                 }
 352  0
                 return appDocStatusRows;
 353  
         }
 354  
 
 355  
         /**
 356  
          *
 357  
          * @see org.kuali.rice.kns.lookup.LookupableHelperService#shouldDisplayHeaderNonMaintActions()
 358  
          */
 359  
         public boolean shouldDisplayHeaderNonMaintActions() {
 360  0
                 return criteriaProcessor.isHeaderBarDisplayed();
 361  
         }
 362  
 
 363  
         /**
 364  
          *
 365  
          * @see org.kuali.rice.kns.lookup.LookupableHelperService#shouldDisplayLookupCriteria()
 366  
          */
 367  
         public boolean shouldDisplayLookupCriteria() {
 368  
                 //TODO: chris - How should this handle advanced?  I thought we were only hiding main
 369  0
                 return criteriaProcessor.isBasicSearchCriteriaDisplayed();
 370  
         }
 371  
 }