Coverage Report - org.kuali.rice.kew.bo.lookup.DocumentRouteHeaderValueLookupableHelperServiceImpl
 
Classes in this File Line Coverage Branch Coverage Complexity
DocumentRouteHeaderValueLookupableHelperServiceImpl
0%
0/118
0%
0/58
5.375
 
 1  
 /*
 2  
  * Copyright 2006-2011 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  
 
 17  
 package org.kuali.rice.kew.bo.lookup;
 18  
 
 19  
 import org.apache.commons.beanutils.PropertyUtils;
 20  
 import org.apache.commons.lang.StringUtils;
 21  
 import org.kuali.rice.core.api.datetime.DateTimeService;
 22  
 import org.kuali.rice.core.api.config.property.ConfigContext;
 23  
 import org.kuali.rice.core.web.format.BooleanFormatter;
 24  
 import org.kuali.rice.core.web.format.CollectionFormatter;
 25  
 import org.kuali.rice.core.web.format.DateFormatter;
 26  
 import org.kuali.rice.core.web.format.Formatter;
 27  
 import org.kuali.rice.kew.docsearch.DocSearchCriteriaDTO;
 28  
 import org.kuali.rice.kew.docsearch.DocumentLookupCriteriaProcessor;
 29  
 import org.kuali.rice.kew.docsearch.DocumentLookupCriteriaProcessorKEWAdapter;
 30  
 import org.kuali.rice.kew.docsearch.DocumentSearchResult;
 31  
 import org.kuali.rice.kew.docsearch.DocumentSearchResultComponents;
 32  
 import org.kuali.rice.kew.docsearch.StandardDocumentSearchCriteriaProcessor;
 33  
 import org.kuali.rice.kew.doctype.bo.DocumentType;
 34  
 import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
 35  
 import org.kuali.rice.kew.service.KEWServiceLocator;
 36  
 import org.kuali.rice.kew.util.KEWConstants;
 37  
 import org.kuali.rice.kew.util.KEWPropertyConstants;
 38  
 import org.kuali.rice.kew.web.KeyValueSort;
 39  
 import org.kuali.rice.kim.bo.Person;
 40  
 import org.kuali.rice.kns.lookup.HtmlData;
 41  
 import org.kuali.rice.kns.lookup.KualiLookupableHelperServiceImpl;
 42  
 import org.kuali.rice.kns.web.comparator.CellComparatorHelper;
 43  
 import org.kuali.rice.kns.web.struts.form.LookupForm;
 44  
 import org.kuali.rice.kns.web.ui.Column;
 45  
 import org.kuali.rice.kns.web.ui.Field;
 46  
 import org.kuali.rice.kns.web.ui.ResultRow;
 47  
 import org.kuali.rice.kns.web.ui.Row;
 48  
 import org.kuali.rice.krad.bo.BusinessObject;
 49  
 import org.kuali.rice.krad.util.GlobalVariables;
 50  
 import org.kuali.rice.krad.util.KRADConstants;
 51  
 
 52  
 import java.lang.reflect.InvocationTargetException;
 53  
 import java.sql.Date;
 54  
 import java.util.ArrayList;
 55  
 import java.util.Collection;
 56  
 import java.util.HashMap;
 57  
 import java.util.List;
 58  
 import java.util.Map;
 59  
 
 60  
 /**
 61  
  * This is a description of what this class does - chris don't forget to fill this in.
 62  
  *
 63  
  * @author Kuali Rice Team (rice.collab@kuali.org)
 64  
  *
 65  
  */
 66  0
 public class DocumentRouteHeaderValueLookupableHelperServiceImpl extends KualiLookupableHelperServiceImpl {
 67  
 
 68  
         private static final long serialVersionUID = -5162419674659967408L;
 69  
         DateTimeService dateTimeService;
 70  
         DocumentLookupCriteriaProcessor processor;
 71  
 
 72  
 
 73  
         /**
 74  
          * This overridden method ...
 75  
          *
 76  
          * @see org.kuali.rice.kew.bo.lookup.DocumentRouteHeaderValueLookupableHelperService#setDateTimeService(org.kuali.rice.core.api.datetime.DateTimeService)
 77  
          */
 78  
         public void setDateTimeService(DateTimeService dateTimeService) {
 79  0
                 this.dateTimeService = dateTimeService;
 80  0
         }
 81  
 
 82  
 
 83  
         /**
 84  
          * This overridden method ...
 85  
          *
 86  
          * @see org.kuali.rice.krad.lookup.AbstractLookupableHelperServiceImpl#getCustomActionUrls(org.kuali.rice.krad.bo.BusinessObject, java.util.List)
 87  
          */
 88  
         @Override
 89  
         public List<HtmlData> getCustomActionUrls(BusinessObject businessObject,
 90  
                         List pkNames) {
 91  
                 // TODO chris - THIS METHOD NEEDS JAVADOCS
 92  0
                 return super.getCustomActionUrls(businessObject, pkNames);
 93  
         }
 94  
 
 95  
 
 96  
 
 97  
 
 98  
 
 99  
 
 100  
 
 101  
         /**
 102  
          * This overridden method ...
 103  
          *
 104  
          * @see org.kuali.rice.krad.lookup.AbstractLookupableHelperServiceImpl#performLookup(org.kuali.rice.krad.web.struts.form.LookupForm, java.util.Collection, boolean)
 105  
          */
 106  
         @Override
 107  
         public Collection performLookup(LookupForm lookupForm,
 108  
                         Collection resultTable, boolean bounded) {
 109  
 
 110  
                 //TODO: KNS updates to make this not require code from the parent
 111  
 
 112  
 
 113  0
             Map<String,String> fieldsForLookup = lookupForm.getFieldsForLookup();
 114  0
             DocSearchCriteriaDTO criteria = constructCriteria(fieldsForLookup);
 115  
 
 116  
             //TODO: move this into actual adapter as well
 117  0
             Collection displayList=null;
 118  0
             DocumentSearchResultComponents components = KEWServiceLocator.getDocumentSearchService().getList(GlobalVariables.getUserSession().getPrincipalId(), criteria);
 119  0
             List<DocumentSearchResult> result = components.getSearchResults();
 120  
 //            for (DocumentSearchResult documentSearchResult : result) {
 121  0
                         displayList = result;//.getResultContainers();
 122  
 //                }
 123  
 
 124  
                 //####BEGIN COPIED CODE#########
 125  0
         setBackLocation((String) lookupForm.getFieldsForLookup().get(KRADConstants.BACK_LOCATION));
 126  0
         setDocFormKey((String) lookupForm.getFieldsForLookup().get(KRADConstants.DOC_FORM_KEY));
 127  
 
 128  
 //###COMENTED OUT
 129  
 //                  Collection displayList;
 130  
 //        // call search method to get results
 131  
 //        if (bounded) {
 132  
 //            displayList = getSearchResults(lookupForm.getFieldsForLookup());
 133  
 //        }
 134  
 //        else {
 135  
 //            displayList = getSearchResultsUnbounded(lookupForm.getFieldsForLookup());
 136  
 //        }
 137  
 //##COMENTED OUT
 138  
 
 139  0
         HashMap<String,Class> propertyTypes = new HashMap<String, Class>();
 140  
 
 141  0
         boolean hasReturnableRow = false;
 142  
 
 143  0
         List returnKeys = getReturnKeys();
 144  0
         List pkNames = getBusinessObjectMetaDataService().listPrimaryKeyFieldNames(getBusinessObjectClass());
 145  0
         Person user = GlobalVariables.getUserSession().getPerson();
 146  
 
 147  
         // iterate through result list and wrap rows with return url and action urls
 148  
 
 149  
 //COMMENTING THIS OUT FOR NOW
 150  
 //        for (Iterator iter = displayList.iterator(); iter.hasNext();) {
 151  
 //            BusinessObject element = (BusinessObject) iter.next();
 152  
 //                if(element instanceof PersistableBusinessObject){
 153  
 //                lookupForm.setLookupObjectId(((PersistableBusinessObject)element).getObjectId());
 154  
 //            }
 155  
 //                BusinessObject element = null;
 156  
 //                BusinessObjectRestrictions businessObjectRestrictions = getBusinessObjectAuthorizationService().getLookupResultRestrictions(element, user);
 157  
 
 158  
 //            HtmlData returnUrl = getReturnUrl(element, lookupForm, returnKeys, businessObjectRestrictions);
 159  
 //          String actionUrls = getActionUrls(element, pkNames, businessObjectRestrictions);
 160  
 //ADDED (4 lines)
 161  0
         for (DocumentSearchResult aResult : result)
 162  
         {
 163  
             //TODO: where to get these from?
 164  0
             HtmlData returnUrl = new HtmlData.AnchorHtmlData();
 165  0
             String actionUrls = "";
 166  
 
 167  
 //TODO: convert columns either here or in the getColumns method
 168  
 //ADDED (3)
 169  0
             List<? extends Column> columns = components.getColumns();//getColumns();
 170  0
             List<KeyValueSort> keyValues = aResult.getResultContainers();
 171  0
             for (int i = 0; i < columns.size(); i++)
 172  
             {
 173  
 
 174  
 //            for (Iterator iterator = columns.iterator(); iterator.hasNext();) {
 175  
 
 176  
 //                Column col = (Column) iterator.next();
 177  
 //ADDED 3
 178  0
                 Column col = (Column) columns.get(i);
 179  0
                 KeyValueSort keyValue = keyValues.get(i);
 180  
 //Set values from keyvalue on column
 181  0
                 col.setPropertyValue(keyValue.getUserDisplayValue());
 182  
 
 183  0
                 Formatter formatter = col.getFormatter();
 184  
 
 185  
                 // pick off result column from result list, do formatting
 186  0
                 String propValue = KRADConstants.EMPTY_STRING;
 187  
 //                Object prop = ObjectUtils.getPropertyValue(element, col.getPropertyName());
 188  
 //ADDED
 189  0
                 Object prop = col.getPropertyValue();
 190  
 
 191  
                 // set comparator and formatter based on property type
 192  0
                 Class propClass = propertyTypes.get(col.getPropertyName());
 193  0
                 if (propClass == null)
 194  
                 {
 195  
                     try
 196  
                     {
 197  
 //                            propClass = ObjectUtils.getPropertyType( element, col.getPropertyName(), getPersistenceStructureService() );
 198  
 //                            propertyTypes.put( col.getPropertyName(), propClass );
 199  
                     } catch (Exception e)
 200  
                     {
 201  
 //                        throw new RuntimeException("Cannot access PropertyType for property " + "'" + col.getPropertyName() + "' " + " on an instance of '" + element.getClass().getName() + "'.", e);
 202  0
                     }
 203  
                 }
 204  
 
 205  
                 // formatters
 206  0
                 if (prop != null)
 207  
                 {
 208  
                     // for Booleans, always use BooleanFormatter
 209  0
                     if (prop instanceof Boolean)
 210  
                     {
 211  0
                         formatter = new BooleanFormatter();
 212  
                     }
 213  
 
 214  
                     // for Dates, always use DateFormatter
 215  0
                     if (prop instanceof Date)
 216  
                     {
 217  0
                         formatter = new DateFormatter();
 218  
                     }
 219  
 
 220  
                     // for collection, use the list formatter if a formatter hasn't been defined yet
 221  0
                     if (prop instanceof Collection && formatter == null)
 222  
                     {
 223  0
                         formatter = new CollectionFormatter();
 224  
                     }
 225  
 
 226  0
                     if (formatter != null)
 227  
                     {
 228  0
                         propValue = (String) formatter.format(prop);
 229  
                     } else
 230  
                     {
 231  0
                         propValue = prop.toString();
 232  
                     }
 233  
                 }
 234  
 
 235  
                 // comparator
 236  0
                 col.setComparator(CellComparatorHelper.getAppropriateComparatorForPropertyClass(propClass));
 237  0
                 col.setValueComparator(CellComparatorHelper.getAppropriateValueComparatorForPropertyClass(propClass));
 238  
 
 239  
 //                propValue = maskValueIfNecessary(element.getClass(), col.getPropertyName(), propValue, businessObjectRestrictions);
 240  
 
 241  0
                 col.setPropertyValue(propValue);
 242  
 
 243  0
                 if (StringUtils.isNotBlank(propValue))
 244  
                 {
 245  
 //                    col.setColumnAnchor(getInquiryUrl(element, col.getPropertyName()));
 246  
 //ADDED (3 lines)
 247  0
                     HtmlData.AnchorHtmlData anchor = new HtmlData.AnchorHtmlData(KRADConstants.EMPTY_STRING, KRADConstants.EMPTY_STRING);
 248  
                     //TODO: change to grab URL from config variable
 249  0
                     if (StringUtils.isNotEmpty(keyValue.getValue()) && StringUtils.equals("documentId", keyValue.getKey()))
 250  
                     {
 251  0
                         anchor.setHref(StringUtils.substringBetween(keyValue.getValue(), "<a href=\"", "docId=") + "docId=" + keyValue.getUserDisplayValue());
 252  0
                         col.setMaxLength(100); //for now force this
 253  
                     }
 254  
 
 255  0
                     col.setColumnAnchor(anchor);
 256  
                 }
 257  
             }
 258  
 
 259  0
             ResultRow row = new ResultRow((List<Column>) columns, returnUrl.constructCompleteHtmlTag(), actionUrls);
 260  0
             row.setRowId(returnUrl.getName());
 261  
             // because of concerns of the BO being cached in session on the ResultRow,
 262  
             // let's only attach it when needed (currently in the case of export)
 263  0
             if (getBusinessObjectDictionaryService().isExportable(getBusinessObjectClass()))
 264  
             {
 265  
 //                    row.setBusinessObject(element);
 266  
             }
 267  
 
 268  
 //            boolean rowReturnable = isResultReturnable(element);
 269  
 //ADDED
 270  0
             boolean rowReturnable = true;
 271  0
             row.setRowReturnable(rowReturnable);
 272  0
             if (rowReturnable)
 273  
             {
 274  0
                 hasReturnableRow = true;
 275  
             }
 276  0
             resultTable.add(row);
 277  0
         }
 278  
 
 279  0
         lookupForm.setHasReturnableRow(hasReturnableRow);
 280  
 
 281  0
         return displayList;
 282  
                 //####END COPIED CODE#########
 283  
         }
 284  
 
 285  
 
 286  
         /**
 287  
          * This method ...
 288  
          *
 289  
          * @param lookupForm
 290  
          * @return
 291  
          */
 292  
         private DocSearchCriteriaDTO constructCriteria(Map<String,String> fieldsForLookup) {
 293  
                 //TODO: move this into adapter
 294  0
             DocSearchCriteriaDTO criteria = new DocSearchCriteriaDTO();
 295  0
             Map<String,String> fieldsToSet = new HashMap<String,String>();
 296  0
                 for (String formKey : fieldsForLookup.keySet()) {
 297  0
                         if(!(formKey.equalsIgnoreCase(KRADConstants.BACK_LOCATION) ||
 298  
                            formKey.equalsIgnoreCase(KRADConstants.DOC_FORM_KEY)) && StringUtils.isNotEmpty(fieldsForLookup.get(formKey))) {
 299  0
                                 fieldsToSet.put(formKey, fieldsForLookup.get(formKey));
 300  
                         }
 301  
                 }
 302  
                 //if we use DocSearchCriteriaDTO as object we shouldn't need this conversion stuff
 303  0
             for (String fieldToSet : fieldsToSet.keySet()) {
 304  
                         //need translation code here for certain fields
 305  0
                     String valueToSet = fieldsToSet.get(fieldToSet);
 306  
                         try {
 307  
                                 //TODO: temporary work around until is a criteria
 308  0
                                 if(fieldToSet.equals("documentType.name")) {
 309  0
                                         fieldToSet = "docTypeFullName";
 310  
                                 }
 311  0
                                 PropertyUtils.setNestedProperty(criteria, fieldToSet, valueToSet);
 312  0
                         } catch (IllegalAccessException e) {
 313  0
                                 e.printStackTrace();
 314  0
                         } catch (InvocationTargetException e) {
 315  0
                                 e.printStackTrace();
 316  0
                         } catch (NoSuchMethodException e) {
 317  0
                                 e.printStackTrace();
 318  0
                         }
 319  0
                 }
 320  0
                 return criteria;
 321  
         }
 322  
 
 323  
 
 324  
         /**
 325  
          * This overridden method ...
 326  
          *
 327  
          * @see org.kuali.rice.krad.lookup.AbstractLookupableHelperServiceImpl#getInquiryUrl(org.kuali.rice.krad.bo.BusinessObject, java.lang.String)
 328  
          */
 329  
         @Override
 330  
         public HtmlData getInquiryUrl(BusinessObject bo, String propertyName) {
 331  
                 //FIXME: ctk - make sure and check that it's ok to do this here.  I may move this out to the doc search processor
 332  0
                 if(KEWPropertyConstants.DOC_SEARCH_RESULT_PROPERTY_NAME_DOCUMENT_ID.equals(propertyName)) {
 333  
 
 334  0
                         HtmlData.AnchorHtmlData link = new HtmlData.AnchorHtmlData();
 335  0
                         DocumentRouteHeaderValue doc = (DocumentRouteHeaderValue)bo;
 336  
                         //if !superuser
 337  0
                         String documentId = doc.getDocumentId();
 338  0
                         link.setDisplayText(documentId+"");
 339  
                         
 340  0
                         String href = ConfigContext.getCurrentContextConfig().getKRBaseURL()+"/"+
 341  
                         KEWConstants.DOC_HANDLER_REDIRECT_PAGE + "?" + KEWConstants.COMMAND_PARAMETER + "=" + 
 342  
                         KEWConstants.DOCSEARCH_COMMAND + "&" + KEWConstants.DOCUMENT_ID_PARAMETER + "=" + documentId;
 343  0
                         link.setHref(href);
 344  
 
 345  0
                         return link;
 346  
                 }
 347  
 
 348  0
                 return super.getInquiryUrl(bo, propertyName);
 349  
         }
 350  
 
 351  
 
 352  
         /**
 353  
          * This overridden method ...
 354  
          *
 355  
          * @see org.kuali.rice.krad.lookup.AbstractLookupableHelperServiceImpl#setRows()
 356  
          */
 357  
         @Override
 358  
         protected void setRows() {
 359  
                 // TODO chris - this method should call the criteria processor adapter which will
 360  
                 //call the criteria processor (either standard or custom) and massage the data into the proper format
 361  
                 //this is called by setbo in super(which is called by form) so should be called when the page needs refreshing
 362  
 
 363  
                 //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?)
 364  
 
 365  
 
 366  
                 //###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
 367  0
                 super.setRows();
 368  0
                 List<Row> lookupRows = new ArrayList<Row>();
 369  
                 //copy the current rows
 370  0
                 for (Row row : super.getRows()) {
 371  0
                         lookupRows.add(row);
 372  
                 }
 373  
                 //clear out
 374  0
                 super.getRows().clear();
 375  
                 //###END LOOKUP ROW CODE TODO: do something with lookupRows or delete above code
 376  
 
 377  
 
 378  0
         processor = new DocumentLookupCriteriaProcessorKEWAdapter();
 379  
 
 380  
 
 381  
 
 382  
                 //TODO: get this from parameters (or bo?)
 383  0
                 DocumentType docType = null;
 384  0
                 if(processor != null) {
 385  
                         //TODO: same Doc type
 386  
 //                        if(docType==oldDocType) {
 387  0
                         ((DocumentLookupCriteriaProcessorKEWAdapter)processor).setCriteriaProcessor(new StandardDocumentSearchCriteriaProcessor());
 388  
 //                        } else {
 389  
 
 390  
 //                        }
 391  
                 } else {
 392  
                         //TODO: same Doc type
 393  0
                         if(docType==null) {
 394  0
                                 ((DocumentLookupCriteriaProcessorKEWAdapter)processor).setCriteriaProcessor(new StandardDocumentSearchCriteriaProcessor());
 395  
                         }// else {
 396  
 
 397  
 //                        }
 398  
                 }
 399  
 
 400  
                 //call get rows
 401  0
                 List<Row> rows = processor.getRows(docType,lookupRows,false,false);
 402  0
                 super.getRows().addAll(rows);
 403  
 
 404  
                 //are we in basic or detailed, are we in super.
 405  
                 //TODO: ctk Add this code back in when KNS impacting changes are worked back
 406  
 
 407  
 
 408  
 
 409  
 
 410  
 
 411  0
         }
 412  
 
 413  
 
 414  
         /**
 415  
          * This overridden method allows for overriding what the clear logic does.
 416  
          *
 417  
          * @see org.kuali.rice.krad.lookup.AbstractLookupableHelperServiceImpl#performClear()
 418  
          */
 419  
         @Override
 420  
         public void performClear(LookupForm lookupForm) {
 421  0
                 Map<String,String> fieldsToClear = new HashMap<String,String>();
 422  
 
 423  0
                 for (Row row : this.getRows()) {
 424  0
                         for (Field field : row.getFields()) {
 425  0
                                 fieldsToClear.put(field.getPropertyName(), field.getPropertyValue());
 426  
                         }
 427  
                 }
 428  
                 //TODO: also check if standard here (maybe from object if use criteria)
 429  0
                 if(this.processor==null) {
 430  0
                         super.performClear(lookupForm);
 431  
                 } else {
 432  0
                         DocSearchCriteriaDTO docCriteria = constructCriteria(fieldsToClear);
 433  0
                         if(StringUtils.isNotEmpty("documentType.name")) {
 434  
                                 //TODO: move these strings to constants (probably after moving this to criteria
 435  0
                                 getValidDocumentType(fieldsToClear.get("documentType.name")).getDocumentSearchGenerator().clearSearch(docCriteria);;
 436  
                         }
 437  
                 }
 438  0
         }
 439  
         /**
 440  
          *
 441  
          * This method is taken from DocSearch to retrieve a document type
 442  
          *
 443  
          * @param docTypeName
 444  
          * @return
 445  
          */
 446  
     private static DocumentType getValidDocumentType(String docTypeName) {
 447  0
         DocumentType documentType = KEWServiceLocator.getDocumentTypeService().findByName(docTypeName);
 448  0
         if (documentType == null) {
 449  0
             throw new RuntimeException("Document Type invalid : " + docTypeName);
 450  
         }
 451  0
         return documentType;
 452  
     }
 453  
 }