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