Coverage Report - org.kuali.rice.kew.bo.lookup.DocSearchCriteriaDTOLookupableHelperServiceImpl
 
Classes in this File Line Coverage Branch Coverage Complexity
DocSearchCriteriaDTOLookupableHelperServiceImpl
0%
0/554
0%
0/398
13.5
 
 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.bo.lookup;
 17  
 
 18  
 import org.apache.commons.beanutils.PropertyUtils;
 19  
 import org.apache.commons.lang.StringUtils;
 20  
 import org.kuali.rice.core.config.ConfigContext;
 21  
 import org.kuali.rice.core.util.KeyLabelPair;
 22  
 import org.kuali.rice.kew.docsearch.*;
 23  
 import org.kuali.rice.kew.docsearch.service.DocumentSearchService;
 24  
 import org.kuali.rice.kew.doctype.bo.DocumentType;
 25  
 import org.kuali.rice.kew.exception.WorkflowServiceError;
 26  
 import org.kuali.rice.kew.exception.WorkflowServiceErrorException;
 27  
 import org.kuali.rice.kew.lookup.valuefinder.SavedSearchValuesFinder;
 28  
 import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
 29  
 import org.kuali.rice.kew.service.KEWServiceLocator;
 30  
 import org.kuali.rice.kew.util.KEWConstants;
 31  
 import org.kuali.rice.kew.util.KEWPropertyConstants;
 32  
 import org.kuali.rice.kew.web.KeyValueSort;
 33  
 import org.kuali.rice.kim.bo.Person;
 34  
 import org.kuali.rice.kns.authorization.BusinessObjectRestrictions;
 35  
 import org.kuali.rice.kns.bo.BusinessObject;
 36  
 import org.kuali.rice.kns.datadictionary.BusinessObjectEntry;
 37  
 import org.kuali.rice.kns.exception.ValidationException;
 38  
 import org.kuali.rice.kns.lookup.HtmlData;
 39  
 import org.kuali.rice.kns.lookup.HtmlData.AnchorHtmlData;
 40  
 import org.kuali.rice.kns.lookup.KualiLookupableHelperServiceImpl;
 41  
 import org.kuali.rice.kns.service.DateTimeService;
 42  
 import org.kuali.rice.kns.service.KNSServiceLocator;
 43  
 import org.kuali.rice.kns.util.*;
 44  
 import org.kuali.rice.kns.web.comparator.CellComparatorHelper;
 45  
 import org.kuali.rice.kns.web.format.*;
 46  
 import org.kuali.rice.kns.web.format.Formatter;
 47  
 import org.kuali.rice.kns.web.struts.form.LookupForm;
 48  
 import org.kuali.rice.kns.web.ui.Column;
 49  
 import org.kuali.rice.kns.web.ui.Field;
 50  
 import org.kuali.rice.kns.web.ui.ResultRow;
 51  
 import org.kuali.rice.kns.web.ui.Row;
 52  
 
 53  
 import java.lang.reflect.InvocationTargetException;
 54  
 import java.math.BigDecimal;
 55  
 import java.sql.Date;
 56  
 import java.sql.Timestamp;
 57  
 import java.util.*;
 58  
 import java.util.regex.Matcher;
 59  
 import java.util.regex.Pattern;
 60  
 
 61  
 /**
 62  
  * Lookupable helper class for new doc search
 63  
  * @author Kuali Rice Team (rice.collab@kuali.org)
 64  
  *
 65  
  */
 66  0
 public class DocSearchCriteriaDTOLookupableHelperServiceImpl extends
 67  
 KualiLookupableHelperServiceImpl {
 68  
 
 69  
         private static final long serialVersionUID = -5162419674659967408L;
 70  
         DateTimeService dateTimeService;
 71  
         DocumentLookupCriteriaProcessor processor;
 72  0
         boolean savedSearch = false;
 73  0
         private static final Pattern HREF_PATTERN = Pattern.compile("<a href=\"([^\"]+)\"");
 74  
 
 75  
         /**
 76  
          * @see org.kuali.rice.kew.bo.lookup.DocumentRouteHeaderValueLookupableHelperService#setDateTimeService(org.kuali.rice.kns.service.DateTimeService)
 77  
          */
 78  
         public void setDateTimeService(DateTimeService dateTimeService) {
 79  0
                 this.dateTimeService = dateTimeService;
 80  0
         }
 81  
 
 82  
         /**
 83  
          * @see org.kuali.rice.kns.lookup.AbstractLookupableHelperServiceImpl#performLookup(org.kuali.rice.kns.web.struts.form.LookupForm, java.util.Collection, boolean)
 84  
          */
 85  
         @Override
 86  
         public Collection performLookup(LookupForm lookupForm,
 87  
                         Collection resultTable, boolean bounded) {
 88  
 
 89  
                 //TODO: ideally implement KNS updates to make this not require code from the parent
 90  
 
 91  0
             Map<String,String[]> parameters = this.getParameters();
 92  
 
 93  0
             DocSearchCriteriaDTO criteria = null;
 94  0
             if(savedSearch) {
 95  
                     //TODO: set the criteria on this from below method instead of this (so we're not calling out twice for the same object)
 96  0
                     DocumentSearchService docSearchService = KEWServiceLocator.getDocumentSearchService();
 97  
 
 98  0
                     String savedSearchName = ((String[])getParameters().get("savedSearchName"))[0];
 99  0
                     SavedSearchResult savedSearchResult = null;
 100  0
                     if(StringUtils.isNotEmpty(savedSearchName)) {
 101  0
                             savedSearchResult = docSearchService.getSavedSearchResults(GlobalVariables.getUserSession().getPrincipalId(), savedSearchName);
 102  
                     }
 103  0
                     if(savedSearchResult!=null){
 104  0
                             criteria = savedSearchResult.getDocSearchCriteriaDTO();
 105  
                     }
 106  0
                     savedSearch=false;
 107  0
             } else {
 108  0
                     Map<String,String[]> fixedParameters = new HashMap<String,String[]>();
 109  0
                     Map<String,String> changedDateFields = preprocessDateFields(lookupForm.getFieldsForLookup());
 110  0
                     fixedParameters.putAll(this.getParameters());
 111  0
                     for (Map.Entry<String,String> prop : changedDateFields.entrySet()) {
 112  0
                                 fixedParameters.remove(prop.getKey());
 113  0
                             fixedParameters.put(prop.getKey(), new String[]{prop.getValue()});
 114  
                         }
 115  0
                     criteria = DocumentLookupCriteriaBuilder.populateCriteria(fixedParameters);
 116  
 
 117  
             }
 118  
 
 119  0
             Collection<DocumentSearchResult> displayList=null;
 120  
 
 121  0
             DocumentSearchResultComponents components = null;
 122  
             try {
 123  0
                     components = KEWServiceLocator.getDocumentSearchService().getList(GlobalVariables.getUserSession().getPrincipalId(), criteria);
 124  0
             } catch (WorkflowServiceErrorException wsee) {
 125  0
                     for (WorkflowServiceError workflowServiceError : (List<WorkflowServiceError>)wsee.getServiceErrors()) {
 126  0
                                 if(workflowServiceError.getMessageMap() != null && workflowServiceError.getMessageMap().hasErrors()){
 127  
                                         // merge the message maps
 128  0
                                         GlobalVariables.getMessageMap().merge(workflowServiceError.getMessageMap());
 129  
                                 }else{
 130  
                                         //TODO: can we add something to this to get it to highlight the right field too?  Maybe in arg1
 131  0
                                         GlobalVariables.getMessageMap().putError(workflowServiceError.getMessage(), RiceKeyConstants.ERROR_CUSTOM, workflowServiceError.getMessage());
 132  
                                 }
 133  
                     };
 134  0
             }
 135  
 
 136  0
             if(!GlobalVariables.getMessageMap().hasNoErrors()) {
 137  0
                 throw new ValidationException("error with doc search");
 138  
         }
 139  
 
 140  
             // check various warning conditions
 141  
 
 142  0
             if (criteria.isOverThreshold() && criteria.getSecurityFilteredRows() > 0) {
 143  0
                 GlobalVariables.getMessageMap().putWarning(KNSConstants.GLOBAL_MESSAGES, "docsearch.DocumentSearchService.exceededThresholdAndSecurityFiltered", String.valueOf(components.getSearchResults().size()), String.valueOf(criteria.getSecurityFilteredRows()));
 144  0
             } else if (criteria.getSecurityFilteredRows() > 0) {
 145  0
                 GlobalVariables.getMessageMap().putWarning(KNSConstants.GLOBAL_MESSAGES, "docsearch.DocumentSearchService.securityFiltered", String.valueOf(criteria.getSecurityFilteredRows()));
 146  0
             } else if (criteria.isOverThreshold()) {
 147  0
                     GlobalVariables.getMessageMap().putWarning(KNSConstants.GLOBAL_MESSAGES,"docsearch.DocumentSearchService.exceededThreshold", String.valueOf(components.getSearchResults().size()));
 148  
             }
 149  
 
 150  0
             for (Row row : this.getRows()) {
 151  0
                         for (Field field : row.getFields()) {
 152  0
                                 if(StringUtils.equals(field.getPropertyName(),"fromDateCreated") && StringUtils.isEmpty(field.getPropertyValue())) {
 153  0
                                         field.setPropertyValue(criteria.getFromDateCreated());
 154  
                                 }
 155  
                         }
 156  
                 }
 157  
 
 158  0
             List<DocumentSearchResult> result = components.getSearchResults();
 159  
 //            for (DocumentSearchResult documentSearchResult : result) {
 160  0
                         displayList = result;//.getResultContainers();
 161  
 //                }
 162  
 
 163  
                 //####BEGIN COPIED CODE#########
 164  0
         setBackLocation((String) lookupForm.getFieldsForLookup().get(KNSConstants.BACK_LOCATION));
 165  0
         setDocFormKey((String) lookupForm.getFieldsForLookup().get(KNSConstants.DOC_FORM_KEY));
 166  
 
 167  
 //###COMENTED OUT
 168  
 //                  Collection displayList;
 169  
 //        // call search method to get results
 170  
 //        if (bounded) {
 171  
 //            displayList = getSearchResults(lookupForm.getFieldsForLookup());
 172  
 //        }
 173  
 //        else {
 174  
 //            displayList = getSearchResultsUnbounded(lookupForm.getFieldsForLookup());
 175  
 //        }
 176  
 //##COMENTED OUT
 177  
 
 178  0
         HashMap<String,Class> propertyTypes = new HashMap<String, Class>();
 179  
 
 180  0
         boolean hasReturnableRow = false;
 181  
 
 182  0
         List returnKeys = getReturnKeys();
 183  0
         List pkNames = getBusinessObjectMetaDataService().listPrimaryKeyFieldNames(getBusinessObjectClass());
 184  0
         Person user = GlobalVariables.getUserSession().getPerson();
 185  
 
 186  
         // iterate through result list and wrap rows with return url and action urls
 187  
 
 188  
 //COMMENTING THIS OUT FOR NOW
 189  
 //        for (Iterator iter = displayList.iterator(); iter.hasNext();) {
 190  
 //            BusinessObject element = (BusinessObject) iter.next();
 191  
 //                if(element instanceof PersistableBusinessObject){
 192  
 //                lookupForm.setLookupObjectId(((PersistableBusinessObject)element).getObjectId());
 193  
 //            }
 194  0
         DocumentRouteHeaderEBO element = new DocSearchCriteriaDTO();
 195  
         //TODO: additional BORestrictions through generator or component to lock down per document?
 196  0
             BusinessObjectRestrictions businessObjectRestrictions = getBusinessObjectAuthorizationService().getLookupResultRestrictions(element, user);
 197  
 
 198  
 //          String actionUrls = getActionUrls(element, pkNames, businessObjectRestrictions);
 199  
 //ADDED (4 lines)
 200  0
         for (Iterator<DocumentSearchResult> iter = result.iterator(); iter.hasNext();) {
 201  
 
 202  
 
 203  
 
 204  
 
 205  
 
 206  0
                 DocumentSearchResult docSearchResult = (DocumentSearchResult)iter.next();
 207  
 //TODO: where to get these from?
 208  
 //                HtmlData returnUrl = new AnchorHtmlData();
 209  0
                 String actionUrls = "";
 210  
 
 211  
 //ADDED (3)
 212  0
             List<? extends Column> origColumns = components.getColumns();//getColumns();
 213  0
             List<Column> newColumns = new ArrayList<Column>();
 214  0
             List<KeyValueSort> keyValues = docSearchResult.getResultContainers();
 215  0
             for (int i = 0; i < origColumns.size(); i++) {
 216  
 
 217  
 //            for (Iterator iterator = columns.iterator(); iterator.hasNext();) {
 218  
 
 219  
 //                Column col = (Column) iterator.next();
 220  
 //ADDED 3
 221  0
                       Column col = (Column) origColumns.get(i);
 222  0
                       KeyValueSort keyValue = null;
 223  0
                       for (KeyValueSort keyValueFromList : keyValues) {
 224  0
                               if(StringUtils.equals(col.getPropertyName(), keyValueFromList.getkey())) {
 225  0
                                       keyValue = keyValueFromList;
 226  0
                                       break;
 227  
                               }
 228  
                       }
 229  0
                       if(keyValue==null) {
 230  
                               //means we didn't find an indexed value for this, this seems bad but happens a lot we should research why
 231  0
                               keyValue = new KeyValueSort();
 232  
 //                              System.out.println("column: "+col.getPropertyName()+"has an empty KeyValue, this should never happen");
 233  
                       }
 234  
 
 235  
                       //Set values from keyvalue on column
 236  0
                       col.setPropertyValue(keyValue.getUserDisplayValue());
 237  
 
 238  0
                       String propertyName = col.getPropertyName();
 239  0
                                 if(StringUtils.isEmpty(col.getColumnTitle())) {
 240  
                               String labelMessageKey;
 241  0
                               if(StringUtils.equals(propertyName,KEWPropertyConstants.DOC_SEARCH_RESULT_PROPERTY_NAME_ROUTE_LOG)) {
 242  
                                       //TODO: find a better place for this
 243  0
                                       labelMessageKey = "Route Log";
 244  
                               } else {
 245  
                                       //TODO: change this to an enum (or another dd property)
 246  0
                                       propertyName=(StringUtils.equals(propertyName,"docTypeLabel"))?"docTypeFullName":propertyName;
 247  0
                                       propertyName=(StringUtils.equals(propertyName,"docRouteStatusCodeDesc"))?"docRouteStatus":propertyName;
 248  0
                                       propertyName=(StringUtils.equals(propertyName,"documentTitle"))?"docTitle":propertyName;
 249  0
                                       labelMessageKey = getDataDictionaryService().getAttributeLabel(DocSearchCriteriaDTO.class,propertyName);
 250  
                               }
 251  0
                               col.setColumnTitle(labelMessageKey);
 252  
                       }
 253  
 
 254  0
                                 if(StringUtils.equals(propertyName, KEWPropertyConstants.DOC_SEARCH_RESULT_PROPERTY_NAME_ROUTE_HEADER_ID)) {
 255  0
                                         ((DocSearchCriteriaDTO)element).setRouteHeaderId(col.getPropertyValue());
 256  
                                 }
 257  
 
 258  0
                     Formatter formatter = col.getFormatter();
 259  
 
 260  
                 // pick off result column from result list, do formatting
 261  0
                 String propValue = KNSConstants.EMPTY_STRING;
 262  
 //                Object prop = ObjectUtils.getPropertyValue(element, col.getPropertyName());
 263  
 //ADDED
 264  0
                 Object prop=keyValue.getSortValue();
 265  
 
 266  
                 // set comparator and formatter based on property type
 267  0
                 Class propClass = propertyTypes.get(propertyName);
 268  0
                 if ( propClass == null ) {
 269  
                     try {
 270  
                             //ADDED 3
 271  0
                             if(prop!=null) {
 272  0
                                     propertyTypes.put(propertyName, prop.getClass());
 273  0
                                     propClass = prop.getClass();
 274  
                             }
 275  
 
 276  
                             //propClass = ObjectUtils.getPropertyType( element, col.getPropertyName(), getPersistenceStructureService() );
 277  
 //                            propertyTypes.put( col.getPropertyName(), propClass );
 278  0
                     } catch (Exception e) {
 279  
 //                        throw new RuntimeException("Cannot access PropertyType for property " + "'" + col.getPropertyName() + "' " + " on an instance of '" + element.getClass().getName() + "'.", e);
 280  0
                     }
 281  
                 }
 282  
 
 283  
 
 284  
                 //TODO: check exisiting formatter here, ideally we should be getting this formatter from col.getFormatter in most cases
 285  
                 // formatters
 286  0
                 if (prop != null) {
 287  0
                     if (formatter == null) {
 288  
                         // for Booleans, always use BooleanFormatter
 289  0
                         if (prop instanceof Boolean) {
 290  0
                             formatter = new BooleanFormatter();
 291  
                         }
 292  
 
 293  
                         // for Dates, always use DateFormatter
 294  0
                         if (prop instanceof Date) {
 295  0
                             formatter = new DateFormatter();
 296  
                         }
 297  
                         //#ADDED 3
 298  0
                         if (prop instanceof Timestamp) {
 299  0
                             formatter = new TimestampAMPMFormatter();
 300  
                         }
 301  
 
 302  
                         // for collection, use the list formatter if a formatter hasn't been defined yet
 303  0
                         if (prop instanceof Collection && formatter == null) {
 304  0
                             formatter = new CollectionFormatter();
 305  
                         }
 306  
                     }
 307  0
                     if (formatter != null) {
 308  
                         //hack for Currency values as big decimal
 309  0
                         if (prop instanceof BigDecimal  && formatter.getImplementationClass().equals("org.kuali.rice.kns.web.format.CurrencyFormatter")) {
 310  0
                             prop = new KualiDecimal((BigDecimal)prop);
 311  0
                         } else if (prop instanceof BigDecimal  && formatter.getImplementationClass().equals("org.kuali.rice.kns.web.format.PercentageFormatter")) {
 312  0
                             prop = new KualiPercent((BigDecimal)prop);
 313  
                         }
 314  0
                          propValue = (String) formatter.format(prop);
 315  
                     }
 316  
                     else {
 317  0
                         propValue = prop.toString();
 318  
                     }
 319  
                 }
 320  
 
 321  
                 // comparator
 322  0
                 col.setComparator(CellComparatorHelper.getAppropriateComparatorForPropertyClass(propClass));
 323  0
                 col.setValueComparator(CellComparatorHelper.getAppropriateValueComparatorForPropertyClass(propClass));
 324  
 
 325  
                 //TODO: can we call into a method in the result processor to get this (or set something on the criteria)
 326  
 //                propValue = maskValueIfNecessary(element.getClass(), col.getPropertyName(), propValue, businessObjectRestrictions);
 327  
 
 328  0
                 col.setPropertyValue(propValue);
 329  
 
 330  0
                 if (StringUtils.isNotBlank(propValue)) {
 331  
 //                    col.setColumnAnchor(getInquiryUrl(element, col.getPropertyName()));
 332  
 //ADDED (3 lines)
 333  0
                         AnchorHtmlData anchor = new AnchorHtmlData(KNSConstants.EMPTY_STRING, KNSConstants.EMPTY_STRING);
 334  
                         //TODO: change to grab URL from config variable
 335  0
                         if(StringUtils.isNotEmpty(keyValue.getValue()) && StringUtils.equals("routeHeaderId", keyValue.getkey())) {
 336  0
                             String target = StringUtils.substringBetween(keyValue.getValue(), "target=\"", "\"");
 337  0
                             if (target == null) {
 338  0
                                 target = "_self";
 339  
                             }
 340  0
                             anchor.setTarget(target.trim());
 341  0
                                 if(!DocSearchCriteriaDTO.SUPER_USER_SEARCH_INDICATOR_STRING.equals(criteria.getSuperUserSearch())) {
 342  0
                                         anchor.setHref(".."+KEWConstants.WEBAPP_DIRECTORY+"/"+StringUtils.substringBetween(keyValue.getValue(), "<a href=\"", "docId=")+"docId="+keyValue.getUserDisplayValue());
 343  
                                 } else {
 344  
                                         // KULRICE-3035: Append the doc search's returnLocation parameter to the superuser page URL.
 345  0
                                                     String returnLoc = "";
 346  0
                                                     if (this.getParameters().containsKey(KNSConstants.RETURN_LOCATION_PARAMETER)) {
 347  0
                                                             returnLoc = (new StringBuilder()).append("&").append(KNSConstants.RETURN_LOCATION_PARAMETER).append("=").append(
 348  
                                                                             ((String[])this.getParameters().get(KNSConstants.RETURN_LOCATION_PARAMETER))[0]).toString();
 349  
                                                     }
 350  0
                                                     else if (StringUtils.isNotBlank(this.getBackLocation())) {
 351  0
                                                             returnLoc = (new StringBuilder()).append("&").append(KNSConstants.RETURN_LOCATION_PARAMETER).append("=").append(
 352  
                                                                             this.getBackLocation()).toString();
 353  
                                                     }
 354  
 
 355  0
                                         anchor.setHref(".."+KEWConstants.WEBAPP_DIRECTORY+"/"+StringUtils.substringBetween(keyValue.getValue(), "<a href=\"", "routeHeaderId=")+"routeHeaderId="+keyValue.getUserDisplayValue() + returnLoc);
 356  
                                 }
 357  0
                         col.setMaxLength(100); //for now force this
 358  0
                         } else if(StringUtils.isNotEmpty(keyValue.getvalue()) && StringUtils.equals(KEWPropertyConstants.DOC_SEARCH_RESULT_PROPERTY_NAME_ROUTE_LOG, keyValue.getkey())) {
 359  0
                                 Matcher hrefMatcher = HREF_PATTERN.matcher(keyValue.getValue());
 360  0
                                 String matchedURL = "";
 361  0
                                 if (hrefMatcher.find()) {
 362  0
                                         matchedURL = hrefMatcher.group(1);
 363  
                                 }
 364  0
                                 anchor.setHref(".."+KEWConstants.WEBAPP_DIRECTORY+"/"+matchedURL);
 365  0
                                 String target = StringUtils.substringBetween(keyValue.getValue(), "target=\"", "\"");
 366  0
                         if (target == null) {
 367  0
                             target = "_self";
 368  
                         }
 369  0
                         anchor.setTarget(target.trim());
 370  0
                                 col.setMaxLength(100); //for now force this
 371  0
                         keyValue.setvalue(keyValue.getUserDisplayValue());
 372  0
                         col.setEscapeXMLValue(false);
 373  0
                         } else if (StringUtils.isNotEmpty(keyValue.getvalue()) && StringUtils.equals(KEWPropertyConstants.DOC_SEARCH_RESULT_PROPERTY_NAME_INITIATOR, keyValue.getkey())) {
 374  0
                                 anchor.setHref(StringUtils.substringBetween(keyValue.getValue(), "<a href=\"", "\" target=\"_blank\""));
 375  0
                                 col.setMaxLength(100); //for now force this
 376  
                         }
 377  
 
 378  0
                         col.setColumnAnchor(anchor);
 379  
 
 380  
                 }
 381  0
                 Column newCol = (Column)ObjectUtils.deepCopy(col);
 382  0
                 newColumns.add(newCol);
 383  
 
 384  
             }
 385  
 
 386  0
             HtmlData returnUrl = getReturnUrl(element, lookupForm, returnKeys, businessObjectRestrictions);
 387  0
             ResultRow row = new ResultRow(newColumns, returnUrl.constructCompleteHtmlTag(), actionUrls);
 388  0
             row.setRowId(returnUrl.getName());
 389  
             // because of concerns of the BO being cached in session on the ResultRow,
 390  
             // let's only attach it when needed (currently in the case of export)
 391  0
             if (getBusinessObjectDictionaryService().isExportable(getBusinessObjectClass())) {
 392  
                     //                    row.setBusinessObject(element);
 393  
             }
 394  
 
 395  
             //            boolean rowReturnable = isResultReturnable(element);
 396  
             //ADDED
 397  0
             boolean rowReturnable = true;
 398  0
             row.setRowReturnable(rowReturnable);
 399  0
             if (rowReturnable) {
 400  0
                     hasReturnableRow = true;
 401  
             }
 402  0
             resultTable.add(row);
 403  0
         }
 404  
 
 405  
 
 406  0
         lookupForm.setHasReturnableRow(hasReturnableRow);
 407  
 
 408  0
         return displayList;
 409  
                 //####END COPIED CODE#########
 410  
         }
 411  
 
 412  
 
 413  
 
 414  
 
 415  
 
 416  
         /**
 417  
          * @see org.kuali.rice.kns.lookup.AbstractLookupableHelperServiceImpl#getInquiryUrl(org.kuali.rice.kns.bo.BusinessObject, java.lang.String)
 418  
          */
 419  
         @Override
 420  
         public HtmlData getInquiryUrl(BusinessObject bo, String propertyName) {
 421  
                 //FIXME: ctk - make sure and check that it's ok to do this here.  I may move this out to the doc search processor
 422  0
                 if(KEWPropertyConstants.DOC_SEARCH_RESULT_PROPERTY_NAME_ROUTE_HEADER_ID.equals(propertyName)) {
 423  
 
 424  0
                         AnchorHtmlData link = new AnchorHtmlData();
 425  0
                         DocumentRouteHeaderValue doc = (DocumentRouteHeaderValue)bo;
 426  
                         //if !superuser
 427  0
                         Long routeHeaderId = doc.getRouteHeaderId();
 428  0
                         link.setDisplayText(routeHeaderId+"");
 429  
 
 430  0
                         String href = ConfigContext.getCurrentContextConfig().getKRBaseURL()+"/"+ KEWConstants.APP_CODE + "/" +
 431  
                         KEWConstants.DOC_HANDLER_REDIRECT_PAGE + "?" + KEWConstants.COMMAND_PARAMETER + "=" +
 432  
                         KEWConstants.DOCSEARCH_COMMAND + "&" + KEWConstants.ROUTEHEADER_ID_PARAMETER + "=" + routeHeaderId;
 433  
 
 434  0
                         link.setHref(href);
 435  
 
 436  0
                         return link;
 437  
                 }
 438  
 
 439  0
                 return super.getInquiryUrl(bo, propertyName);
 440  
         }
 441  
 
 442  
 
 443  
         /**
 444  
          * @see org.kuali.rice.kns.lookup.AbstractLookupableHelperServiceImpl#setRows()
 445  
          */
 446  
         @Override
 447  
         protected void setRows() {
 448  0
             this.setRows(new HashMap<String,String[]>(), null);
 449  0
         }
 450  
 
 451  
 
 452  
         /**
 453  
          * @see org.kuali.rice.kns.lookup.AbstractLookupableHelperServiceImpl#setRows()
 454  
          */
 455  
         protected void setRows(Map fieldValues, String docTypeName) {
 456  
                 // TODO chris - this method should call the criteria processor adapter which will
 457  
                 //call the criteria processor (either standard or custom) and massage the data into the proper format
 458  
                 //this is called by setbo in super(which is called by form) so should be called when the page needs refreshing
 459  
 
 460  
                 //TODO: move over code that checks for doctype (actually should that be in the refresh, since that's where the doc type will be coming back to?)
 461  
 
 462  
 
 463  
                 //###START LOOKUP ROW CODE Not sure if we need these but they may be valuable for eventually forcing all standard field customization in the xml
 464  0
                 if (getRows() == null) {
 465  0
                     super.setRows();
 466  
                 }
 467  0
                 List<Row> lookupRows = new ArrayList<Row>();
 468  
                 //copy the current rows
 469  0
                 for (Row row : getRows()) {
 470  0
                         lookupRows.add(row);
 471  
                 }
 472  
                 //clear out
 473  0
                 getRows().clear();
 474  
 
 475  0
         processor = new DocumentLookupCriteriaProcessorKEWAdapter();
 476  
 
 477  
 
 478  0
                 DocumentType docType = null;
 479  
 
 480  0
                 if(StringUtils.isNotEmpty(docTypeName)) {
 481  0
                         docType = getValidDocumentType((String)docTypeName);
 482  
                 }
 483  
 
 484  0
                 DocumentLookupCriteriaProcessorKEWAdapter documentLookupCriteriaProcessorKEWAdapter = (DocumentLookupCriteriaProcessorKEWAdapter)processor;
 485  0
                 if(processor != null && documentLookupCriteriaProcessorKEWAdapter.getCriteriaProcessor()!=null) {
 486  0
                         if(docType==null) {
 487  0
                                 documentLookupCriteriaProcessorKEWAdapter.setCriteriaProcessor(new StandardDocumentSearchCriteriaProcessor());
 488  0
                         } else if(!StringUtils.equals(docTypeName, documentLookupCriteriaProcessorKEWAdapter.getCriteriaProcessor().getDocSearchCriteriaDTO().getDocTypeFullName())){
 489  0
                                 documentLookupCriteriaProcessorKEWAdapter.setCriteriaProcessor(docType.getDocumentSearchCriteriaProcessor());
 490  
                         }
 491  
                 } else {
 492  0
                         if(docType==null) {
 493  0
                                 documentLookupCriteriaProcessorKEWAdapter.setCriteriaProcessor(new StandardDocumentSearchCriteriaProcessor());
 494  
                         } else {
 495  0
                                 documentLookupCriteriaProcessorKEWAdapter.setCriteriaProcessor(docType.getDocumentSearchCriteriaProcessor());
 496  
                         }
 497  
                 }
 498  
                 //TODO: This should probably be moved into spring injection since it's a constant
 499  0
                 documentLookupCriteriaProcessorKEWAdapter.setDataDictionaryService(getDataDictionaryService());
 500  
 
 501  0
                 boolean detailed=false;
 502  0
                 if(this.getParameters().containsKey("isAdvancedSearch")) {
 503  0
                         detailed = DocSearchCriteriaDTO.ADVANCED_SEARCH_INDICATOR_STRING.equalsIgnoreCase(((String[])this.getParameters().get("isAdvancedSearch"))[0]);
 504  0
                 } else if(fieldValues.containsKey("isAdvancedSearch")) {
 505  0
                         detailed = DocSearchCriteriaDTO.ADVANCED_SEARCH_INDICATOR_STRING.equalsIgnoreCase((String) fieldValues.get("isAdvancedSearch"));
 506  
                 }
 507  
 
 508  0
                 boolean superSearch=false;
 509  0
                 if(this.getParameters().containsKey(("superUserSearch"))) {
 510  0
                         superSearch = DocSearchCriteriaDTO.SUPER_USER_SEARCH_INDICATOR_STRING.equalsIgnoreCase(((String[])this.getParameters().get("superUserSearch"))[0]);
 511  0
                 } else if(fieldValues.containsKey("superUserSearch")) {
 512  0
                         superSearch = DocSearchCriteriaDTO.SUPER_USER_SEARCH_INDICATOR_STRING.equalsIgnoreCase((String)fieldValues.get("superUserSearch"));
 513  
                 }
 514  
 
 515  
                 //call get rows
 516  0
                 List<Row> rows = processor.getRows(docType,lookupRows, detailed, superSearch);
 517  
 
 518  0
                 BusinessObjectEntry boe = KNSServiceLocator.getDataDictionaryService().getDataDictionary().getBusinessObjectEntry(this.getBusinessObjectClass().getName());
 519  0
         int numCols = boe.getLookupDefinition().getNumOfColumns();
 520  0
         if(numCols == 0) numCols = KNSConstants.DEFAULT_NUM_OF_COLUMNS;
 521  
 
 522  0
                 super.getRows().addAll(FieldUtils.wrapFields(this.getFields(rows),numCols ));
 523  
 
 524  0
         }
 525  
 
 526  
          private List<Field> getFields(List<Row> rows){
 527  0
                     List<Field> rList = new ArrayList<Field>();
 528  
 
 529  0
                     for(Row r: rows){
 530  0
                             for(Field f: r.getFields()){
 531  0
                                     rList.add(f);
 532  
                             }
 533  
                     }
 534  
 
 535  0
                     return rList;
 536  
             }
 537  
 
 538  
            private void setRowsAfterClear(DocSearchCriteriaDTO searchCriteria, Map<String,String[]> fieldValues) {
 539  
                 // TODO chris - this method should call the criteria processor adapter which will
 540  
                 //call the criteria processor (either standard or custom) and massage the data into the proper format
 541  
                 //this is called by setbo in super(which is called by form) so should be called when the page needs refreshing
 542  
 
 543  
                 //TODO: move over code that checks for doctype (actually should that be in the refresh, since that's where the doc type will be coming back to?)
 544  0
                if (getRows() == null) {
 545  0
                     super.setRows();
 546  
                 }
 547  0
                List<Row> lookupRows = new ArrayList<Row>();
 548  
                 //copy the current rows
 549  0
                 for (Row row : getRows()) {
 550  0
                     lookupRows.add(row);
 551  
                 }
 552  0
                 super.getRows().clear();
 553  
 
 554  0
                 processor = new DocumentLookupCriteriaProcessorKEWAdapter();
 555  
 
 556  0
                 String docTypeName = searchCriteria.getDocTypeFullName();
 557  0
                 DocumentType docType = null;
 558  
 
 559  0
                 if(StringUtils.isNotEmpty(docTypeName)) {
 560  0
                     docType = getValidDocumentType(docTypeName);
 561  
                 }
 562  
 
 563  0
                 DocumentLookupCriteriaProcessorKEWAdapter documentLookupCriteriaProcessorKEWAdapter = (DocumentLookupCriteriaProcessorKEWAdapter)processor;
 564  0
                 if(processor != null && documentLookupCriteriaProcessorKEWAdapter.getCriteriaProcessor()!=null) {
 565  0
                     if(docType==null) {
 566  0
                         documentLookupCriteriaProcessorKEWAdapter.setCriteriaProcessor(new StandardDocumentSearchCriteriaProcessor());
 567  0
                     } else if(!StringUtils.equals(docTypeName, documentLookupCriteriaProcessorKEWAdapter.getCriteriaProcessor().getDocSearchCriteriaDTO().getDocTypeFullName())){
 568  0
                         documentLookupCriteriaProcessorKEWAdapter.setCriteriaProcessor(docType.getDocumentSearchCriteriaProcessor());
 569  
                     }
 570  
                 } else {
 571  0
                     if(docType==null) {
 572  0
                         documentLookupCriteriaProcessorKEWAdapter.setCriteriaProcessor(new StandardDocumentSearchCriteriaProcessor());
 573  
                     } else {
 574  0
                         documentLookupCriteriaProcessorKEWAdapter.setCriteriaProcessor(docType.getDocumentSearchCriteriaProcessor());
 575  
                     }
 576  
                 }
 577  
                 //TODO: This should probably be moved into spring injection since it's a constant
 578  0
                 documentLookupCriteriaProcessorKEWAdapter.setDataDictionaryService(getDataDictionaryService());
 579  
 
 580  0
                 boolean detailed=false;
 581  0
                 if(this.getParameters().containsKey("isAdvancedSearch")) {
 582  0
                     detailed = DocSearchCriteriaDTO.ADVANCED_SEARCH_INDICATOR_STRING.equalsIgnoreCase(((String[])this.getParameters().get("isAdvancedSearch"))[0]);
 583  0
                 } else if(fieldValues.containsKey("isAdvancedSearch")) {
 584  0
                     detailed = DocSearchCriteriaDTO.ADVANCED_SEARCH_INDICATOR_STRING.equalsIgnoreCase((String) fieldValues.get("isAdvancedSearch")[0]);
 585  
                 }
 586  
 
 587  0
                 boolean superSearch=false;
 588  0
                 if(this.getParameters().containsKey(("superUserSearch"))) {
 589  0
                     superSearch = DocSearchCriteriaDTO.SUPER_USER_SEARCH_INDICATOR_STRING.equalsIgnoreCase(((String[])this.getParameters().get("superUserSearch"))[0]);
 590  0
                 } else if(fieldValues.containsKey("superUserSearch")) {
 591  0
                     superSearch = DocSearchCriteriaDTO.SUPER_USER_SEARCH_INDICATOR_STRING.equalsIgnoreCase((String)fieldValues.get("superUserSearch")[0]);
 592  
                 }
 593  
                 //call get rows
 594  0
                 List<Row> rows = documentLookupCriteriaProcessorKEWAdapter.getRows(docType, super.getRows(), detailed, superSearch);
 595  
 
 596  0
                 super.getRows().addAll(rows);
 597  
 
 598  
                 //Set field values from DocSearchCriteria
 599  0
                 if(StringUtils.isNotEmpty(docTypeName)) {
 600  0
                     for (Row row : super.getRows()) {
 601  0
                         for (Field field : row.getFields()) {
 602  
                             //if from date, strip off prefix
 603  0
                             String propertyName = null;
 604  0
                             if(field.getPropertyName().startsWith(KNSConstants.LOOKUP_RANGE_LOWER_BOUND_PROPERTY_PREFIX)) {
 605  0
                                 propertyName = StringUtils.remove(field.getPropertyName(), KNSConstants.LOOKUP_RANGE_LOWER_BOUND_PROPERTY_PREFIX);
 606  
                             } else {
 607  0
                                 propertyName = field.getPropertyName();
 608  
                             }
 609  
                             //We don't need to set field if it was already empty
 610  0
                             if (fieldValues.get(propertyName) != null) {
 611  0
                                 Object value = this.getDocSearchCriteriaDTOFieldValue(searchCriteria, field.getPropertyName());
 612  0
                                 if (value instanceof String
 613  
                                         && StringUtils.isNotEmpty((String)value)) {
 614  0
                                     field.setPropertyValue(value);
 615  0
                                 } else if (value instanceof List){
 616  0
                                     field.setPropertyValues((String[])((List)value).toArray());
 617  
                                 }
 618  
                             }
 619  0
                         }
 620  
                     }
 621  
                 }
 622  0
             }
 623  
 
 624  
 
 625  
         /**
 626  
          * @see org.kuali.rice.kns.lookup.AbstractLookupableHelperServiceImpl#performClear()
 627  
          */
 628  
         @Override
 629  
         public void performClear(LookupForm lookupForm) {
 630  
                 //Map<String,String[]> fieldsToClear = new HashMap<String,String[]>();
 631  
 
 632  
                 //for (Row row : this.getRows()) {
 633  
                 //        for (Field field : row.getFields()) {
 634  
                 //                String[] propertyValue = {};
 635  
                 //                if(!Field.MULTI_VALUE_FIELD_TYPES.contains(field.getFieldType())) {
 636  
                 //                        propertyValue = new String[]{field.getPropertyValue()};
 637  
                 //                } else {
 638  
                 //                        propertyValue = field.getPropertyValues();
 639  
                 //                }
 640  
                 //                fieldsToClear.put(field.getPropertyName(), propertyValue);
 641  
                 //        }
 642  
                 //}
 643  
 
 644  0
             Map<String,String[]> fixedParameters = new HashMap<String,String[]>();
 645  0
         Map<String,String> changedDateFields = preprocessDateFields(lookupForm.getFieldsForLookup());
 646  0
         fixedParameters.putAll(this.getParameters());
 647  0
         for (Map.Entry<String,String> prop : changedDateFields.entrySet()) {
 648  0
             fixedParameters.remove(prop.getKey());
 649  0
             fixedParameters.put(prop.getKey(), new String[]{prop.getValue()});
 650  
         }
 651  
                 //TODO: also check if standard here (maybe from object if use criteria)
 652  0
                 String docTypeName = fixedParameters.get("docTypeFullName")[0];
 653  
 
 654  0
                 DocumentType docType = getValidDocumentType(docTypeName);
 655  
 
 656  0
                 if(docType == null) {
 657  0
                     super.performClear(lookupForm);
 658  
 
 659  
                     // Retrieve the detailed/superuser search statuses.
 660  0
                 boolean detailed=false;
 661  0
                 if(this.getParameters().containsKey("isAdvancedSearch")) {
 662  0
                     detailed = DocSearchCriteriaDTO.ADVANCED_SEARCH_INDICATOR_STRING.equalsIgnoreCase(((String[])this.getParameters().get("isAdvancedSearch"))[0]);
 663  0
                 } else if(fixedParameters.containsKey("isAdvancedSearch")) {
 664  0
                     detailed = DocSearchCriteriaDTO.ADVANCED_SEARCH_INDICATOR_STRING.equalsIgnoreCase((String) fixedParameters.get("isAdvancedSearch")[0]);
 665  
                 }
 666  
 
 667  0
                 boolean superSearch=false;
 668  0
                 if(this.getParameters().containsKey(("superUserSearch"))) {
 669  0
                     superSearch = DocSearchCriteriaDTO.SUPER_USER_SEARCH_INDICATOR_STRING.equalsIgnoreCase(((String[])this.getParameters().get("superUserSearch"))[0]);
 670  0
                 } else if(fixedParameters.containsKey("superUserSearch")) {
 671  0
                     superSearch = DocSearchCriteriaDTO.SUPER_USER_SEARCH_INDICATOR_STRING.equalsIgnoreCase((String) fixedParameters.get("superUserSearch")[0]);
 672  
                 }
 673  
 
 674  
                 // Repopulate the fields indicating detailed/superuser search status.
 675  0
                 int fieldsRepopulated = 0;
 676  0
                 List<Row> rows = super.getRows();
 677  0
                 int index = rows.size() - 1;
 678  0
                 while (index >= 0 && fieldsRepopulated < 2) {
 679  0
                         for (Field tempField : rows.get(index).getFields()) {
 680  0
                                 if ("isAdvancedSearch".equals(tempField.getPropertyName())) {
 681  0
                                         tempField.setPropertyValue(detailed?"YES":"NO");
 682  0
                                         fieldsRepopulated++;
 683  
                                 }
 684  0
                                 else if ("superUserSearch".equals(tempField.getPropertyName())) {
 685  0
                                         tempField.setPropertyValue(superSearch?"YES":"NO");
 686  0
                                         fieldsRepopulated++;
 687  
                                 }
 688  
                         }
 689  0
                         index--;
 690  
                 }
 691  0
                 } else {
 692  0
                     DocSearchCriteriaDTO docCriteria = DocumentLookupCriteriaBuilder.populateCriteria(fixedParameters);
 693  0
                     docCriteria = docType.getDocumentSearchGenerator().clearSearch(docCriteria);
 694  0
             if (docCriteria == null) {
 695  0
                 docCriteria = new DocSearchCriteriaDTO();
 696  
             }
 697  
 
 698  0
             this.setRowsAfterClear(docCriteria, fixedParameters);
 699  
                 }
 700  
 
 701  0
         }
 702  
         /**
 703  
          *
 704  
          * retrieve a document type. This is not a case sensitive search so "TravelRequest" == "Travelrequest"
 705  
          *
 706  
          * @param docTypeName
 707  
          * @return
 708  
          */
 709  
     private static DocumentType getValidDocumentType(String docTypeName) {
 710  0
             if (StringUtils.isNotEmpty(docTypeName)) {
 711  0
             DocumentType dTypeCriteria = new DocumentType();
 712  0
                     dTypeCriteria.setName(docTypeName.trim());
 713  0
                     dTypeCriteria.setActive(true);
 714  0
                     Collection<DocumentType> docTypeList = KEWServiceLocator.getDocumentTypeService().find(dTypeCriteria, null, false);
 715  
 
 716  
                     // Return the first valid doc type.
 717  0
                     DocumentType firstDocumentType = null;
 718  0
                     if(docTypeList != null){
 719  0
                             for(DocumentType dType: docTypeList){
 720  0
                                 if (firstDocumentType == null) {
 721  0
                                     firstDocumentType = dType;
 722  
                                 }
 723  0
                                 if (StringUtils.equals(docTypeName.toUpperCase(), dType.getName().toUpperCase())) {
 724  0
                                     return dType;
 725  
                                 }
 726  
                             }
 727  0
                             return firstDocumentType;
 728  
                     }
 729  
             }
 730  
 
 731  0
             return null;
 732  
     }
 733  
 
 734  
 
 735  
         /**
 736  
          * @see org.kuali.rice.kns.lookup.AbstractLookupableHelperServiceImpl#getSupplementalMenuBar()
 737  
          */
 738  
         @Override
 739  
         public String getSupplementalMenuBar() {
 740  0
                 boolean detailed = false;
 741  0
                 if(this.getParameters().containsKey("isAdvancedSearch")) {
 742  0
                         detailed = DocSearchCriteriaDTO.ADVANCED_SEARCH_INDICATOR_STRING.equalsIgnoreCase(((String[])this.getParameters().get("isAdvancedSearch"))[0]);
 743  
                 }
 744  
 
 745  0
                 boolean superSearch = false;
 746  0
                 if(this.getParameters().containsKey("superUserSearch")) {
 747  0
                         superSearch = DocSearchCriteriaDTO.SUPER_USER_SEARCH_INDICATOR_STRING.equalsIgnoreCase(((String[])this.getParameters().get("superUserSearch"))[0]);
 748  
                 }
 749  
 
 750  0
                 StringBuilder suppMenuBar = new StringBuilder();
 751  
 
 752  
                 // Add the detailed-search-toggling button.
 753  0
                 suppMenuBar.append("<input type=\"image\" name=\"methodToCall.customLookupableMethodCall.(((").append(detailed ? "NO" : DocSearchCriteriaDTO.ADVANCED_SEARCH_INDICATOR_STRING).append("))).((`").append(superSearch ? DocSearchCriteriaDTO.SUPER_USER_SEARCH_INDICATOR_STRING : "NO").append(
 754  
                                 "`))\" class=\"tinybutton\" src=\"..").append(KEWConstants.WEBAPP_DIRECTORY).append(detailed ? "/images/tinybutton-basicsearch.gif\" alt=\"basic search\" title=\"basic search\" />" : "/images/tinybutton-detailedsearch.gif\" alt=\"detailed search\" title=\"detailed search\" />");
 755  
 
 756  
                 // Add the superuser-search-toggling button.
 757  0
                 suppMenuBar.append("&nbsp;").append("<input type=\"image\" name=\"methodToCall.customLookupableMethodCall.(((").append((!detailed && superSearch) ? "NO" : DocSearchCriteriaDTO.ADVANCED_SEARCH_INDICATOR_STRING).append("))).((`").append(superSearch ? "NO" : DocSearchCriteriaDTO.SUPER_USER_SEARCH_INDICATOR_STRING).append(
 758  
                                 "`))\" class=\"tinybutton\" src=\"..").append(KEWConstants.WEBAPP_DIRECTORY).append(superSearch ? "/images/tinybutton-nonsupusearch.gif\" alt=\"non-superuser search\" title=\"non-superuser search\" />" : "/images/tinybutton-superusersearch.gif\" alt=\"superuser search\" title=\"superuser search\" />");
 759  
 
 760  
                 // Add the "clear saved searches" button.
 761  0
                 suppMenuBar.append("&nbsp;").append("<input type=\"image\" name=\"methodToCall.customLookupableMethodCall.(([true]))\" class=\"tinybutton\" src=\"..").append(KEWConstants.WEBAPP_DIRECTORY).append("/images/tinybutton-clearsavedsearch.gif\" alt=\"clear saved searches\" title=\"clear saved searches\" />");
 762  
 
 763  0
         Properties parameters = new Properties();
 764  0
         parameters.put(KNSConstants.BUSINESS_OBJECT_CLASS_ATTRIBUTE, this.getBusinessObjectClass().getName());
 765  0
         this.getParameters().keySet();
 766  0
         for (Object parameter : this.getParameters().keySet()) {
 767  0
                         parameters.put(parameter, this.getParameters().get(parameter));
 768  
                 }
 769  
 
 770  0
                 UrlFactory.parameterizeUrl(KNSConstants.LOOKUP_ACTION, parameters);
 771  0
                 return suppMenuBar.toString();
 772  
         }
 773  
 
 774  
 //    /**
 775  
 //     * This method is called by performLookup method to generate supplemental action urls.
 776  
 //     * It calls the method getCustomActionUrls to get html data, calls getMaintenanceUrl to get the actual html tag,
 777  
 //     * and returns a formatted/concatenated string of action urls.
 778  
 //     *
 779  
 //     * @see org.kuali.core.lookup.LookupableHelperService#getActionUrls(org.kuali.core.bo.BusinessObject)
 780  
 //     */
 781  
 //    public String getSupplementalActionUrls(List<HtmlData> htmlDataList) {
 782  
 //        StringBuffer actions = new StringBuffer();
 783  
 //
 784  
 //        for(HtmlData htmlData: htmlDataList){
 785  
 //                actions.append(getMaintenanceUrl(businessObject, htmlData, pkNames, businessObjectRestrictions));
 786  
 //            if(htmlData.getChildUrlDataList()!=null){
 787  
 //                    if(htmlData.getChildUrlDataList().size()>0){
 788  
 //                    actions.append(ACTION_URLS_CHILDREN_STARTER);
 789  
 //                            for(HtmlData childURLData: htmlData.getChildUrlDataList()){
 790  
 //                                actions.append(getMaintenanceUrl(businessObject, childURLData, pkNames, businessObjectRestrictions));
 791  
 //                            actions.append(ACTION_URLS_CHILDREN_SEPARATOR);
 792  
 //                            }
 793  
 //                            if(actions.toString().endsWith(ACTION_URLS_CHILDREN_SEPARATOR))
 794  
 //                                    actions.delete(actions.length()-ACTION_URLS_CHILDREN_SEPARATOR.length(), actions.length());
 795  
 //                    actions.append(ACTION_URLS_CHILDREN_END);
 796  
 //                    }
 797  
 //            }
 798  
 //                actions.append(ACTION_URLS_SEPARATOR);
 799  
 //        }
 800  
 //        if(actions.toString().endsWith(ACTION_URLS_SEPARATOR))
 801  
 //                actions.delete(actions.length()-ACTION_URLS_SEPARATOR.length(), actions.length());
 802  
 //        return actions.toString();
 803  
 //    }
 804  
 
 805  
         /**
 806  
          * @see org.kuali.rice.kns.lookup.AbstractLookupableHelperServiceImpl#shouldDisplayHeaderNonMaintActions()
 807  
          */
 808  
         @Override
 809  
         public boolean shouldDisplayHeaderNonMaintActions() {
 810  0
                 return this.processor.shouldDisplayHeaderNonMaintActions();
 811  
         }
 812  
 
 813  
 
 814  
         /**
 815  
          * @see org.kuali.rice.kns.lookup.AbstractLookupableHelperServiceImpl#shouldDisplayLookupCriteria()
 816  
          */
 817  
         @Override
 818  
         public boolean shouldDisplayLookupCriteria() {
 819  0
                 return this.processor.shouldDisplayLookupCriteria();
 820  
         }
 821  
 
 822  
 
 823  
         /**
 824  
          * @see org.kuali.rice.kns.lookup.AbstractLookupableHelperServiceImpl#checkForAdditionalFields(java.util.Map)
 825  
          */
 826  
         @Override
 827  
         public boolean checkForAdditionalFields(Map fieldValues) {
 828  
                 // TODO chris - THIS METHOD NEEDS JAVADOCS
 829  
 //                return super.checkForAdditionalFields(fieldValues);
 830  0
                 String docTypeName = null;
 831  0
                 if(this.getParameters().get("docTypeFullName")!=null) {
 832  0
                         docTypeName = ((String[])this.getParameters().get("docTypeFullName"))[0];
 833  
                 }
 834  0
                 else if(fieldValues.get("docTypeFullName")!=null) {
 835  0
                         docTypeName = (String)fieldValues.get("docTypeFullName");
 836  
                 }
 837  0
                 if(!StringUtils.isEmpty(docTypeName)) {
 838  0
                     DocumentType dType = getValidDocumentType(docTypeName);
 839  
 
 840  0
             DocSearchCriteriaDTO criteria = DocumentLookupCriteriaBuilder.populateCriteria(getParameters());
 841  0
             if (dType != null) {
 842  0
                     MessageMap messages = getValidDocumentType(dType.getName()).getDocumentSearchGenerator().getMessageMap(criteria);
 843  0
                     if (messages != null
 844  
                             && messages.hasMessages()) {
 845  0
                         GlobalVariables.mergeErrorMap(messages);
 846  
                     }
 847  0
                     setRows(fieldValues,dType.getName());
 848  0
                     return true;
 849  
             }
 850  
         }
 851  
 
 852  0
                 setRows(fieldValues, docTypeName);
 853  
 
 854  0
                 return true;
 855  
         }
 856  
 
 857  
         /**
 858  
          * @see org.kuali.rice.kns.lookup.AbstractLookupableHelperServiceImpl#validateSearchParameters(java.util.Map)
 859  
          */
 860  
         @Override
 861  
     public void validateSearchParameters(Map fieldValues) {
 862  0
         super.validateSearchParameters(fieldValues);
 863  0
         DocumentSearchService docSearchService = KEWServiceLocator.getDocumentSearchService();
 864  0
         DocSearchCriteriaDTO criteria = DocumentLookupCriteriaBuilder.populateCriteria(getParameters());
 865  0
         DocumentType docType = null;
 866  0
         if(StringUtils.isNotEmpty(criteria.getDocTypeFullName())) {
 867  0
                         docType = getValidDocumentType((String)criteria.getDocTypeFullName());
 868  
                 }
 869  0
         DocumentSearchGenerator generator=null;
 870  0
         if(docType!=null) {
 871  0
                 generator = docType.getDocumentSearchGenerator();
 872  
         } else {
 873  0
                 generator = KEWServiceLocator.getDocumentSearchService().getStandardDocumentSearchGenerator();
 874  
         }
 875  
         try {
 876  0
                 docSearchService.validateDocumentSearchCriteria(generator, criteria);
 877  0
                 } catch (WorkflowServiceErrorException wsee) {
 878  0
                         for (WorkflowServiceError workflowServiceError : (List<WorkflowServiceError>)wsee.getServiceErrors()) {
 879  0
                                 if(workflowServiceError.getMessageMap() != null && workflowServiceError.getMessageMap().hasErrors()){
 880  
                                         // merge the message maps
 881  0
                                         GlobalVariables.getMessageMap().merge(workflowServiceError.getMessageMap());
 882  
                                 }else{
 883  
                                         //TODO: can we add something to this to get it to highlight the right field too?  Maybe in arg1
 884  0
                                         GlobalVariables.getMessageMap().putError(workflowServiceError.getMessage(), RiceKeyConstants.ERROR_CUSTOM, workflowServiceError.getMessage());
 885  
                                 }
 886  
                         };
 887  0
                 }
 888  0
         if(!GlobalVariables.getMessageMap().hasNoErrors()) {
 889  0
                 throw new ValidationException("errors in search criteria");
 890  
         }
 891  
 
 892  0
     }
 893  
 
 894  
 
 895  
         /**
 896  
          * @see org.kuali.rice.kns.lookup.AbstractLookupableHelperServiceImpl#performCustomAction(boolean)
 897  
          */
 898  
         @Override
 899  
         public boolean performCustomAction(boolean ignoreErrors) {
 900  0
                 DocumentSearchService docSearchService = KEWServiceLocator.getDocumentSearchService();
 901  
 
 902  0
                 Map<String,String> fieldValues = new HashMap<String,String>();
 903  0
                 Map<String,String[]> multFieldValues = new HashMap<String,String[]>();
 904  
 
 905  
                 // Determine if there are any properties embedded in the methodToCall parameter, and retrieve them if so.
 906  0
                 String[] methodToCallArray = ((String[])this.getParameters().get(KNSConstants.DISPATCH_REQUEST_PARAMETER + ".customLookupableMethodCall"));
 907  0
                 if (methodToCallArray == null) {
 908  0
                     for (String parameter: new ArrayList<String>(this.getParameters().keySet())) {
 909  0
                         String[] parameterSplit = StringUtils.split(parameter, ".");
 910  0
                         String parameterValue = "";
 911  0
                         if (StringUtils.contains(parameter, KNSConstants.DISPATCH_REQUEST_PARAMETER + ".customLookupableMethodCall.")) {
 912  0
                             if (parameter.trim().endsWith(".x")) {
 913  0
                                 parameterValue = StringUtils.substringBetween(parameter, KNSConstants.DISPATCH_REQUEST_PARAMETER + ".customLookupableMethodCall.", ".x");
 914  0
                             } else if (parameter.trim().endsWith(".y")) {
 915  0
                                 parameterValue = StringUtils.substringBetween(parameter, KNSConstants.DISPATCH_REQUEST_PARAMETER + ".customLookupableMethodCall.", ".y");
 916  
                             } 
 917  0
                             if (StringUtils.isNotEmpty(parameterValue)) {
 918  0
                                 methodToCallArray = new String[]{ parameterValue };
 919  0
                             break;
 920  
                             }
 921  
                         }
 922  0
                     }
 923  
                 }
 924  
                 //String[] methodToCallArray = ((String[])this.getParameters().get(KNSConstants.DISPATCH_REQUEST_PARAMETER + ".customLookupableMethodCall"));
 925  0
                 if (ObjectUtils.isNotNull(methodToCallArray) && methodToCallArray.length > 0) {
 926  0
                         String methodToCallVal = methodToCallArray[0];
 927  0
                         if (StringUtils.isNotBlank(methodToCallVal)) {
 928  0
                                 boolean resetRows = false;
 929  
                                 // Retrieve the isAdvancedSearch property, if present.
 930  0
                                 String advancedSearchVal = StringUtils.substringBetween(methodToCallVal, KNSConstants.METHOD_TO_CALL_PARM1_LEFT_DEL, KNSConstants.METHOD_TO_CALL_PARM1_RIGHT_DEL);
 931  0
                                 if (StringUtils.isNotBlank(advancedSearchVal)) {
 932  0
                                         if (this.getParameters().containsKey("isAdvancedSearch")) {
 933  0
                                                 ((String[]) this.getParameters().get("isAdvancedSearch"))[0] = advancedSearchVal;
 934  
                                         }
 935  
                                         else {
 936  0
                                                 fieldValues.put("isAdvancedSearch", advancedSearchVal);
 937  
                                         }
 938  0
                                         resetRows = true;
 939  
                                 }
 940  
                                 // Retrieve the superUserSearch property, if present.
 941  0
                                 String superUserSearchVal = StringUtils.substringBetween(methodToCallVal, KNSConstants.METHOD_TO_CALL_PARM2_LEFT_DEL, KNSConstants.METHOD_TO_CALL_PARM2_RIGHT_DEL);
 942  0
                                 if (StringUtils.isNotBlank(superUserSearchVal)) {
 943  0
                                         if (this.getParameters().containsKey("superUserSearch")) {
 944  0
                                                 ((String[]) this.getParameters().get("superUserSearch"))[0] = superUserSearchVal;
 945  
                                         } else {
 946  0
                                                 fieldValues.put("superUserSearch", superUserSearchVal);
 947  
                                         }
 948  0
                                         resetRows = true;
 949  
                                 }
 950  
                                 // Retrieve and act upon the resetSavedSearch property, if present and set to true.
 951  0
                                 String resetSavedSearchVal = StringUtils.substringBetween(methodToCallVal, KNSConstants.METHOD_TO_CALL_PARM4_LEFT_DEL, KNSConstants.METHOD_TO_CALL_PARM4_RIGHT_DEL);
 952  0
                                 if (Boolean.parseBoolean(resetSavedSearchVal)) {
 953  0
                                         docSearchService.clearNamedSearches(GlobalVariables.getUserSession().getPrincipalId());
 954  0
                                         resetRows = true;
 955  
                                 }
 956  
 
 957  
                                 // If any of the above properties were found, reset the rows in a manner similar to KualiLookupAction.refresh, but with
 958  
                                 // enough modifications to prevent any changed isAdvancedSearch or superUserSearch values from being overridden again.
 959  0
                                 if (resetRows) {
 960  0
                                         Map<String,String> values = new HashMap<String,String>();
 961  0
                                         for (Field tempField : getFields(this.getRows())) {
 962  0
                                                 values.put(tempField.getPropertyName(), tempField.getPropertyValue());
 963  
                                         }
 964  
 
 965  0
                                 for (Iterator<Row> iter = this.getRows().iterator(); iter.hasNext();) {
 966  0
                                         Row row = iter.next();
 967  
 
 968  0
                                         for (Iterator<Field> iterator = row.getFields().iterator(); iterator.hasNext();) {
 969  0
                                                 Field field = iterator.next();
 970  
 
 971  0
                                                 if (field.getPropertyName() != null && !field.getPropertyName().equals("")) {
 972  0
                                                         if (this.getParameters().get(field.getPropertyName()) != null) {
 973  0
                                                                 if(!Field.MULTI_VALUE_FIELD_TYPES.contains(field.getFieldType())) {
 974  0
                                                                         field.setPropertyValue(((String[])this.getParameters().get(field.getPropertyName()))[0]);
 975  
                                                                 } else {
 976  
                                                                         //multi value, set to values
 977  0
                                                                         field.setPropertyValues((String[])this.getParameters().get(field.getPropertyName()));
 978  
                                                                 }
 979  
                                                         }
 980  
                                                 }
 981  0
                                                 else if (values.get(field.getPropertyName()) != null) {
 982  0
                                                         field.setPropertyValue(values.get(field.getPropertyName()));
 983  
                                                 }
 984  
 
 985  0
                                                 applyFieldAuthorizationsFromNestedLookups(field);
 986  
 
 987  0
                                                 fieldValues.put(field.getPropertyName(), field.getPropertyValue());
 988  0
                                         }
 989  0
                                 }
 990  
 
 991  0
                                 if (checkForAdditionalFields(fieldValues)) {
 992  0
                                     for (Iterator<Row> iter = this.getRows().iterator(); iter.hasNext();) {
 993  0
                                         Row row = iter.next();
 994  0
                                         for (Iterator<Field> iterator = row.getFields().iterator(); iterator.hasNext();) {
 995  0
                                             Field field = iterator.next();
 996  0
                                             if (field.getPropertyName() != null && !field.getPropertyName().equals("")) {
 997  0
                                                 if (this.getParameters().get(field.getPropertyName()) != null) {
 998  0
                                                         if(!Field.MULTI_VALUE_FIELD_TYPES.contains(field.getFieldType())) {
 999  0
                                                                             field.setPropertyValue(((String[])this.getParameters().get(field.getPropertyName()))[0]);
 1000  
                                                                     } else {
 1001  
                                                                             //multi value, set to values
 1002  0
                                                                             field.setPropertyValues((String[])this.getParameters().get(field.getPropertyName()));
 1003  
                                                                     }
 1004  
                                                                     //FIXME: any reason this is inside this "if" instead of the outer one, like above - this seems inconsistent
 1005  0
                                                                     fieldValues.put(field.getPropertyName(), ((String[])this.getParameters().get(field.getPropertyName()))[0]);
 1006  
                                                 }
 1007  0
                                                 else if (values.get(field.getPropertyName()) != null) {
 1008  0
                                                         field.setPropertyValue(values.get(field.getPropertyName()));
 1009  
                                                 }
 1010  
                                             }
 1011  0
                                         }
 1012  0
                                     }
 1013  
                                 }
 1014  
                                 // Finally, return false to prevent the search from being performed and to skip the other custom processing below.
 1015  0
                                 return false;
 1016  
                                 }
 1017  
 
 1018  
                         }
 1019  
                 } // End of methodToCall parameter retrieval.
 1020  
 
 1021  0
                 String[] resetSavedSearch = ((String[])getParameters().get("resetSavedSearch"));
 1022  0
                 if(resetSavedSearch!=null) {
 1023  0
                         docSearchService.clearNamedSearches(GlobalVariables.getUserSession().getPrincipalId());
 1024  0
                         setRows(fieldValues,"");
 1025  0
                         return false;
 1026  
                 }
 1027  
 
 1028  0
                 String savedSearchName = ((String[])getParameters().get("savedSearchName"))[0];
 1029  0
                 if(StringUtils.isEmpty(savedSearchName)||"*ignore*".equals(savedSearchName)) {
 1030  0
                         if(!ignoreErrors) {
 1031  0
                                 GlobalVariables.getMessageMap().putError("savedSearchName", RiceKeyConstants.ERROR_CUSTOM, "You must select a saved search");
 1032  
                         } else {
 1033  
                                 //if we're ignoring errors and we got an error just return, no reason to continue.  Also set false to indicate not to perform lookup
 1034  0
                                 return false;
 1035  
                         }
 1036  
                         //TODO: is there a better way to override a single field value?
 1037  0
                         List<Row> rows = this.getRows();
 1038  0
                         for (Row row : rows) {
 1039  0
                                 List<Field> fields = row.getFields();
 1040  0
                                 for (Field field : fields) {
 1041  0
                                         if(StringUtils.equals(field.getPropertyName(), "savedSearchName")) {
 1042  0
                                                 field.setPropertyValue("");
 1043  0
                                                 break;
 1044  
                                         }
 1045  
                                 }
 1046  0
                         }
 1047  
                 }
 1048  0
         if (!GlobalVariables.getMessageMap().hasNoErrors()) {
 1049  0
             throw new ValidationException("errors in search criteria");
 1050  
         }
 1051  
 
 1052  
 
 1053  0
                 SavedSearchResult savedSearchResult = null;
 1054  0
                 if(StringUtils.isNotEmpty(savedSearchName)) {
 1055  0
                         savedSearchResult = docSearchService.getSavedSearchResults(GlobalVariables.getUserSession().getPrincipalId(), savedSearchName);
 1056  
                 }
 1057  0
                 DocSearchCriteriaDTO criteria=null;
 1058  0
                 if(savedSearchResult!=null){
 1059  0
                         criteria = savedSearchResult.getDocSearchCriteriaDTO();
 1060  
                 }
 1061  
                 //put the doc type from the criteria in the map to send to setRows and then call setRows
 1062  0
                 String docTypeName = criteria.getDocTypeFullName();
 1063  
 
 1064  
 
 1065  0
                 setRows(fieldValues,docTypeName);
 1066  
 
 1067  
                 //set field values (besides search atts) here
 1068  
 //                fieldValues.put("docTypeFullName", docTypeName);
 1069  
 //                fieldValues.put("fromDateCreated", criteria.getFromDateCreated());
 1070  0
                 fieldValues.put("savedSearchName", "");
 1071  
 
 1072  
 
 1073  0
                 for (SearchAttributeCriteriaComponent searchAtt : criteria.getSearchableAttributes()) {
 1074  0
                         if(!searchAtt.isCanHoldMultipleValues()) {
 1075  0
                                 fieldValues.put(searchAtt.getSavedKey(), searchAtt.getValue());
 1076  
                         } else {
 1077  0
                                 List<String> values = searchAtt.getValues();
 1078  0
                                 String[] arrayValues = {};
 1079  0
                                 arrayValues = values.toArray(arrayValues);
 1080  0
                                 multFieldValues.put(searchAtt.getSavedKey(), arrayValues);
 1081  0
                         }
 1082  
 
 1083  
                 }
 1084  0
                 Object fieldValue = null;
 1085  0
         for (Iterator<Row> iter = getRows().iterator(); iter.hasNext();) {
 1086  0
             Row row = (Row) iter.next();
 1087  0
             for (Iterator<Field> iterator = row.getFields().iterator(); iterator.hasNext();) {
 1088  0
                 Field field = (Field) iterator.next();
 1089  0
                 if (field.getPropertyName() != null && !field.getPropertyName().equals("")) {
 1090  0
                         if (fieldValues.get(field.getPropertyName()) != null) {
 1091  0
                                         field.setPropertyValue(fieldValues.get(field.getPropertyName()));
 1092  0
                     } else if(multFieldValues.get(field.getPropertyName())!=null){
 1093  0
                                          field.setPropertyValues(multFieldValues.get(field.getPropertyName()));
 1094  
                     } else {
 1095  
                             //may be on the root of the criteria object, try looking there:
 1096  
                             try {
 1097  0
                                                         fieldValue = PropertyUtils.getProperty(criteria, field.getPropertyName());
 1098  0
                                                 } catch (IllegalAccessException e) {
 1099  0
                                                         e.printStackTrace();
 1100  0
                                                 } catch (InvocationTargetException e) {
 1101  0
                                                         e.printStackTrace();
 1102  0
                                                 } catch (NoSuchMethodException e) {
 1103  
 //                                                        e.printStackTrace();
 1104  
                                                         //hmm what to do here, we should be able to find everything either in the search atts or at the base as far as I know.
 1105  0
                                                 }
 1106  0
                                                 if(fieldValue!=null) {
 1107  0
                                                         field.setPropertyValue(fieldValue);
 1108  
                                                 }
 1109  
 
 1110  
                     }
 1111  
                 }
 1112  0
             }
 1113  0
         }
 1114  
         //indicate to subsequent actions (search in this case) that a saved search was just populated
 1115  0
         savedSearch=true;
 1116  
 
 1117  0
         return true;
 1118  
         }
 1119  
 
 1120  
         /**
 1121  
          * @see org.kuali.rice.kns.lookup.AbstractLookupableHelperServiceImpl#getExtraField()
 1122  
          */
 1123  
         @Override
 1124  
         public Field getExtraField() {
 1125  0
                 SavedSearchValuesFinder savedSearchValuesFinder = new SavedSearchValuesFinder();
 1126  0
                 List<KeyLabelPair> savedSearchValues = savedSearchValuesFinder.getKeyValues();
 1127  
 
 1128  0
                 Field savedSearch = new Field();
 1129  0
                 savedSearch.setPropertyName("savedSearchName");
 1130  0
                 savedSearch.setFieldType(Field.DROPDOWN_SCRIPT);
 1131  0
                 savedSearch.setScript("customLookupChanged()");
 1132  0
                 savedSearch.setFieldValidValues(savedSearchValues);
 1133  0
                 savedSearch.setFieldLabel("Saved Searches");
 1134  0
                 return savedSearch;
 1135  
 
 1136  
         }
 1137  
 
 1138  
         private Object getDocSearchCriteriaDTOFieldValue (DocSearchCriteriaDTO searchCriteria, String fieldName) {
 1139  0
         Class<?> clazz = searchCriteria.getClass();
 1140  0
         String propertyName = fieldName;
 1141  0
         if(fieldName.startsWith(KNSConstants.LOOKUP_RANGE_LOWER_BOUND_PROPERTY_PREFIX)) {
 1142  0
             propertyName = StringUtils.remove(fieldName, KNSConstants.LOOKUP_RANGE_LOWER_BOUND_PROPERTY_PREFIX);
 1143  
         }
 1144  
         try {
 1145  0
             String methodName = new StringBuffer("get").append(propertyName.toUpperCase().charAt(0)).append(propertyName.substring(1)).toString();
 1146  0
             java.lang.reflect.Method method = clazz.getMethod(methodName);
 1147  0
             return method.invoke(searchCriteria);
 1148  0
         } catch (SecurityException e) {
 1149  0
             return null;
 1150  0
         } catch (IllegalArgumentException e) {
 1151  0
             return null;
 1152  0
         } catch (IllegalAccessException e) {
 1153  0
             return null;
 1154  0
         } catch (InvocationTargetException e) {
 1155  0
             return null;
 1156  0
         } catch (NoSuchMethodException e) {
 1157  0
             return getSearchableAttributeFieldValue(searchCriteria, fieldName);
 1158  
         }
 1159  
     }
 1160  
 
 1161  
         private Object getSearchableAttributeFieldValue(DocSearchCriteriaDTO searchCriteria, String fieldName) {
 1162  0
             Object valueToReturn = null;
 1163  0
             String propertyName = fieldName;
 1164  0
             boolean isDateTime = false;
 1165  0
         if(fieldName.startsWith(KNSConstants.LOOKUP_RANGE_LOWER_BOUND_PROPERTY_PREFIX)) {
 1166  0
             propertyName = StringUtils.remove(fieldName, KNSConstants.LOOKUP_RANGE_LOWER_BOUND_PROPERTY_PREFIX);
 1167  
         }
 1168  0
             if (searchCriteria.getSearchableAttributes() != null) {
 1169  0
                 for (SearchAttributeCriteriaComponent sa : searchCriteria.getSearchableAttributes()) {
 1170  0
                     if (StringUtils.equals(propertyName, sa.getFormKey())) {
 1171  0
                         if (StringUtils.equals(sa.getSearchableAttributeValue().getOjbConcreteClass(), "org.kuali.rice.kew.docsearch.SearchableAttributeDateTimeValue")) {
 1172  0
                             isDateTime = true;
 1173  
                         }
 1174  0
                         if (sa.isCanHoldMultipleValues()) {
 1175  0
                             valueToReturn = sa.getValues();
 1176  
                         } else {
 1177  0
                             valueToReturn = sa.getValue();
 1178  
                         }
 1179  0
                         break;
 1180  
                     }
 1181  
                 }
 1182  
             }
 1183  
 
 1184  0
             if (valueToReturn != null
 1185  
                     && valueToReturn instanceof String
 1186  
                     && isDateTime) {
 1187  0
                 if(fieldName.startsWith(KNSConstants.LOOKUP_RANGE_LOWER_BOUND_PROPERTY_PREFIX)) {
 1188  0
                     if (StringUtils.contains((String)valueToReturn, "..")) {
 1189  0
                         valueToReturn = StringUtils.split((String)valueToReturn, "..")[0];
 1190  0
                     } else if (StringUtils.contains((String)valueToReturn, ">=")) {
 1191  0
                         valueToReturn = StringUtils.split((String)valueToReturn, ">=")[0];
 1192  
                     } else {
 1193  0
                         valueToReturn = null;
 1194  
                     }
 1195  
                 } else {
 1196  0
                     if (StringUtils.contains((String)valueToReturn, "..")) {
 1197  0
                     valueToReturn = StringUtils.split((String)valueToReturn, "..")[1];
 1198  0
                 } else if (StringUtils.contains((String)valueToReturn, ">=")) {
 1199  0
                     valueToReturn = null;
 1200  0
                 } else if (StringUtils.contains((String)valueToReturn, "<=")) {
 1201  0
                     valueToReturn = StringUtils.split((String)valueToReturn, "<=")[0];
 1202  
                 }
 1203  
 
 1204  
                 }
 1205  
             }
 1206  
 
 1207  0
             return valueToReturn;
 1208  
         }
 1209  
 
 1210  
         /*
 1211  
     @Override
 1212  
     public List<Row> getRows() {
 1213  
         if(StringUtils.isEmpty(docTypeName)) {
 1214  
             super.performClear(lookupForm);
 1215  
         } else {
 1216  
             DocSearchCriteriaDTO docCriteria = DocumentLookupCriteriaBuilder.populateCriteria(fieldsToClear);
 1217  
             //TODO: Chris - (2 stage clear) set the isOnlyDocTypeFilled, to true if only doc type coming in (besides hidden) and false otherwise)
 1218  
             docCriteria = getValidDocumentType(docTypeName).getDocumentSearchGenerator().clearSearch(docCriteria);
 1219  
         }
 1220  
 
 1221  
         return super.getRows();
 1222  
     }
 1223  
         */
 1224  
 
 1225  
 }