Coverage Report - org.kuali.rice.kns.workflow.attribute.DataDictionarySearchableAttribute
 
Classes in this File Line Coverage Branch Coverage Complexity
DataDictionarySearchableAttribute
0%
0/195
0%
0/84
4.643
 
 1  
 /*
 2  
  * Copyright 2008-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.kns.workflow.attribute;
 17  
 
 18  
 import java.util.ArrayList;
 19  
 import java.util.Collection;
 20  
 import java.util.LinkedHashMap;
 21  
 import java.util.List;
 22  
 import java.util.Map;
 23  
 
 24  
 import org.apache.commons.lang.StringUtils;
 25  
 import org.apache.log4j.Logger;
 26  
 import org.kuali.rice.kew.docsearch.DocumentSearchContext;
 27  
 import org.kuali.rice.kew.docsearch.SearchableAttribute;
 28  
 import org.kuali.rice.kew.docsearch.SearchableAttributeStringValue;
 29  
 import org.kuali.rice.kew.docsearch.SearchableAttributeValue;
 30  
 import org.kuali.rice.kew.exception.WorkflowException;
 31  
 import org.kuali.rice.kew.rule.WorkflowAttributeValidationError;
 32  
 import org.kuali.rice.kew.util.KEWConstants;
 33  
 import org.kuali.rice.kns.bo.BusinessObject;
 34  
 import org.kuali.rice.kns.bo.DocumentHeader;
 35  
 import org.kuali.rice.kns.bo.GlobalBusinessObject;
 36  
 import org.kuali.rice.kns.bo.PersistableBusinessObject;
 37  
 import org.kuali.rice.kns.datadictionary.BusinessObjectEntry;
 38  
 import org.kuali.rice.kns.datadictionary.DocumentEntry;
 39  
 import org.kuali.rice.kns.datadictionary.MaintenanceDocumentEntry;
 40  
 import org.kuali.rice.kns.datadictionary.SearchingAttribute;
 41  
 import org.kuali.rice.kns.datadictionary.SearchingTypeDefinition;
 42  
 import org.kuali.rice.kns.datadictionary.WorkflowAttributes;
 43  
 import org.kuali.rice.kns.document.Document;
 44  
 import org.kuali.rice.kns.document.MaintenanceDocument;
 45  
 import org.kuali.rice.kns.lookup.LookupUtils;
 46  
 import org.kuali.rice.kns.maintenance.KualiGlobalMaintainableImpl;
 47  
 import org.kuali.rice.kns.maintenance.Maintainable;
 48  
 import org.kuali.rice.kns.service.*;
 49  
 import org.kuali.rice.kns.util.FieldUtils;
 50  
 import org.kuali.rice.kns.util.GlobalVariables;
 51  
 import org.kuali.rice.kns.util.KNSPropertyConstants;
 52  
 import org.kuali.rice.kns.util.MessageMap;
 53  
 import org.kuali.rice.kns.util.ObjectUtils;
 54  
 import org.kuali.rice.kns.web.ui.Field;
 55  
 import org.kuali.rice.kns.web.ui.Row;
 56  
 import org.kuali.rice.kns.workflow.service.WorkflowAttributePropertyResolutionService;
 57  
 
 58  
 /**
 59  
  * This class...
 60  
  */
 61  0
 public class DataDictionarySearchableAttribute implements SearchableAttribute {
 62  
 
 63  
     private static final long serialVersionUID = 173059488280366451L;
 64  0
         private static final Logger LOG = Logger.getLogger(DataDictionarySearchableAttribute.class);
 65  
     public static final String DATA_TYPE_BOOLEAN = "boolean";
 66  
 
 67  
     /**
 68  
      * @see org.kuali.rice.kew.docsearch.SearchableAttribute#getSearchContent(org.kuali.rice.kew.docsearch.DocumentSearchContext)
 69  
      */
 70  
     public String getSearchContent(DocumentSearchContext documentSearchContext) {
 71  
 
 72  0
         return "";
 73  
     }
 74  
 
 75  
     /**
 76  
      * @see org.kuali.rice.kew.docsearch.SearchableAttribute#getSearchStorageValues(org.kuali.rice.kew.docsearch.DocumentSearchContext)
 77  
      */
 78  
     public List<SearchableAttributeValue> getSearchStorageValues(DocumentSearchContext documentSearchContext) {
 79  0
         List<SearchableAttributeValue> saValues = new ArrayList<SearchableAttributeValue>();
 80  
 
 81  0
         String docId = documentSearchContext.getDocumentId();
 82  
 
 83  0
         DocumentService docService = KNSServiceLocatorWeb.getDocumentService();
 84  0
         Document doc = null;
 85  
         try  {
 86  0
             doc = docService.getByDocumentHeaderIdSessionless(docId);
 87  0
         } catch (WorkflowException we) {
 88  0
                 LOG.error( "Unable to retrieve document " + docId + " in getSearchStorageValues()", we);
 89  0
         }
 90  
 
 91  0
         SearchableAttributeStringValue searchableAttributeValue = new SearchableAttributeStringValue();
 92  0
         searchableAttributeValue.setSearchableAttributeKey("documentDescription");
 93  0
         if ( doc != null ) {
 94  0
                 if ( doc.getDocumentHeader() != null ) {
 95  0
                 searchableAttributeValue.setSearchableAttributeValue(doc.getDocumentHeader().getDocumentDescription());
 96  
                 } else {
 97  0
                         searchableAttributeValue.setupAttributeValue( "null document header" );
 98  
                 }
 99  
         } else {
 100  0
                     searchableAttributeValue.setupAttributeValue( "null document" );
 101  
         }
 102  0
         saValues.add(searchableAttributeValue);
 103  
 
 104  0
         searchableAttributeValue = new SearchableAttributeStringValue();
 105  0
         searchableAttributeValue.setSearchableAttributeKey("organizationDocumentNumber");
 106  0
         if ( doc != null ) {
 107  0
                 if ( doc.getDocumentHeader() != null ) {
 108  0
                 searchableAttributeValue.setSearchableAttributeValue(doc.getDocumentHeader().getOrganizationDocumentNumber());
 109  
                 } else {
 110  0
                         searchableAttributeValue.setupAttributeValue( "null document header" );
 111  
                 }
 112  
         } else {
 113  0
                     searchableAttributeValue.setupAttributeValue( "null document" );
 114  
         }
 115  0
         saValues.add(searchableAttributeValue);
 116  
 
 117  0
         if ( doc != null && doc instanceof MaintenanceDocument) {
 118  0
             final Class<? extends BusinessObject> businessObjectClass = getBusinessObjectClass(documentSearchContext.getDocumentTypeName());
 119  0
             if (businessObjectClass != null) {
 120  0
                 if (GlobalBusinessObject.class.isAssignableFrom(businessObjectClass)) {
 121  0
                     final String documentNumber = documentSearchContext.getDocumentId();
 122  0
                     final GlobalBusinessObject globalBO = retrieveGlobalBusinessObject(documentNumber, businessObjectClass);
 123  
 
 124  0
                     if (globalBO != null) {
 125  0
                         saValues.addAll(findAllSearchableAttributesForGlobalBusinessObject(globalBO));
 126  
                     }
 127  0
                 } else {
 128  0
                     saValues.addAll(parsePrimaryKeyValuesFromDocument(businessObjectClass, (MaintenanceDocument)doc));
 129  
                 }
 130  
 
 131  
             }
 132  
         }
 133  0
         if ( doc != null ) {
 134  0
             DocumentEntry docEntry = KNSServiceLocatorWeb.getDataDictionaryService().getDataDictionary().getDocumentEntry(documentSearchContext.getDocumentTypeName());
 135  0
             if ( docEntry != null ) {
 136  0
                         WorkflowAttributes workflowAttributes = docEntry.getWorkflowAttributes();
 137  0
                         WorkflowAttributePropertyResolutionService waprs = KNSServiceLocatorInternal.getWorkflowAttributePropertyResolutionService();
 138  0
                         saValues.addAll(waprs.resolveSearchableAttributeValues(doc, workflowAttributes));
 139  0
             } else {
 140  0
                     LOG.error( "Unable to find DD document entry for document type: " + documentSearchContext.getDocumentTypeName() );
 141  
             }
 142  
         }
 143  0
         return saValues;
 144  
     }
 145  
 
 146  
     /**
 147  
      * @see org.kuali.rice.kew.docsearch.SearchableAttribute#getSearchingRows(org.kuali.rice.kew.docsearch.DocumentSearchContext)
 148  
      */
 149  
     public List<Row> getSearchingRows(DocumentSearchContext documentSearchContext) {
 150  
 
 151  0
         List<Row> docSearchRows = new ArrayList<Row>();
 152  
 
 153  0
         Class boClass = DocumentHeader.class;
 154  
 
 155  0
         Field descriptionField = FieldUtils.getPropertyField(boClass, "documentDescription", true);
 156  0
         descriptionField.setFieldDataType(KEWConstants.SearchableAttributeConstants.DATA_TYPE_STRING);
 157  
 
 158  0
         Field orgDocNumberField = FieldUtils.getPropertyField(boClass, "organizationDocumentNumber", true);
 159  0
         orgDocNumberField.setFieldDataType(KEWConstants.SearchableAttributeConstants.DATA_TYPE_STRING);
 160  
 
 161  0
         List<Field> fieldList = new ArrayList<Field>();
 162  0
         fieldList.add(descriptionField);
 163  0
         docSearchRows.add(new Row(fieldList));
 164  
 
 165  0
         fieldList = new ArrayList<Field>();
 166  0
         fieldList.add(orgDocNumberField);
 167  0
         docSearchRows.add(new Row(fieldList));
 168  
 
 169  
 
 170  0
         DocumentEntry entry = KNSServiceLocatorWeb.getDataDictionaryService().getDataDictionary().getDocumentEntry(documentSearchContext.getDocumentTypeName());
 171  0
         if (entry  == null)
 172  0
             return docSearchRows;
 173  0
         if (entry instanceof MaintenanceDocumentEntry) {
 174  0
             Class<? extends BusinessObject> businessObjectClass = getBusinessObjectClass(documentSearchContext.getDocumentTypeName());
 175  0
             Class<? extends Maintainable> maintainableClass = getMaintainableClass(documentSearchContext.getDocumentTypeName());
 176  
 
 177  0
             KualiGlobalMaintainableImpl globalMaintainable = null;
 178  
             try {
 179  0
                 globalMaintainable = (KualiGlobalMaintainableImpl)maintainableClass.newInstance();
 180  0
                 businessObjectClass = globalMaintainable.getPrimaryEditedBusinessObjectClass();
 181  0
             } catch (Exception ie) {
 182  
                 //was not a globalMaintainable.
 183  0
             }
 184  
 
 185  0
             if (businessObjectClass != null)
 186  0
                 docSearchRows.addAll(createFieldRowsForBusinessObject(businessObjectClass));
 187  
         }
 188  
 
 189  0
         WorkflowAttributes workflowAttributes = entry.getWorkflowAttributes();
 190  0
         if (workflowAttributes != null)
 191  0
             docSearchRows.addAll(createFieldRowsForWorkflowAttributes(workflowAttributes));
 192  
 
 193  0
         return docSearchRows;
 194  
     }
 195  
 
 196  
     public List<WorkflowAttributeValidationError> validateUserSearchInputs(Map<Object, Object> paramMap, DocumentSearchContext searchContext) {
 197  0
         List<WorkflowAttributeValidationError> validationErrors = null;
 198  0
         DictionaryValidationService validationService = KNSServiceLocatorWeb.getDictionaryValidationService();
 199  
         
 200  0
         for (Object key : paramMap.keySet()) {
 201  0
             Object value = paramMap.get(key);
 202  0
             if (value != null) {
 203  0
                     if (value instanceof String && !StringUtils.isEmpty((String)value)) {
 204  0
                             validationService.validateAttributeFormat(searchContext.getDocumentTypeName(), (String)key, (String)value, (String)key);
 205  0
                     } else if (value instanceof Collection && !((Collection)value).isEmpty()) {
 206  
                             // we're doing multi-select search; so we need to loop through all of the Strings
 207  
                             // we've been handed and validate each of them
 208  0
                             for (Object v : ((Collection)value)) {
 209  0
                                     if (v instanceof String) {
 210  0
                                             validationService.validateAttributeFormat(searchContext.getDocumentTypeName(), (String)key, (String)v, (String)key);
 211  
                                     }
 212  
                             }
 213  
                     }
 214  
             }
 215  0
         }
 216  
 
 217  0
         if(GlobalVariables.getMessageMap().hasErrors()){
 218  0
                 validationErrors = new ArrayList<WorkflowAttributeValidationError>();
 219  0
                 MessageMap deepCopy = (MessageMap)ObjectUtils.deepCopy(GlobalVariables.getMessageMap()); 
 220  0
                 validationErrors.add(new WorkflowAttributeValidationError(null,null,deepCopy));
 221  
                 // we should now strip the error messages from the map because they have moved to validationErrors
 222  0
                 GlobalVariables.getMessageMap().clearErrorMessages();
 223  
         }
 224  
 
 225  
 
 226  0
         return validationErrors;
 227  
     }
 228  
 
 229  
     /**
 230  
      * Creates a list of search fields, one for each primary key of the maintained business object
 231  
      * @param businessObjectClass the class of the maintained business object
 232  
      * @return a List of KEW search fields
 233  
      */
 234  
     protected List<Row> createFieldRowsForWorkflowAttributes(WorkflowAttributes attrs) {
 235  0
         List<Row> searchFields = new ArrayList<Row>();
 236  
 
 237  0
         List<SearchingTypeDefinition> searchingTypeDefinitions = attrs.getSearchingTypeDefinitions();
 238  0
         final WorkflowAttributePropertyResolutionService propertyResolutionService = KNSServiceLocatorInternal.getWorkflowAttributePropertyResolutionService();
 239  0
         for (SearchingTypeDefinition definition: searchingTypeDefinitions) {
 240  0
             SearchingAttribute attr = definition.getSearchingAttribute();
 241  
 
 242  0
             final String attributeName = attr.getAttributeName();
 243  0
             final String businessObjectClassName = attr.getBusinessObjectClassName();
 244  0
             Class boClass = null;
 245  0
             BusinessObject businessObject  = null;
 246  
             try {
 247  0
                 boClass = Class.forName(businessObjectClassName);
 248  0
                 businessObject = (BusinessObject)boClass.newInstance();
 249  0
             } catch (Exception e) {
 250  0
                 throw new RuntimeException(e);
 251  0
             }
 252  
 
 253  0
             Field searchField = FieldUtils.getPropertyField(boClass, attributeName, false);
 254  0
             searchField.setColumnVisible(attr.isShowAttributeInResultSet());
 255  
 
 256  
             //TODO this is a workaround to hide the Field from the search criteria.
 257  
             //This should be removed once hiding the entire Row is working
 258  0
             if (!attr.isShowAttributeInSearchCriteria()){
 259  0
                 searchField.setFieldType(Field.HIDDEN);
 260  
             }
 261  0
             String fieldDataType = propertyResolutionService.determineFieldDataType(boClass, attributeName);
 262  0
             if (fieldDataType.equals(DataDictionarySearchableAttribute.DATA_TYPE_BOOLEAN)) {
 263  0
                 fieldDataType = KEWConstants.SearchableAttributeConstants.DATA_TYPE_STRING;
 264  
             }
 265  
 
 266  
             // Allow inline range searching on dates and numbers
 267  0
             if (fieldDataType.equals(KEWConstants.SearchableAttributeConstants.DATA_TYPE_FLOAT) ||
 268  
                 fieldDataType.equals(KEWConstants.SearchableAttributeConstants.DATA_TYPE_LONG) ||
 269  
                 fieldDataType.equals(KEWConstants.SearchableAttributeConstants.DATA_TYPE_DATE)) {
 270  
 
 271  0
                 searchField.setAllowInlineRange(true);
 272  
             }
 273  0
             searchField.setFieldDataType(fieldDataType);
 274  0
             List displayedFieldNames = new ArrayList();
 275  0
             displayedFieldNames.add(attributeName);
 276  0
             LookupUtils.setFieldQuickfinder(businessObject, attributeName, searchField, displayedFieldNames);
 277  
 
 278  0
             List<Field> fieldList = new ArrayList<Field>();
 279  0
             fieldList.add(searchField);
 280  
 
 281  0
             Row row = new Row(fieldList);
 282  0
             if (!attr.isShowAttributeInSearchCriteria()) {
 283  0
                 row.setHidden(true);
 284  
             }
 285  0
             searchFields.add(row);
 286  0
         }
 287  
 
 288  0
         return searchFields;
 289  
     }
 290  
 
 291  
 
 292  
     /**
 293  
      *
 294  
      * @param businessObjectClass
 295  
      * @param documentContent
 296  
      * @return
 297  
      */
 298  
     protected List<SearchableAttributeValue> parsePrimaryKeyValuesFromDocument(Class<? extends BusinessObject> businessObjectClass, MaintenanceDocument document) {
 299  0
         List<SearchableAttributeValue> values = new ArrayList<SearchableAttributeValue>();
 300  
 
 301  0
         final List primaryKeyNames = KNSServiceLocatorWeb.getBusinessObjectMetaDataService().listPrimaryKeyFieldNames(businessObjectClass);
 302  
 
 303  0
         for (Object primaryKeyNameAsObj : primaryKeyNames) {
 304  0
             final String primaryKeyName = (String)primaryKeyNameAsObj;
 305  0
             final SearchableAttributeValue searchableValue = parseSearchableAttributeValueForPrimaryKey(primaryKeyName, businessObjectClass, document);
 306  0
             if (searchableValue != null) {
 307  0
                 values.add(searchableValue);
 308  
             }
 309  0
         }
 310  0
         return values;
 311  
     }
 312  
 
 313  
     /**
 314  
      * Creates a searchable attribute value for the given property name out of the document XML
 315  
      * @param propertyName the name of the property to return
 316  
      * @param businessObjectClass the class of the business object maintained
 317  
      * @param document the document XML
 318  
      * @return a generated SearchableAttributeValue, or null if a value could not be created
 319  
      */
 320  
     protected SearchableAttributeValue parseSearchableAttributeValueForPrimaryKey(String propertyName, Class<? extends BusinessObject> businessObjectClass, MaintenanceDocument document) {
 321  
 
 322  0
         Maintainable maintainable  = document.getNewMaintainableObject();
 323  0
         PersistableBusinessObject bo = maintainable.getBusinessObject();
 324  
 
 325  0
         final Object propertyValue = ObjectUtils.getPropertyValue(bo, propertyName);
 326  0
         if (propertyValue == null) return null;
 327  
 
 328  0
         final WorkflowAttributePropertyResolutionService propertyResolutionService = KNSServiceLocatorInternal.getWorkflowAttributePropertyResolutionService();
 329  0
         SearchableAttributeValue value = propertyResolutionService.buildSearchableAttribute(businessObjectClass, propertyName, propertyValue);
 330  0
         return value;
 331  
     }
 332  
 
 333  
     /**
 334  
      * Returns the class of the object being maintained by the given maintenance document type name
 335  
      * @param documentTypeName the name of the document type to look up the maintained business object for
 336  
      * @return the class of the maintained business object
 337  
      */
 338  
     protected Class<? extends BusinessObject> getBusinessObjectClass(String documentTypeName) {
 339  0
         MaintenanceDocumentEntry entry = retrieveMaintenanceDocumentEntry(documentTypeName);
 340  0
         return (entry == null ? null : entry.getBusinessObjectClass());
 341  
     }
 342  
 
 343  
     /**
 344  
      * Returns the maintainable of the object being maintained by the given maintenance document type name
 345  
      * @param documentTypeName the name of the document type to look up the maintained business object for
 346  
      * @return the Maintainable of the maintained business object
 347  
      */
 348  
     protected Class<? extends Maintainable> getMaintainableClass(String documentTypeName) {
 349  0
         MaintenanceDocumentEntry entry = retrieveMaintenanceDocumentEntry(documentTypeName);
 350  0
         return (entry == null ? null : entry.getMaintainableClass());
 351  
     }
 352  
 
 353  
 
 354  
     /**
 355  
      * Retrieves the maintenance document entry for the given document type name
 356  
      * @param documentTypeName the document type name to look up the data dictionary document entry for
 357  
      * @return the corresponding data dictionary entry for a maintenance document
 358  
      */
 359  
     protected MaintenanceDocumentEntry retrieveMaintenanceDocumentEntry(String documentTypeName) {
 360  0
         return (MaintenanceDocumentEntry) KNSServiceLocatorWeb.getDataDictionaryService().getDataDictionary().getDocumentEntry(documentTypeName);
 361  
     }
 362  
 
 363  
     /**
 364  
      *
 365  
      * @param documentNumber
 366  
      * @param businessObjectClass
 367  
      * @param document
 368  
      * @return
 369  
      */
 370  
     protected GlobalBusinessObject retrieveGlobalBusinessObject(String documentNumber, Class<? extends BusinessObject> businessObjectClass) {
 371  0
         GlobalBusinessObject globalBO = null;
 372  
 
 373  0
         Map pkMap = new LinkedHashMap();
 374  0
         pkMap.put(KNSPropertyConstants.DOCUMENT_NUMBER, documentNumber);
 375  
 
 376  0
         List returnedBOs = (List) KNSServiceLocator.getBusinessObjectService().findMatching(businessObjectClass, pkMap);
 377  0
         if (returnedBOs.size() > 0) {
 378  0
             globalBO = (GlobalBusinessObject)returnedBOs.get(0);
 379  
         }
 380  
 
 381  0
         return globalBO;
 382  
     }
 383  
 
 384  
     /**
 385  
      *
 386  
      * @param globalBO
 387  
      * @return
 388  
      */
 389  
     protected List<SearchableAttributeValue> findAllSearchableAttributesForGlobalBusinessObject(GlobalBusinessObject globalBO) {
 390  0
         List<SearchableAttributeValue> searchValues = new ArrayList<SearchableAttributeValue>();
 391  
 
 392  0
         for (PersistableBusinessObject bo : globalBO.generateGlobalChangesToPersist()) {
 393  0
             SearchableAttributeValue value = generateSearchableAttributeFromChange(bo);
 394  0
             if (value != null) {
 395  0
                 searchValues.add(value);
 396  
             }
 397  0
         }
 398  
 
 399  0
         return searchValues;
 400  
     }
 401  
 
 402  
     /**
 403  
      *
 404  
      * @param changeToPersist
 405  
      * @return
 406  
      */
 407  
     protected SearchableAttributeValue generateSearchableAttributeFromChange(PersistableBusinessObject changeToPersist) {
 408  0
         List primaryKeyNames = KNSServiceLocatorWeb.getBusinessObjectMetaDataService().listPrimaryKeyFieldNames(changeToPersist.getClass());
 409  
 
 410  0
         for (Object primaryKeyNameAsObject : primaryKeyNames) {
 411  0
             String primaryKeyName = (String)primaryKeyNameAsObject;
 412  0
             Object value = ObjectUtils.getPropertyValue(changeToPersist, primaryKeyName);
 413  
 
 414  0
             if (value != null) {
 415  
 
 416  0
                 final WorkflowAttributePropertyResolutionService propertyResolutionService = KNSServiceLocatorInternal.getWorkflowAttributePropertyResolutionService();
 417  0
                 SearchableAttributeValue saValue = propertyResolutionService.buildSearchableAttribute(changeToPersist.getClass(), primaryKeyName, value);
 418  0
                 return saValue;
 419  
 
 420  
             }
 421  0
         }
 422  0
         return null;
 423  
     }
 424  
 
 425  
     /**
 426  
      * Creates a list of search fields, one for each primary key of the maintained business object
 427  
      * @param businessObjectClass the class of the maintained business object
 428  
      * @return a List of KEW search fields
 429  
      */
 430  
     protected List<Row> createFieldRowsForBusinessObject(Class<? extends BusinessObject> businessObjectClass) {
 431  0
         List<Row> searchFields = new ArrayList<Row>();
 432  
 
 433  0
         final List primaryKeyNamesAsObjects = KNSServiceLocatorWeb.getBusinessObjectMetaDataService().listPrimaryKeyFieldNames(businessObjectClass);
 434  0
         final BusinessObjectEntry boEntry = KNSServiceLocatorWeb.getDataDictionaryService().getDataDictionary().getBusinessObjectEntry(businessObjectClass.getName());
 435  0
         final WorkflowAttributePropertyResolutionService propertyResolutionService = KNSServiceLocatorInternal.getWorkflowAttributePropertyResolutionService();
 436  0
         for (Object primaryKeyNameAsObject : primaryKeyNamesAsObjects) {
 437  
 
 438  0
             String attributeName =  (String)primaryKeyNameAsObject;
 439  0
             BusinessObject businessObject = null;
 440  
             try {
 441  0
                 businessObject = businessObjectClass.newInstance();
 442  0
             } catch (Exception e) {
 443  0
                 throw new RuntimeException(e);
 444  0
             }
 445  
 
 446  0
             Field searchField = FieldUtils.getPropertyField(businessObjectClass, attributeName, false);
 447  0
             String dataType = propertyResolutionService.determineFieldDataType(businessObjectClass, attributeName);
 448  0
             searchField.setFieldDataType(dataType);
 449  0
             List<Field> fieldList = new ArrayList<Field>();
 450  
 
 451  0
             List displayedFieldNames = new ArrayList();
 452  0
             displayedFieldNames.add(attributeName);
 453  0
             LookupUtils.setFieldQuickfinder(businessObject, attributeName, searchField, displayedFieldNames);
 454  
 
 455  0
             fieldList.add(searchField);
 456  0
             searchFields.add(new Row(fieldList));
 457  0
         }
 458  
 
 459  0
         return searchFields;
 460  
     }
 461  
 
 462  
 }