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