/**
   * Produces legacy KNS rows to use for search attributes. This method was left intact to help ease
   * conversion until KNS is replaced with KRAD.
   */
  protected List<Row> getSearchingRows(String documentTypeName) {

    List<Row> docSearchRows = new ArrayList<Row>();

    Class boClass = DocumentHeader.class;

    Field descriptionField = FieldUtils.getPropertyField(boClass, "documentDescription", true);
    descriptionField.setFieldDataType(
        KewApiConstants.SearchableAttributeConstants.DATA_TYPE_STRING);

    Field orgDocNumberField =
        FieldUtils.getPropertyField(boClass, "organizationDocumentNumber", true);
    orgDocNumberField.setFieldDataType(
        KewApiConstants.SearchableAttributeConstants.DATA_TYPE_STRING);

    List<Field> fieldList = new ArrayList<Field>();
    fieldList.add(descriptionField);
    docSearchRows.add(new Row(fieldList));

    fieldList = new ArrayList<Field>();
    fieldList.add(orgDocNumberField);
    docSearchRows.add(new Row(fieldList));

    DocumentEntry entry =
        KRADServiceLocatorWeb.getDataDictionaryService()
            .getDataDictionary()
            .getDocumentEntry(documentTypeName);
    if (entry == null) return docSearchRows;
    if (entry instanceof MaintenanceDocumentEntry) {
      Class<? extends BusinessObject> businessObjectClass =
          getBusinessObjectClass(documentTypeName);
      Class<? extends Maintainable> maintainableClass = getMaintainableClass(documentTypeName);

      KualiGlobalMaintainableImpl globalMaintainable = null;
      try {
        globalMaintainable = (KualiGlobalMaintainableImpl) maintainableClass.newInstance();
        businessObjectClass = globalMaintainable.getPrimaryEditedBusinessObjectClass();
      } catch (Exception ie) {
        // was not a globalMaintainable.
      }

      if (businessObjectClass != null)
        docSearchRows.addAll(createFieldRowsForBusinessObject(businessObjectClass));
    }

    WorkflowAttributes workflowAttributes = entry.getWorkflowAttributes();
    if (workflowAttributes != null)
      docSearchRows.addAll(createFieldRowsForWorkflowAttributes(workflowAttributes));

    return docSearchRows;
  }
  /**
   * Creates a list of search fields, one for each primary key of the maintained business object
   *
   * @param businessObjectClass the class of the maintained business object
   * @return a List of KEW search fields
   */
  protected List<Row> createFieldRowsForBusinessObject(
      Class<? extends BusinessObject> businessObjectClass) {
    List<Row> searchFields = new ArrayList<Row>();

    final List primaryKeyNamesAsObjects =
        KRADServiceLocatorWeb.getLegacyDataAdapter().listPrimaryKeyFieldNames(businessObjectClass);
    final BusinessObjectEntry boEntry =
        KRADServiceLocatorWeb.getDataDictionaryService()
            .getDataDictionary()
            .getBusinessObjectEntry(businessObjectClass.getName());
    final WorkflowAttributePropertyResolutionService propertyResolutionService =
        KNSServiceLocator.getWorkflowAttributePropertyResolutionService();
    for (Object primaryKeyNameAsObject : primaryKeyNamesAsObjects) {

      String attributeName = (String) primaryKeyNameAsObject;
      BusinessObject businessObject = null;
      try {
        businessObject = businessObjectClass.newInstance();
      } catch (Exception e) {
        throw new RuntimeException(e);
      }

      Field searchField = FieldUtils.getPropertyField(businessObjectClass, attributeName, false);
      String dataType =
          propertyResolutionService.determineFieldDataType(businessObjectClass, attributeName);
      searchField.setFieldDataType(dataType);
      List<Field> fieldList = new ArrayList<Field>();

      List displayedFieldNames = new ArrayList();
      displayedFieldNames.add(attributeName);
      LookupUtils.setFieldQuickfinder(
          businessObject, attributeName, searchField, displayedFieldNames);

      fieldList.add(searchField);
      searchFields.add(new Row(fieldList));
    }

    return searchFields;
  }
  protected List<Row> createFieldRowsForWorkflowAttributes(WorkflowAttributes attrs) {
    List<Row> searchFields = new ArrayList<Row>();

    List<SearchingTypeDefinition> searchingTypeDefinitions = attrs.getSearchingTypeDefinitions();
    final WorkflowAttributePropertyResolutionService propertyResolutionService =
        KNSServiceLocator.getWorkflowAttributePropertyResolutionService();
    for (SearchingTypeDefinition definition : searchingTypeDefinitions) {
      SearchingAttribute attr = definition.getSearchingAttribute();

      final String attributeName = attr.getAttributeName();
      final String businessObjectClassName = attr.getBusinessObjectClassName();
      Class boClass = null;
      Object businessObject = null;
      try {
        boClass = Class.forName(businessObjectClassName);
        businessObject = (Object) boClass.newInstance();
      } catch (Exception e) {
        throw new RuntimeException(e);
      }

      Field searchField = FieldUtils.getPropertyField(boClass, attributeName, false);
      // prepend all document attribute field names with "documentAttribute."
      // searchField.setPropertyName(KewApiConstants.DOCUMENT_ATTRIBUTE_FIELD_PREFIX +
      // searchField.getPropertyName());
      searchField.setColumnVisible(attr.isShowAttributeInResultSet());

      // TODO this is a workaround to hide the Field from the search criteria.
      // This should be removed once hiding the entire Row is working
      if (!attr.isShowAttributeInSearchCriteria()) {
        searchField.setFieldType(Field.HIDDEN);
      }
      String fieldDataType =
          propertyResolutionService.determineFieldDataType(boClass, attributeName);
      if (fieldDataType.equals(DataDictionarySearchableAttribute.DATA_TYPE_BOOLEAN)) {
        fieldDataType = KewApiConstants.SearchableAttributeConstants.DATA_TYPE_STRING;
      }

      // Allow inline range searching on dates and numbers
      if (fieldDataType.equals(KewApiConstants.SearchableAttributeConstants.DATA_TYPE_FLOAT)
          || fieldDataType.equals(KewApiConstants.SearchableAttributeConstants.DATA_TYPE_LONG)
          || fieldDataType.equals(KewApiConstants.SearchableAttributeConstants.DATA_TYPE_DATE)) {

        searchField.setAllowInlineRange(true);
      }
      searchField.setFieldDataType(fieldDataType);
      List displayedFieldNames = new ArrayList();
      displayedFieldNames.add(attributeName);
      LookupUtils.setFieldQuickfinder(
          businessObject, attributeName, searchField, displayedFieldNames);

      List<Field> fieldList = new ArrayList<Field>();
      fieldList.add(searchField);

      Row row = new Row(fieldList);
      if (!attr.isShowAttributeInSearchCriteria()) {
        row.setHidden(true);
      }
      searchFields.add(row);
    }

    return searchFields;
  }