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