Coverage Report - org.kuali.rice.kns.uif.service.impl.LookupViewHelperServiceImpl
 
Classes in this File Line Coverage Branch Coverage Complexity
LookupViewHelperServiceImpl
0%
0/459
0%
0/248
2.841
 
 1  
 /*
 2  
  * Copyright 2011 The Kuali Foundation
 3  
  *
 4  
  * Licensed under the Educational Community License, Version 1.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/ecl1.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.uif.service.impl;
 17  
 
 18  
 import java.security.GeneralSecurityException;
 19  
 import java.sql.Date;
 20  
 import java.util.ArrayList;
 21  
 import java.util.Collection;
 22  
 import java.util.Collections;
 23  
 import java.util.HashMap;
 24  
 import java.util.HashSet;
 25  
 import java.util.Iterator;
 26  
 import java.util.List;
 27  
 import java.util.Map;
 28  
 import java.util.Properties;
 29  
 import java.util.Set;
 30  
 
 31  
 import org.apache.commons.beanutils.PropertyUtils;
 32  
 import org.apache.commons.lang.BooleanUtils;
 33  
 import org.apache.commons.lang.StringUtils;
 34  
 import org.kuali.rice.core.api.encryption.EncryptionService;
 35  
 import org.kuali.rice.core.api.services.CoreApiServiceLocator;
 36  
 import org.kuali.rice.core.util.RiceKeyConstants;
 37  
 import org.kuali.rice.core.util.type.TypeUtils;
 38  
 import org.kuali.rice.core.web.format.DateFormatter;
 39  
 import org.kuali.rice.core.web.format.Formatter;
 40  
 import org.kuali.rice.kim.bo.Person;
 41  
 import org.kuali.rice.kns.authorization.BusinessObjectRestrictions;
 42  
 import org.kuali.rice.kns.bo.ExternalizableBusinessObject;
 43  
 import org.kuali.rice.kns.datadictionary.BusinessObjectEntry;
 44  
 import org.kuali.rice.kns.datadictionary.RelationshipDefinition;
 45  
 import org.kuali.rice.kns.exception.ValidationException;
 46  
 import org.kuali.rice.kns.lookup.HtmlData;
 47  
 import org.kuali.rice.kns.lookup.HtmlData.AnchorHtmlData;
 48  
 import org.kuali.rice.kns.lookup.LookupUtils;
 49  
 import org.kuali.rice.kns.service.BusinessObjectAuthorizationService;
 50  
 import org.kuali.rice.kns.service.BusinessObjectDictionaryService;
 51  
 import org.kuali.rice.kns.service.DataObjectMetaDataService;
 52  
 import org.kuali.rice.kns.service.KNSServiceLocator;
 53  
 import org.kuali.rice.kns.service.KNSServiceLocatorWeb;
 54  
 import org.kuali.rice.kns.service.LookupService;
 55  
 import org.kuali.rice.kns.service.MaintenanceDocumentDictionaryService;
 56  
 import org.kuali.rice.kns.service.ModuleService;
 57  
 import org.kuali.rice.kns.service.PersistenceStructureService;
 58  
 import org.kuali.rice.kns.uif.UifConstants;
 59  
 import org.kuali.rice.kns.uif.UifParameters;
 60  
 import org.kuali.rice.kns.uif.container.LookupView;
 61  
 import org.kuali.rice.kns.uif.container.View;
 62  
 import org.kuali.rice.kns.uif.core.Component;
 63  
 import org.kuali.rice.kns.uif.field.AttributeField;
 64  
 import org.kuali.rice.kns.uif.field.GeneratedField;
 65  
 import org.kuali.rice.kns.uif.field.LookupCriteriaAttributeField;
 66  
 import org.kuali.rice.kns.uif.service.LookupViewHelperService;
 67  
 import org.kuali.rice.kns.util.BeanPropertyComparator;
 68  
 import org.kuali.rice.kns.util.ExternalizableBusinessObjectUtils;
 69  
 import org.kuali.rice.kns.util.GlobalVariables;
 70  
 import org.kuali.rice.kns.util.KNSConstants;
 71  
 import org.kuali.rice.kns.util.ObjectUtils;
 72  
 import org.kuali.rice.kns.util.UrlFactory;
 73  
 import org.kuali.rice.kns.web.spring.controller.MaintenanceDocumentController;
 74  
 import org.springframework.web.util.HtmlUtils;
 75  
 
 76  
 /**
 77  
  * @author Kuali Rice Team (rice.collab@kuali.org)
 78  
  */
 79  
 public class LookupViewHelperServiceImpl extends ViewHelperServiceImpl implements LookupViewHelperService {
 80  0
         protected static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(LookupViewHelperServiceImpl.class);
 81  
 
 82  
         public static final String TITLE_RETURN_URL_PREPENDTEXT_PROPERTY = "title.return.url.value.prependtext";
 83  
         public static final String TITLE_ACTION_URL_PREPENDTEXT_PROPERTY = "title.action.url.value.prependtext";
 84  
         public static final String ACTION_URLS_CHILDREN_SEPARATOR = " | ";
 85  
         public static final String ACTION_URLS_CHILDREN_STARTER = " [";
 86  
         public static final String ACTION_URLS_CHILDREN_END = "]";
 87  
         public static final String ACTION_URLS_SEPARATOR = "  ";
 88  
         public static final String ACTION_URLS_EMPTY = " ";
 89  
 
 90  
         private transient LookupService lookupService;
 91  
         // TODO delyea - investigate if encryptionService is even needed due to new spring binding
 92  
         private transient EncryptionService encryptionService;
 93  
         private transient BusinessObjectDictionaryService businessObjectDictionaryService;
 94  
         private transient DataObjectMetaDataService dataObjectMetaDataService;
 95  
         private transient MaintenanceDocumentDictionaryService maintenanceDocumentDictionaryService;
 96  
         private transient BusinessObjectAuthorizationService businessObjectAuthorizationService;
 97  
         private transient PersistenceStructureService persistenceStructureService;
 98  
 
 99  
         protected Class<?> dataObjectClass;
 100  
         protected String returnLocation;
 101  
         protected String returnFormKey;
 102  
         protected String docNum;
 103  
         protected String referencesToRefresh;
 104  0
         protected boolean searchUsingOnlyPrimaryKeyValues = false;
 105  
         protected Map<String, String> fieldConversions;
 106  
         protected Map parameters;
 107  
         protected List<String> readOnlyFieldsList;
 108  0
         protected boolean atLeastOneRowReturnable = false;
 109  0
     protected boolean atLeastOneRowHasActions = false;
 110  
 
 111  
         protected List<String> defaultSortAttributeNames;
 112  
         // TODO delyea: where to take into account the sort ascending value (old KNS appeared to ignore?)
 113  
         protected boolean sortAscending;
 114  
 
 115  
         /**
 116  
          * Default Constructor
 117  
          * 
 118  
          */
 119  
         public LookupViewHelperServiceImpl() {
 120  0
                 super();
 121  0
         }
 122  
 
 123  
         /**
 124  
      * @see org.kuali.rice.kns.uif.service.impl.ViewHelperServiceImpl#populateViewFromRequestParameters(org.kuali.rice.kns.uif.container.View, java.util.Map)
 125  
      */
 126  
     @Override
 127  
     public void populateViewFromRequestParameters(View view, Map<String, String> parameters) {
 128  0
             super.populateViewFromRequestParameters(view, parameters);
 129  
             /* On the old Lookupable and LookupableHelperService in KNS the parameters list used to have multipart form
 130  
              * data in it where it may not in the new KRAD. See PojoFormBase.populate() method for more information
 131  
              */
 132  0
             setParameters(parameters);
 133  0
     }
 134  
 
 135  
         /**
 136  
          * Initialization of Lookupable requires that the business object class be set for the {@link #initializeAttributeFieldFromDataDictionary(View, AttributeField)} method
 137  
          * 
 138  
          * @see org.kuali.rice.kns.uif.service.impl.ViewHelperServiceImpl#performInitialization(org.kuali.rice.kns.uif.container.View)
 139  
          */
 140  
         @Override
 141  
         public void performInitialization(View view) {
 142  0
                 if (!LookupView.class.isAssignableFrom(view.getClass())) {
 143  0
                         throw new IllegalArgumentException("View class '" + view.getClass() + " is not assignable from the '" + LookupView.class + "'");
 144  
                 }
 145  0
                 LookupView lookupView = (LookupView) view;
 146  0
                 initializeLookupViewHelperService(lookupView);
 147  0
                 super.performInitialization(view);
 148  0
         }
 149  
 
 150  
         protected void initializeLookupViewHelperService(LookupView lookupView) {
 151  0
                 setDefaultSortAttributeNames(lookupView.getDefaultSortAttributeNames());
 152  0
                 setSortAscending(lookupView.isSortAscending());
 153  0
                 setDataObjectClass(lookupView.getDataObjectClassName());
 154  0
         }
 155  
 
 156  
         /**
 157  
          * After initial Data Dictionary initialization of an {@link AttributeField} , the binding path will need to be changed if the initial 'binding object path' is set to
 158  
          * {@link UifConstants.LookupModelPropertyNames#CRITERIA_FIELDS}. The exact 'binding path' that needs to be set will be to convert a nested property path to one that allows for mapping to a
 159  
          * {@link Map} object.
 160  
          * 
 161  
          * eg: If the existing 'binding object path' is set to 'criteriaMap' and the 'binding name' is 'subAccount' then the default 'binding path' will be 'criteriaMap.subAccount'. In the case of lookups
 162  
          * we need the 'binding path' to be set to 'criteriaMap[subAccount]'.
 163  
          * 
 164  
          * @see org.kuali.rice.kns.uif.service.impl.ViewHelperServiceImpl#initializeAttributeFieldFromDataDictionary(org.kuali.rice.kns.uif.container.View, org.kuali.rice.kns.uif.field.AttributeField)
 165  
          */
 166  
         @Override
 167  
         protected void initializeAttributeFieldFromDataDictionary(View view, AttributeField field) {
 168  0
                 super.initializeAttributeFieldFromDataDictionary(view, field);
 169  
                 
 170  
 //                if (StringUtils.equals(UifPropertyPaths.CRITERIA_FIELDS, field.getBindingInfo().getBindingObjectPath())) {
 171  
 //                        field.getBindingInfo().setBindingPath(field.getBindingInfo().getBindingObjectPath() + "[" + field.getBindingInfo().getBindingName() + "]");
 172  
 //                }
 173  0
         }
 174  
 
 175  
         /**
 176  
          * When the dictionary model class is retrieved for an AttributeField where the BindingObjectPath is equal to the {@link org.kuali.rice.kns.web.spring.form.LookupForm} criteria fields object...
 177  
          * the BusinessObjectClass needs to be returned to fetch the proper data dictionary entry.
 178  
          * 
 179  
          * @see org.kuali.rice.kns.uif.service.impl.ViewHelperServiceImpl#getDictionaryModelClass(org.kuali.rice.kns.uif.container.View, org.kuali.rice.kns.uif.field.AttributeField)
 180  
          */
 181  
 //        @Override
 182  
 //        protected Class<?> getDictionaryModelClass(View view, AttributeField field) {
 183  
 //                // if the field binding object path matches the map name on the
 184  
 //                // LookupForm model then use BO class rather than looking up dictionary
 185  
 //                // model class
 186  
 //                if (StringUtils.equals(UifPropertyPaths.CRITERIA_FIELDS, field.getBindingInfo().getBindingObjectPath())) {
 187  
 //                        return getDataObjectClass();
 188  
 //                }
 189  
 //                
 190  
 //                return ViewModelUtils.getPropertyType(view, field.getBindingInfo().getBindingObjectPath());
 191  
 //        }
 192  
 
 193  
         /**
 194  
          * @see org.kuali.rice.kns.uif.service.LookupViewHelperService#validateSearchParameters(java.util.List, java.util.Map)
 195  
          */
 196  
         public void validateSearchParameters(List<? extends Component> criteriaComponents, Map<String, String> fieldValues) {
 197  0
                 if (!getViewDictionaryService().isLookupable(getDataObjectClass())) {
 198  0
                         throw new RuntimeException("Lookup not defined for data object " + getDataObjectClass());
 199  
                 }
 200  0
                 for (Component component : criteriaComponents) {
 201  0
                 if (AttributeField.class.isAssignableFrom(component.getClass())) {
 202  0
                         AttributeField attributeField = (AttributeField) component;
 203  0
                                 if (fieldValues.containsKey(attributeField.getPropertyName())) {
 204  0
                                         String attributeValue = fieldValues.get(attributeField.getPropertyName());
 205  
 
 206  
                                         // check for required if field does not have value
 207  0
                                         if (StringUtils.isBlank(attributeValue)) {
 208  0
                                                 if (BooleanUtils.isTrue(attributeField.getRequired())) {
 209  0
                                                         GlobalVariables.getMessageMap().putError(attributeField.getPropertyName(), RiceKeyConstants.ERROR_REQUIRED, attributeField.getLabel());
 210  
                                                 }
 211  
                                         }
 212  0
                                         validateSearchParameterWildcardAndOperators(attributeField, attributeValue);
 213  
                                 }
 214  0
                 }
 215  
         }
 216  
 
 217  0
                 if (GlobalVariables.getMessageMap().hasErrors()) {
 218  0
                         throw new ValidationException("errors in search criteria");
 219  
                 }
 220  0
         }
 221  
 
 222  
         protected void validateSearchParameterWildcardAndOperators(AttributeField attributeField, String attributeValue) {
 223  0
                 if (StringUtils.isBlank(attributeValue))
 224  0
                         return;
 225  
 
 226  
                 // make sure a wildcard/operator is in the value
 227  0
                 boolean found = false;
 228  0
                 for (int i = 0; i < KNSConstants.QUERY_CHARACTERS.length; i++) {
 229  0
                         String queryCharacter = KNSConstants.QUERY_CHARACTERS[i];
 230  
 
 231  0
                         if (attributeValue.contains(queryCharacter)) {
 232  0
                                 found = true;
 233  
                         }
 234  
                 }
 235  0
                 if (!found)
 236  0
                         return;
 237  
 
 238  0
                 String attributeLabel = getDataDictionaryService().getAttributeLabel(getDataObjectClass(), attributeField.getPropertyName());
 239  0
                 if ( (LookupCriteriaAttributeField.class.isAssignableFrom(attributeField.getClass())) &&
 240  
                          (((LookupCriteriaAttributeField) attributeField).isTreatWildcardsAndOperatorsAsLiteral())
 241  
                         ) {
 242  0
                         Object dataObjectExample = null;
 243  
                         try {
 244  0
                                 dataObjectExample = getDataObjectClass().newInstance();
 245  0
                         } catch (Exception e) {
 246  0
                                 LOG.error("Exception caught instantiating " + getDataObjectClass().getName(), e);
 247  0
                                 throw new RuntimeException("Cannot instantiate " + getDataObjectClass().getName(), e);
 248  0
                         }
 249  
 
 250  0
                         Class<?> propertyType = ObjectUtils.getPropertyType(dataObjectExample, attributeField.getPropertyName(), getPersistenceStructureService());
 251  0
                         if (TypeUtils.isIntegralClass(propertyType) || TypeUtils.isDecimalClass(propertyType) || TypeUtils.isTemporalClass(propertyType)) {
 252  0
                                 GlobalVariables.getMessageMap().putError(attributeField.getPropertyName(), RiceKeyConstants.ERROR_WILDCARDS_AND_OPERATORS_NOT_ALLOWED_ON_FIELD, attributeLabel);
 253  
                         }
 254  0
                         if (TypeUtils.isStringClass(propertyType)) {
 255  0
                                 GlobalVariables.getMessageMap().putInfo(attributeField.getPropertyName(), RiceKeyConstants.INFO_WILDCARDS_AND_OPERATORS_TREATED_LITERALLY, attributeLabel);
 256  
                         }
 257  0
                 } else {
 258  0
                         if (getBusinessObjectAuthorizationService().attributeValueNeedsToBeEncryptedOnFormsAndLinks(getDataObjectClass(), attributeField.getPropertyName())) {
 259  0
                                 if (!attributeValue.endsWith(EncryptionService.ENCRYPTION_POST_PREFIX)) {
 260  
                                         // encrypted values usually come from the DB, so we don't
 261  
                                         // need to filter for wildcards
 262  
 
 263  
                                         // wildcards are not allowed on restricted fields, because
 264  
                                         // they are typically encrypted, and wildcard searches
 265  
                                         // cannot be performed without
 266  
                                         // decrypting every row, which is currently not supported by
 267  
                                         // KNS
 268  
 
 269  0
                                         GlobalVariables.getMessageMap().putError(attributeField.getPropertyName(), RiceKeyConstants.ERROR_SECURE_FIELD, attributeLabel);
 270  
                                 }
 271  
                         }
 272  
                 }
 273  0
         }
 274  
 
 275  
         /**
 276  
          * @see org.kuali.rice.kns.uif.service.LookupViewHelperService#performClear(java.util.Map)
 277  
          */
 278  
         public Map<String, String> performClear(Map<String, String> fieldsForLookup) {
 279  0
                 Map<String, String> newFieldsForLookup = new HashMap<String, String>();
 280  0
                 if (fieldsForLookup != null) {
 281  0
                         for (Map.Entry<String, String> entry : fieldsForLookup.entrySet()) {
 282  
                                 // check here to see if this field is a criteria element on the form
 283  0
                                 newFieldsForLookup.put(entry.getKey(), null);
 284  
                         }
 285  
                 }
 286  0
                 return newFieldsForLookup;
 287  
         }
 288  
 
 289  
         /**
 290  
          * @see org.kuali.rice.kns.uif.service.LookupViewHelperService#performSearch(java.util.Map, boolean)
 291  
          */
 292  
         public Collection<?> performSearch(Map<String, String> criteriaFieldsForLookup, boolean bounded) {
 293  
                 Collection<?> displayList;
 294  
 
 295  0
                 preprocessDateFields(criteriaFieldsForLookup);
 296  
 
 297  
                 // TODO delyea: switch the bounded flag to be unbounded to match underlying method calls in getSearchResultsWithBounding()
 298  0
                 displayList = getSearchResultsWithBounding(LookupUtils.forceUppercase(getDataObjectClass(), criteriaFieldsForLookup), !bounded);
 299  
                 
 300  
                 // TODO delyea - is this the best way to set that the entire set has a returnable row?
 301  0
                 List<String> pkNames = getDataObjectMetaDataService().listPrimaryKeyFieldNames(getDataObjectClass());
 302  0
                 Person user = GlobalVariables.getUserSession().getPerson();
 303  0
                 for (Object object : displayList) {
 304  0
                 if (isResultReturnable(object)) {
 305  0
                         setAtLeastOneRowReturnable(true);
 306  
                 }
 307  0
                 BusinessObjectRestrictions dataObjectRestrictions = getBusinessObjectAuthorizationService().getLookupResultRestrictions(object, user);
 308  0
                 String actionUrls = getActionUrls(object, pkNames, dataObjectRestrictions);
 309  0
                         if (StringUtils.isNotBlank(HtmlUtils.htmlUnescape(actionUrls).replace('\u00A0', '\u0020'))) {
 310  0
                                 setAtLeastOneRowHasActions(true);
 311  
                         }
 312  0
                         if (isAtLeastOneRowReturnable() && isAtLeastOneRowHasActions()) {
 313  0
                                 break;
 314  
                         }
 315  0
         }
 316  0
                 return displayList;
 317  
         }
 318  
 
 319  
         /**
 320  
          * changes from/to dates into the range operators the lookupable dao expects ("..",">" etc) this method modifies the passed in map and returns a list containing only the modified fields
 321  
          * 
 322  
          * @param lookupFormFields
 323  
          */
 324  
         protected Map<String, String> preprocessDateFields(Map<String, String> lookupFormFields) {
 325  0
                 Map<String, String> fieldsToUpdate = new HashMap<String, String>();
 326  0
                 Set<String> fieldsForLookup = lookupFormFields.keySet();
 327  0
                 for (String propName : fieldsForLookup) {
 328  0
                         if (propName.startsWith(KNSConstants.LOOKUP_RANGE_LOWER_BOUND_PROPERTY_PREFIX)) {
 329  0
                                 String from_DateValue = lookupFormFields.get(propName);
 330  0
                                 String dateFieldName = StringUtils.remove(propName, KNSConstants.LOOKUP_RANGE_LOWER_BOUND_PROPERTY_PREFIX);
 331  0
                                 String to_DateValue = lookupFormFields.get(dateFieldName);
 332  0
                                 String newPropValue = to_DateValue;// maybe clean above with
 333  
                                 // ObjectUtils.clean(propertyValue)
 334  0
                                 if (StringUtils.isNotEmpty(from_DateValue) && StringUtils.isNotEmpty(to_DateValue)) {
 335  0
                                         newPropValue = from_DateValue + KNSConstants.BETWEEN_OPERATOR + to_DateValue;
 336  0
                                 } else if (StringUtils.isNotEmpty(from_DateValue) && StringUtils.isEmpty(to_DateValue)) {
 337  0
                                         newPropValue = ">=" + from_DateValue;
 338  0
                                 } else if (StringUtils.isNotEmpty(to_DateValue) && StringUtils.isEmpty(from_DateValue)) {
 339  0
                                         newPropValue = "<=" + to_DateValue;
 340  
                                 } // could optionally continue on else here
 341  
 
 342  0
                                 fieldsToUpdate.put(dateFieldName, newPropValue);
 343  0
                         }
 344  
                 }
 345  
                 // update lookup values from found date values to update
 346  0
                 Set<String> keysToUpdate = fieldsToUpdate.keySet();
 347  0
                 for (String updateKey : keysToUpdate) {
 348  0
                         lookupFormFields.put(updateKey, fieldsToUpdate.get(updateKey));
 349  
                 }
 350  0
                 return fieldsToUpdate;
 351  
         }
 352  
 
 353  
         protected List<?> getSearchResultsWithBounding(Map<String, String> fieldValues, boolean unbounded) {
 354  
                 // remove hidden fields
 355  0
                 LookupUtils.removeHiddenCriteriaFields(getDataObjectClass(), fieldValues);
 356  
 
 357  0
                 searchUsingOnlyPrimaryKeyValues = getLookupService().allPrimaryKeyValuesPresentAndNotWildcard(getDataObjectClass(), fieldValues);
 358  
 
 359  0
                 setReturnLocation(fieldValues.get(UifParameters.RETURN_LOCATION));
 360  0
                 setReturnFormKey(fieldValues.get(UifParameters.RETURN_FORM_KEY));
 361  0
                 setReferencesToRefresh(fieldValues.get(KNSConstants.REFERENCES_TO_REFRESH));
 362  
                 List<?> searchResults;
 363  0
                 Map<String, String> nonBlankFieldValues = new HashMap<String, String>();
 364  0
                 for (String fieldName : fieldValues.keySet()) {
 365  0
                         String fieldValue = fieldValues.get(fieldName);
 366  0
                         if (StringUtils.isNotBlank(fieldValue)) {
 367  0
                                 if (fieldValue.endsWith(EncryptionService.ENCRYPTION_POST_PREFIX)) {
 368  0
                                         String encryptedValue = StringUtils.removeEnd(fieldValue, EncryptionService.ENCRYPTION_POST_PREFIX);
 369  
                                         try {
 370  0
                                                 fieldValue = getEncryptionService().decrypt(encryptedValue);
 371  0
                                         } catch (GeneralSecurityException e) {
 372  0
                                                 LOG.error("Error decrypting value for business object class " + getDataObjectClass() + " attribute " + fieldName, e);
 373  0
                                                 throw new RuntimeException("Error decrypting value for business object class " + getDataObjectClass() + " attribute " + fieldName, e);
 374  0
                                         }
 375  
                                 }
 376  0
                                 nonBlankFieldValues.put(fieldName, fieldValue);
 377  
                         }
 378  0
                 }
 379  
 
 380  
                 // If this class is an EBO, just call the module service to get the
 381  
                 // results
 382  0
                 if (ExternalizableBusinessObject.class.isAssignableFrom(getDataObjectClass())) {
 383  0
                         ModuleService eboModuleService = KNSServiceLocatorWeb.getKualiModuleService().getResponsibleModuleService(getDataObjectClass());
 384  0
                         BusinessObjectEntry ddEntry = eboModuleService.getExternalizableBusinessObjectDictionaryEntry(getDataObjectClass());
 385  0
                         Map<String, String> filteredFieldValues = new HashMap<String, String>();
 386  0
                         for (String fieldName : nonBlankFieldValues.keySet()) {
 387  0
                                 if (ddEntry.getAttributeNames().contains(fieldName)) {
 388  0
                                         filteredFieldValues.put(fieldName, nonBlankFieldValues.get(fieldName));
 389  
                                 }
 390  
                         }
 391  0
                         searchResults = eboModuleService.getExternalizableBusinessObjectsListForLookup((Class<? extends ExternalizableBusinessObject>) getDataObjectClass(), (Map) filteredFieldValues, unbounded);
 392  
                         // if any of the properties refer to an embedded EBO, call the EBO
 393  
                         // lookups first and apply to the local lookup
 394  0
                 } else if (hasExternalBusinessObjectProperty(getDataObjectClass(), nonBlankFieldValues)) {
 395  0
                         if (LOG.isDebugEnabled()) {
 396  0
                                 LOG.debug("has EBO reference: " + getDataObjectClass());
 397  0
                                 LOG.debug("properties: " + nonBlankFieldValues);
 398  
                         }
 399  
                         // remove the EBO criteria
 400  0
                         Map<String, String> nonEboFieldValues = removeExternalizableBusinessObjectFieldValues(getDataObjectClass(), nonBlankFieldValues);
 401  0
                         if (LOG.isDebugEnabled()) {
 402  0
                                 LOG.debug("Non EBO properties removed: " + nonEboFieldValues);
 403  
                         }
 404  
                         // get the list of EBO properties attached to this object
 405  0
                         List<String> eboPropertyNames = getExternalizableBusinessObjectProperties(getDataObjectClass(), nonBlankFieldValues);
 406  0
                         if (LOG.isDebugEnabled()) {
 407  0
                                 LOG.debug("EBO properties: " + eboPropertyNames);
 408  
                         }
 409  
                         // loop over those properties
 410  0
                         for (String eboPropertyName : eboPropertyNames) {
 411  
                                 // extract the properties as known to the EBO
 412  0
                                 Map<String, String> eboFieldValues = getExternalizableBusinessObjectFieldValues(eboPropertyName, nonBlankFieldValues);
 413  0
                                 if (LOG.isDebugEnabled()) {
 414  0
                                         LOG.debug("EBO properties for master EBO property: " + eboPropertyName);
 415  0
                                         LOG.debug("properties: " + eboFieldValues);
 416  
                                 }
 417  
                                 // run search against attached EBO's module service
 418  0
                                 ModuleService eboModuleService = KNSServiceLocatorWeb.getKualiModuleService().getResponsibleModuleService(getExternalizableBusinessObjectClass(getDataObjectClass(), eboPropertyName));
 419  
                                 // KULRICE-4401 made eboResults an empty list and only filled if
 420  
                                 // service is found.
 421  0
                                 List<?> eboResults = Collections.emptyList();
 422  0
                                 if (eboModuleService != null) {
 423  0
                                         eboResults = eboModuleService.getExternalizableBusinessObjectsListForLookup(getExternalizableBusinessObjectClass(getDataObjectClass(), eboPropertyName), (Map) eboFieldValues,
 424  
                                                 unbounded);
 425  
                                 } else {
 426  0
                                         LOG.debug("EBO ModuleService is null: " + eboPropertyName);
 427  
                                 }
 428  
                                 // get the mapping/relationship between the EBO object and it's
 429  
                                 // parent object
 430  
                                 // use that to adjust the fieldValues
 431  
 
 432  
                                 // get the parent property type
 433  
                                 Class<?> eboParentClass;
 434  
                                 String eboParentPropertyName;
 435  0
                                 if (ObjectUtils.isNestedAttribute(eboPropertyName)) {
 436  0
                                         eboParentPropertyName = StringUtils.substringBeforeLast(eboPropertyName, ".");
 437  
                                         try {
 438  0
                                                 eboParentClass = PropertyUtils.getPropertyType(getDataObjectClass().newInstance(), eboParentPropertyName);
 439  0
                                         } catch (Exception ex) {
 440  0
                                                 throw new RuntimeException("Unable to create an instance of the business object class: " + getDataObjectClass().getName(), ex);
 441  0
                                         }
 442  
                                 } else {
 443  0
                                         eboParentClass = getDataObjectClass();
 444  0
                                         eboParentPropertyName = null;
 445  
                                 }
 446  0
                                 if (LOG.isDebugEnabled()) {
 447  0
                                         LOG.debug("determined EBO parent class/property name: " + eboParentClass + "/" + eboParentPropertyName);
 448  
                                 }
 449  
                                 // look that up in the DD (BOMDS)
 450  
                                 // find the appropriate relationship
 451  
                                 // CHECK THIS: what if eboPropertyName is a nested attribute -
 452  
                                 // need to strip off the eboParentPropertyName if not null
 453  0
                                 RelationshipDefinition rd = getDataObjectMetaDataService().getDictionaryRelationship(eboParentClass, eboPropertyName);
 454  0
                                 if (LOG.isDebugEnabled()) {
 455  0
                                         LOG.debug("Obtained RelationshipDefinition for " + eboPropertyName);
 456  0
                                         LOG.debug(rd);
 457  
                                 }
 458  
 
 459  
                                 // copy the needed properties (primary only) to the field values KULRICE-4446 do so only if the relationship definition exists
 460  
                                 // NOTE: this will work only for single-field PK unless the ORM
 461  
                                 // layer is directly involved
 462  
                                 // (can't make (field1,field2) in ( (v1,v2),(v3,v4) ) style
 463  
                                 // queries in the lookup framework
 464  0
                                 if (ObjectUtils.isNotNull(rd)) {
 465  0
                                         if (rd.getPrimitiveAttributes().size() > 1) {
 466  0
                                                 throw new RuntimeException("EBO Links don't work for relationships with multiple-field primary keys.");
 467  
                                         }
 468  0
                                         String boProperty = rd.getPrimitiveAttributes().get(0).getSourceName();
 469  0
                                         String eboProperty = rd.getPrimitiveAttributes().get(0).getTargetName();
 470  0
                                         StringBuffer boPropertyValue = new StringBuffer();
 471  
                                         // loop over the results, making a string that the lookup
 472  
                                         // DAO will convert into an
 473  
                                         // SQL "IN" clause
 474  0
                                         for (Object ebo : eboResults) {
 475  0
                                                 if (boPropertyValue.length() != 0) {
 476  0
                                                         boPropertyValue.append("|");
 477  
                                                 }
 478  
                                                 try {
 479  0
                                                         boPropertyValue.append(PropertyUtils.getProperty(ebo, eboProperty).toString());
 480  0
                                                 } catch (Exception ex) {
 481  0
                                                         LOG.warn("Unable to get value for " + eboProperty + " on " + ebo);
 482  0
                                                 }
 483  
                                         }
 484  0
                                         if (eboParentPropertyName == null) {
 485  
                                                 // non-nested property containing the EBO
 486  0
                                                 nonEboFieldValues.put(boProperty, boPropertyValue.toString());
 487  
                                         } else {
 488  
                                                 // property nested within the main searched-for BO that
 489  
                                                 // contains the EBO
 490  0
                                                 nonEboFieldValues.put(eboParentPropertyName + "." + boProperty, boPropertyValue.toString());
 491  
                                         }
 492  
                                 }
 493  0
                         }
 494  0
                         if (LOG.isDebugEnabled()) {
 495  0
                                 LOG.debug("Passing these results into the lookup service: " + nonEboFieldValues);
 496  
                         }
 497  
                         // add those results as criteria
 498  
                         // run the normal search (but with the EBO critieria added)
 499  0
                         searchResults = (List<?>) getLookupService().findCollectionBySearchHelper(getDataObjectClass(), nonEboFieldValues, unbounded);
 500  0
                 } else {
 501  0
                         searchResults = (List<?>) getLookupService().findCollectionBySearchHelper(getDataObjectClass(), nonBlankFieldValues, unbounded);
 502  
                 }
 503  
 
 504  0
                 if (searchResults == null) {
 505  0
                         searchResults = new ArrayList<Object>();
 506  
                 }
 507  
 
 508  
                 // sort list if default sort column given
 509  0
                 List<String> defaultSortColumns = getDefaultSortAttributeNames();
 510  0
                 if ((defaultSortColumns != null) && (defaultSortColumns.size() > 0)) {
 511  0
                         Collections.sort(searchResults, new BeanPropertyComparator(defaultSortColumns, true));
 512  
                 }
 513  0
                 return searchResults;
 514  
         }
 515  
 
 516  
         /**
 517  
          * Checks whether any of the fieldValues being passed refer to a property within an ExternalizableBusinessObject.
 518  
          */
 519  
         protected boolean hasExternalBusinessObjectProperty(Class<?> boClass, Map<String, String> fieldValues) {
 520  
                 try {
 521  0
                         Object sampleBo = boClass.newInstance();
 522  0
                         for (String key : fieldValues.keySet()) {
 523  0
                                 if (isExternalBusinessObjectProperty(sampleBo, key)) {
 524  0
                                         return true;
 525  
                                 }
 526  
                         }
 527  0
                 } catch (Exception ex) {
 528  0
                         LOG.debug("Unable to check " + boClass + " for EBO properties.", ex);
 529  0
                 }
 530  0
                 return false;
 531  
         }
 532  
 
 533  
         /**
 534  
          * Check whether the given property represents a property within an EBO starting with the sampleBo object given. This is used to determine if a criteria needs to be applied to the EBO first,
 535  
          * before sending to the normal lookup DAO.
 536  
          */
 537  
         protected boolean isExternalBusinessObjectProperty(Object sampleBo, String propertyName) {
 538  
                 try {
 539  0
                         if (propertyName.indexOf(".") > 0 && !StringUtils.contains(propertyName, "add.")) {
 540  0
                                 Class<?> propertyClass = PropertyUtils.getPropertyType(sampleBo, StringUtils.substringBeforeLast(propertyName, "."));
 541  0
                                 if (propertyClass != null) {
 542  0
                                         return ExternalizableBusinessObjectUtils.isExternalizableBusinessObjectInterface(propertyClass);
 543  
                                 }
 544  0
                                 if (LOG.isDebugEnabled()) {
 545  0
                                         LOG.debug("unable to get class for " + StringUtils.substringBeforeLast(propertyName, ".") + " on " + sampleBo.getClass().getName());
 546  
                                 }
 547  
                         }
 548  0
                 } catch (Exception e) {
 549  0
                         LOG.debug("Unable to determine type of property for " + sampleBo.getClass().getName() + "/" + propertyName, e);
 550  0
                 }
 551  0
                 return false;
 552  
         }
 553  
 
 554  
         /**
 555  
          * Returns a map stripped of any properties which refer to ExternalizableBusinessObjects. These values may not be passed into the lookup service, since the objects they refer to are not in the
 556  
          * local database.
 557  
          */
 558  
         protected Map<String, String> removeExternalizableBusinessObjectFieldValues(Class<?> boClass, Map<String, String> fieldValues) {
 559  0
                 Map<String, String> eboFieldValues = new HashMap<String, String>();
 560  
                 try {
 561  0
                         Object sampleBo = boClass.newInstance();
 562  0
                         for (String key : fieldValues.keySet()) {
 563  0
                                 if (!isExternalBusinessObjectProperty(sampleBo, key)) {
 564  0
                                         eboFieldValues.put(key, fieldValues.get(key));
 565  
                                 }
 566  
                         }
 567  0
                 } catch (Exception ex) {
 568  0
                         LOG.debug("Unable to check " + boClass + " for EBO properties.", ex);
 569  0
                 }
 570  0
                 return eboFieldValues;
 571  
         }
 572  
 
 573  
         /**
 574  
          * Return the EBO fieldValue entries explicitly for the given eboPropertyName. (I.e., any properties with the given property name as a prefix.
 575  
          */
 576  
         protected Map<String, String> getExternalizableBusinessObjectFieldValues(String eboPropertyName, Map<String, String> fieldValues) {
 577  0
                 Map<String, String> eboFieldValues = new HashMap<String, String>();
 578  0
                 for (String key : fieldValues.keySet()) {
 579  0
                         if (key.startsWith(eboPropertyName + ".")) {
 580  0
                                 eboFieldValues.put(StringUtils.substringAfterLast(key, "."), fieldValues.get(key));
 581  
                         }
 582  
                 }
 583  0
                 return eboFieldValues;
 584  
         }
 585  
 
 586  
         /**
 587  
          * Get the complete list of all properties referenced in the fieldValues that are ExternalizableBusinessObjects.
 588  
          * 
 589  
          * This is a list of the EBO object references themselves, not of the properties within them.
 590  
          */
 591  
         protected List<String> getExternalizableBusinessObjectProperties(Class<?> boClass, Map<String, String> fieldValues) {
 592  0
                 Set<String> eboPropertyNames = new HashSet<String>();
 593  
                 try {
 594  0
                         Object sampleBo = boClass.newInstance();
 595  0
                         for (String key : fieldValues.keySet()) {
 596  0
                                 if (isExternalBusinessObjectProperty(sampleBo, key)) {
 597  0
                                         eboPropertyNames.add(StringUtils.substringBeforeLast(key, "."));
 598  
                                 }
 599  
                         }
 600  0
                 } catch (Exception ex) {
 601  0
                         LOG.debug("Unable to check " + boClass + " for EBO properties.", ex);
 602  0
                 }
 603  0
                 return new ArrayList<String>(eboPropertyNames);
 604  
         }
 605  
 
 606  
         /**
 607  
          * Given an property on the main BO class, return the defined type of the ExternalizableBusinessObject. This will be used by other code to determine the correct module service to call for the
 608  
          * lookup.
 609  
          * 
 610  
          * @param boClass
 611  
          * @param propertyName
 612  
          * @return
 613  
          */
 614  
         protected Class<? extends ExternalizableBusinessObject> getExternalizableBusinessObjectClass(Class<?> boClass, String propertyName) {
 615  
                 try {
 616  0
                         return PropertyUtils.getPropertyType(boClass.newInstance(), StringUtils.substringBeforeLast(propertyName, "."));
 617  0
                 } catch (Exception e) {
 618  0
                         LOG.debug("Unable to determine type of property for " + boClass.getName() + "/" + propertyName, e);
 619  
                 }
 620  0
                 return null;
 621  
         }
 622  
 
 623  
         /**
 624  
          * Returns the maintenance document type associated with the business object class or null if one does not exist.
 625  
          * 
 626  
          * @return String representing the maintenance document type name
 627  
          */
 628  
         protected String getMaintenanceDocumentTypeName() {
 629  0
                 MaintenanceDocumentDictionaryService dd = getMaintenanceDocumentDictionaryService();
 630  0
                 String maintDocTypeName = dd.getDocumentTypeName(getDataObjectClass());
 631  0
                 return maintDocTypeName;
 632  
         }
 633  
 
 634  
         /**
 635  
          * Determines if underlying lookup bo has associated maintenance document that allows new or copy maintenance actions.
 636  
          * 
 637  
          * @return true if bo has maint doc that allows new or copy actions
 638  
          */
 639  
         protected boolean allowsMaintenanceNewOrCopyAction() {
 640  0
                 boolean allowsNewOrCopy = false;
 641  
 
 642  0
                 String maintDocTypeName = getMaintenanceDocumentTypeName();
 643  
 
 644  0
                 if (StringUtils.isNotBlank(maintDocTypeName)) {
 645  0
                         allowsNewOrCopy = getBusinessObjectAuthorizationService().canCreate(getDataObjectClass(), GlobalVariables.getUserSession().getPerson(), maintDocTypeName);
 646  
                 }
 647  0
                 return allowsNewOrCopy;
 648  
         }
 649  
 
 650  
         protected boolean allowsMaintenanceEditAction(Object dataObject) {
 651  0
                 boolean allowsEdit = false;
 652  
 
 653  0
                 String maintDocTypeName = getMaintenanceDocumentTypeName();
 654  
 
 655  0
                 if (StringUtils.isNotBlank(maintDocTypeName)) {
 656  0
                         allowsEdit = getBusinessObjectAuthorizationService().canMaintain(dataObject, GlobalVariables.getUserSession().getPerson(), maintDocTypeName);
 657  
                 }
 658  0
                 return allowsEdit;
 659  
         }
 660  
 
 661  
         protected boolean allowsMaintenanceDeleteAction(Object dataObject) {
 662  
 
 663  0
                 boolean allowsMaintain = false;
 664  0
                 boolean allowsDelete = false;
 665  
 
 666  0
                 String maintDocTypeName = getMaintenanceDocumentTypeName();
 667  
 
 668  0
                 if (StringUtils.isNotBlank(maintDocTypeName)) {
 669  0
                         allowsMaintain = getBusinessObjectAuthorizationService().canMaintain(dataObject, GlobalVariables.getUserSession().getPerson(), maintDocTypeName);
 670  
                 }
 671  
 
 672  0
                 allowsDelete = KNSServiceLocatorWeb.getMaintenanceDocumentDictionaryService().getAllowsRecordDeletion(getDataObjectClass());
 673  
 
 674  0
                 return allowsDelete && allowsMaintain;
 675  
         }
 676  
 
 677  
         /**
 678  
          * @see org.kuali.rice.kns.uif.service.LookupViewHelperService#getCreateNewUrl(org.kuali.rice.kns.uif.field.GeneratedField)
 679  
          */
 680  
         public String getCreateNewUrl(GeneratedField generatedField) {
 681  0
                 String url = "";
 682  
 
 683  0
                 if (allowsMaintenanceNewOrCopyAction()) {
 684  0
                         Properties props = new Properties();
 685  
                         // TODO delyea - DOCUMENT THE FOLLOWING CHANGES (next 5 lines)
 686  
                         // props.put(KNSConstants.DISPATCH_REQUEST_PARAMETER, KNSConstants.MAINTENANCE_NEW_METHOD_TO_CALL);
 687  
                         // props.put(KNSConstants.BUSINESS_OBJECT_CLASS_ATTRIBUTE, getDataObjectClass().getName());
 688  0
                         props.put(KNSConstants.DISPATCH_REQUEST_PARAMETER, MaintenanceDocumentController.METHOD_TO_CALL_NEW);
 689  0
                         props.put(UifParameters.DATA_OBJECT_CLASS_NAME, getDataObjectClass().getName());
 690  0
                         props.put(UifParameters.VIEW_TYPE_NAME, UifConstants.ViewType.MAINTENANCE);
 691  
 
 692  
                         // TODO delyea - DOCUMENT THE FOLLOWING CHANGES (next 2 lines)
 693  
                         // url = UrlFactory.parameterizeUrl(KNSConstants.MAINTENANCE_ACTION, props);
 694  0
                         url = UrlFactory.parameterizeUrl(MaintenanceDocumentController.REQUEST_MAPPING_MAINTENANCE, props);
 695  0
                         url = "<a id=\"" + generatedField.getId() + "\" href=\"" + url + "\"><img src=\"images/tinybutton-createnew.gif\" alt=\"create new\" width=\"70\" height=\"15\"/></a>";
 696  
                 }
 697  
 
 698  0
                 return url;
 699  
         }
 700  
 
 701  
         /**
 702  
          * @see org.kuali.rice.kns.uif.service.LookupViewHelperService#getActionUrlsFromField(org.kuali.rice.kns.uif.field.GeneratedField)
 703  
          */
 704  
         public String getActionUrlsFromField(GeneratedField generatedField) {
 705  0
                 Object bo = getLineObjectFromField(generatedField);
 706  0
                 if (bo == null) {
 707  0
                         return ACTION_URLS_EMPTY;
 708  
                 }
 709  0
                 String actionUrls = getActionUrls(bo, getDataObjectMetaDataService().listPrimaryKeyFieldNames(getDataObjectClass()), getBusinessObjectAuthorizationService().getLookupResultRestrictions(
 710  
                         bo, GlobalVariables.getUserSession().getPerson()));
 711  0
                 return (StringUtils.isNotBlank(actionUrls)) ? actionUrls : ACTION_URLS_EMPTY;
 712  
         }
 713  
 
 714  
         protected Object getLineObjectFromField(GeneratedField generatedField) {
 715  0
                 Object bo = generatedField.getContext().get(UifConstants.ContextVariableNames.LINE);
 716  0
                 if (bo == null) {
 717  0
                         LOG.error("***************************************************************");
 718  0
                         LOG.error("**** THERE IS NO BO TO PROCESS - THIS SHOULD NEVER HAPPEN *****");
 719  0
                         LOG.error("***************************************************************");
 720  0
                         return null;
 721  
                 }
 722  0
                 return bo;
 723  
         }
 724  
 
 725  
         /**
 726  
          * This method is called by performLookup method to generate action urls. It calls the method getCustomActionUrls to get html data, calls getMaintenanceUrl to get the actual html tag, and returns
 727  
          * a formatted/concatenated string of action urls.
 728  
          * 
 729  
          * @see org.kuali.rice.kns.lookup.LookupableHelperService#getActionUrls(org.kuali.rice.kns.bo.BusinessObject)
 730  
          */
 731  
         protected String getActionUrls(Object dataObject, List<String> pkNames, BusinessObjectRestrictions dataObjectRestrictions) {
 732  0
                 StringBuffer actions = new StringBuffer();
 733  0
                 List<HtmlData> htmlDataList = getCustomActionUrls(dataObject, pkNames);
 734  0
                 for (HtmlData htmlData : htmlDataList) {
 735  0
                         actions.append(getMaintenanceUrl(dataObject, htmlData, pkNames, dataObjectRestrictions));
 736  0
                         if (htmlData.getChildUrlDataList() != null) {
 737  0
                                 if (htmlData.getChildUrlDataList().size() > 0) {
 738  0
                                         actions.append(ACTION_URLS_CHILDREN_STARTER);
 739  0
                                         for (HtmlData childURLData : htmlData.getChildUrlDataList()) {
 740  0
                                                 actions.append(getMaintenanceUrl(dataObject, childURLData, pkNames, dataObjectRestrictions));
 741  0
                                                 actions.append(ACTION_URLS_CHILDREN_SEPARATOR);
 742  
                                         }
 743  0
                                         if (actions.toString().endsWith(ACTION_URLS_CHILDREN_SEPARATOR))
 744  0
                                                 actions.delete(actions.length() - ACTION_URLS_CHILDREN_SEPARATOR.length(), actions.length());
 745  0
                                         actions.append(ACTION_URLS_CHILDREN_END);
 746  
                                 }
 747  
                         }
 748  0
                         actions.append(ACTION_URLS_SEPARATOR);
 749  
                 }
 750  0
                 if (actions.toString().endsWith(ACTION_URLS_SEPARATOR))
 751  0
                         actions.delete(actions.length() - ACTION_URLS_SEPARATOR.length(), actions.length());
 752  0
                 return actions.toString();
 753  
         }
 754  
 
 755  
         /**
 756  
          * Child classes should override this method if they want to return some other action urls.
 757  
          * 
 758  
          * @returns This default implementation returns links to edit and copy maintenance action for the current maintenance record if the business object class has an associated maintenance document.
 759  
          *          Also checks value of allowsNewOrCopy in maintenance document xml before rendering the copy link.
 760  
          */
 761  
         protected List<HtmlData> getCustomActionUrls(Object dataObject, List<String> pkNames) {
 762  0
                 List<HtmlData> htmlDataList = new ArrayList<HtmlData>();
 763  
                 // TODO delyea - DOCUMENT THE FOLLOWING CHANGES FROM KNSConstants to UifConstants
 764  
                 // TODO delyea - sgibson just hacked in the link text, probably should come
 765  
                 //               from somewhere
 766  0
                 if (allowsMaintenanceEditAction(dataObject)) {
 767  
                         // htmlDataList.add(getUrlData(dataObject, KNSConstants.MAINTENANCE_EDIT_METHOD_TO_CALL, pkNames));
 768  0
                         htmlDataList.add(getUrlData(dataObject, MaintenanceDocumentController.METHOD_TO_CALL_EDIT, "edit", pkNames));
 769  
                 }
 770  0
                 if (allowsMaintenanceNewOrCopyAction()) {
 771  
                         // htmlDataList.add(getUrlData(dataObject, KNSConstants.MAINTENANCE_COPY_METHOD_TO_CALL, pkNames));
 772  0
                         htmlDataList.add(getUrlData(dataObject, MaintenanceDocumentController.METHOD_TO_CALL_COPY, "copy", pkNames));
 773  
                 }
 774  0
                 if (allowsMaintenanceDeleteAction(dataObject)) {
 775  
                         // htmlDataList.add(getUrlData(dataObject, KNSConstants.MAINTENANCE_DELETE_METHOD_TO_CALL, pkNames));
 776  0
                         htmlDataList.add(getUrlData(dataObject, MaintenanceDocumentController.METHOD_TO_CALL_DELETE, "delete", pkNames));
 777  
                 }
 778  0
                 return htmlDataList;
 779  
         }
 780  
 
 781  
         /**
 782  
          * 
 783  
          * This method calls its overloaded method with displayText as methodToCall
 784  
          * 
 785  
          * @param dataObject
 786  
          * @param methodToCall
 787  
          * @param pkNames
 788  
          * @return
 789  
          */
 790  
         protected AnchorHtmlData getUrlData(Object dataObject, String methodToCall, List<String> pkNames) {
 791  0
                 return getUrlData(dataObject, methodToCall, methodToCall, pkNames);
 792  
         }
 793  
 
 794  
         /**
 795  
          * This method constructs an AnchorHtmlData. This method can be overriden by child classes if they want to construct the html data in a different way. Foe example, if they want different type of
 796  
          * html tag, like input/image.
 797  
          * 
 798  
          * @param dataObject
 799  
          * @param methodToCall
 800  
          * @param displayText
 801  
          * @param pkNames
 802  
          * @return
 803  
          */
 804  
         protected AnchorHtmlData getUrlData(Object dataObject, String methodToCall, String displayText, List<String> pkNames) {
 805  0
                 String href = getActionUrlHref(dataObject, methodToCall, pkNames);
 806  
                 // String title = StringUtils.isBlank(href)?"":getActionUrlTitleText(dataObject, displayText, pkNames);
 807  0
                 AnchorHtmlData anchorHtmlData = new AnchorHtmlData(href, methodToCall, displayText);
 808  0
                 return anchorHtmlData;
 809  
         }
 810  
 
 811  
         /**
 812  
          * 
 813  
          * This method generates and returns href for the given parameters. This method can be overridden by child classes if they have to generate href differently. For example, refer to
 814  
          * IntendedIncumbentLookupableHelperServiceImpl
 815  
          * 
 816  
          * @param dataObject
 817  
          * @param methodToCall
 818  
          * @param pkNames
 819  
          * @return
 820  
          */
 821  
         protected String getActionUrlHref(Object dataObject, String methodToCall, List<String> pkNames) {
 822  0
                 Properties props = new Properties();
 823  0
                 props.put(KNSConstants.DISPATCH_REQUEST_PARAMETER, methodToCall);
 824  0
                 props.putAll(getParametersFromPrimaryKey(dataObject, pkNames));
 825  0
                 if (StringUtils.isNotBlank(getReturnLocation())) {
 826  0
                         props.put(KNSConstants.RETURN_LOCATION_PARAMETER, getReturnLocation());
 827  
                 }
 828  
                 // TODO delyea - DOCUMENT THE FOLLOWING CHANGES (next 3 lines)
 829  
                 // props.put(KNSConstants.BUSINESS_OBJECT_CLASS_ATTRIBUTE, dataObject.getClass().getName());
 830  0
                 props.put(UifParameters.DATA_OBJECT_CLASS_NAME, dataObject.getClass().getName());
 831  0
                 props.put(UifParameters.VIEW_TYPE_NAME, UifConstants.ViewType.MAINTENANCE);
 832  
                 // TODO delyea - DOCUMENT THE FOLLOWING CHANGES (next 2 lines)
 833  
                 // return UrlFactory.parameterizeUrl(KNSConstants.MAINTENANCE_ACTION, props);
 834  0
                 return UrlFactory.parameterizeUrl(MaintenanceDocumentController.REQUEST_MAPPING_MAINTENANCE, props);
 835  
         }
 836  
 
 837  
         protected Properties getParametersFromPrimaryKey(Object dataObject, List<String> pkNames) {
 838  0
                 Properties props = new Properties();
 839  0
                 for (Iterator<String> iter = pkNames.iterator(); iter.hasNext();) {
 840  0
                         String fieldNm = iter.next();
 841  
 
 842  0
                         Object fieldVal = ObjectUtils.getPropertyValue(dataObject, fieldNm);
 843  0
                         if (fieldVal == null) {
 844  0
                                 fieldVal = KNSConstants.EMPTY_STRING;
 845  
                         }
 846  0
                         if (fieldVal instanceof java.sql.Date) {
 847  0
                                 String formattedString = "";
 848  0
                                 if (Formatter.findFormatter(fieldVal.getClass()) != null) {
 849  0
                                         Formatter formatter = Formatter.getFormatter(fieldVal.getClass());
 850  0
                                         formattedString = (String) formatter.format(fieldVal);
 851  0
                                         fieldVal = formattedString;
 852  
                                 }
 853  
                         }
 854  
 
 855  
                         // Encrypt value if it is a secure field
 856  0
                         if (getBusinessObjectAuthorizationService().attributeValueNeedsToBeEncryptedOnFormsAndLinks(dataObject.getClass(), fieldNm)) {
 857  
                                 try {
 858  0
                                         fieldVal = getEncryptionService().encrypt(fieldVal) + EncryptionService.ENCRYPTION_POST_PREFIX;
 859  0
                                 } catch (GeneralSecurityException e) {
 860  0
                                         LOG.error("Exception while trying to encrypted value for inquiry framework.", e);
 861  0
                                         throw new RuntimeException(e);
 862  0
                                 }
 863  
 
 864  
                         }
 865  
 
 866  0
                         props.put(fieldNm, fieldVal.toString());
 867  0
                 }
 868  0
                 return props;
 869  
         }
 870  
 
 871  
         /**
 872  
          * Build a maintenance url.
 873  
          * 
 874  
          * @param bo
 875  
          *            - business object representing the record for maint.
 876  
          * @param methodToCall
 877  
          *            - maintenance action
 878  
          * @return
 879  
          */
 880  
         protected String getMaintenanceUrl(Object dataObject, HtmlData htmlData, List<String> pkNames, BusinessObjectRestrictions dataObjectRestrictions) {
 881  0
                 htmlData.setTitle(getActionUrlTitleText(dataObject, htmlData.getDisplayText(), pkNames, dataObjectRestrictions));
 882  0
                 return htmlData.constructCompleteHtmlTag();
 883  
         }
 884  
 
 885  
         /**
 886  
          * 
 887  
          * This method generates and returns title text for action urls. Child classes can override this if they want to generate the title text differently. For example, refer to
 888  
          * BatchJobStatusLookupableHelperServiceImpl
 889  
          * 
 890  
          * @param dataObject
 891  
          * @param displayText
 892  
          * @param pkNames
 893  
          * @return
 894  
          */
 895  
         protected String getActionUrlTitleText(Object dataObject, String displayText, List<String> pkNames, BusinessObjectRestrictions dataObjectRestrictions) {
 896  0
                 String prependTitleText = displayText + " " + getDataDictionaryService().getDataDictionary().getDataObjectEntry(getDataObjectClass().getName()).getObjectLabel() + " "
 897  
                         + KNSServiceLocator.getKualiConfigurationService().getPropertyString(TITLE_ACTION_URL_PREPENDTEXT_PROPERTY);
 898  0
                 return HtmlData.getTitleText(prependTitleText, dataObject, pkNames, dataObjectRestrictions);
 899  
         }
 900  
 
 901  
 //        final protected HtmlData getReturnUrl(Object dataObject, Map<String,String> fieldConversions, String lookupImpl, List returnKeys, BusinessObjectRestrictions businessObjectRestrictions) {
 902  
 //                String href = getReturnHrefUsingObject(dataObject, fieldConversions, lookupImpl, returnKeys);
 903  
 //                String returnUrlAnchorLabel = KNSServiceLocator.getKualiConfigurationService().getPropertyString(TITLE_RETURN_URL_PREPENDTEXT_PROPERTY);
 904  
 //                AnchorHtmlData anchor = new AnchorHtmlData(href, HtmlData.getTitleText(returnUrlAnchorLabel, dataObject, returnKeys, businessObjectRestrictions));
 905  
 //                anchor.setDisplayText(returnUrlAnchorLabel);
 906  
 //                return anchor;
 907  
 //        }
 908  
 
 909  
 //        final protected String getReturnHrefUsingObject(Object dataObject, Map<String,String> fieldConversions, String lookupImpl, List returnKeys) {
 910  
 //                if (StringUtils.isNotBlank(getReturnLocation())) {
 911  
 //                        return UrlFactory.parameterizeUrl(getReturnLocation(), getReturnUrlParameters(dataObject, fieldConversions, lookupImpl, returnKeys));
 912  
 //                }
 913  
 //                return "";
 914  
 //        }
 915  
 
 916  
         /**
 917  
          * Returns the HTML code for a URL that will return the individual row
 918  
          * 
 919  
          * @see org.kuali.rice.kns.uif.service.LookupViewHelperService#getReturnUrlForResults(org.kuali.rice.kns.uif.field.GeneratedField)
 920  
          * 
 921  
          * @param generatedField
 922  
          * @return
 923  
          */
 924  
         public String getReturnUrlForResults(GeneratedField generatedField) {
 925  0
                 Object dataObject = getLineObjectFromField(generatedField);
 926  
                 // return a non-breaking space if the object is null or if the row is not returnable 
 927  0
                 if ( (dataObject == null) || (!isResultReturnable(dataObject)) ) {
 928  0
                         return ACTION_URLS_EMPTY;
 929  
                 }
 930  0
                 HtmlData temp = getReturnUrl(dataObject, generatedField.getContext(), getReturnKeys(), getBusinessObjectAuthorizationService().getLookupResultRestrictions(dataObject,
 931  
                         GlobalVariables.getUserSession().getPerson()));
 932  0
                 String url = temp.constructCompleteHtmlTag(); 
 933  0
                 return (StringUtils.isNotBlank(url)) ? url : ACTION_URLS_EMPTY;
 934  
         }
 935  
 
 936  
         protected HtmlData getReturnUrl(Object dataObject, Map<String, Object> context, List<String> returnKeys, BusinessObjectRestrictions businessObjectRestrictions) {
 937  0
                 View lookupView = (View) context.get(UifConstants.ContextVariableNames.VIEW);
 938  0
                 Properties props = getReturnUrlParameters(dataObject, getFieldConversions(), lookupView.getViewHelperServiceClassName().getName(), returnKeys);
 939  
                 // TODO delyea - Multiple value returns are not yet implemented
 940  
                 // if(StringUtils.isEmpty(lookupForm.getHtmlDataType()) || HtmlData.ANCHOR_HTML_DATA_TYPE.equals(lookupForm.getHtmlDataType())) {
 941  0
                 return getReturnAnchorHtmlData(dataObject, props, context, returnKeys, businessObjectRestrictions, lookupView.getReturnTarget());
 942  
                 // } else {
 943  
                 // return getReturnInputHtmlData(businessObject, props, context, returnKeys, businessObjectRestrictions);
 944  
                 // }
 945  
         }
 946  
 
 947  
         /**
 948  
          * TODO delyea - Multiple value returns are not yet implemented
 949  
          * @deprecated - Multiple value returns are not yet implemented in KRAD
 950  
          */
 951  
         protected HtmlData getReturnInputHtmlData(Object dataObject, Properties props, Map<String, Object> context, List<String> returnKeys, BusinessObjectRestrictions businessObjectRestrictions) {
 952  
                 // String returnUrlAnchorLabel = KNSServiceLocator.getKualiConfigurationService().getPropertyString(TITLE_RETURN_URL_PREPENDTEXT_PROPERTY);
 953  
                 // String name = KNSConstants.MULTIPLE_VALUE_LOOKUP_SELECTED_OBJ_ID_PARAM_PREFIX+lookupForm.getLookupObjectId();
 954  
                 // InputHtmlData input = new InputHtmlData(name, InputHtmlData.CHECKBOX_INPUT_TYPE);
 955  
                 // input.setTitle(HtmlData.getTitleText(returnUrlAnchorLabel, dataObject, returnKeys, businessObjectRestrictions));
 956  
                 // if(((MultipleValueLookupForm)lookupForm).getCompositeObjectIdMap()==null ||
 957  
                 // ((MultipleValueLookupForm)lookupForm).getCompositeObjectIdMap().get(
 958  
                 // ((PersistableBusinessObject)businessObject).getObjectId())==null){
 959  
                 // input.setChecked("");
 960  
                 // } else{
 961  
                 // input.setChecked(InputHtmlData.CHECKBOX_CHECKED_VALUE);
 962  
                 // }
 963  
                 // input.setValue(InputHtmlData.CHECKBOX_CHECKED_VALUE);
 964  
                 // return input;
 965  0
                 return null;
 966  
         }
 967  
 
 968  
         protected HtmlData getReturnAnchorHtmlData(Object dataObject, Properties props, Map<String, Object> context, List<String> returnKeys, BusinessObjectRestrictions businessObjectRestrictions, String returnTarget) {
 969  0
                 String returnUrlAnchorLabel = KNSServiceLocator.getKualiConfigurationService().getPropertyString(TITLE_RETURN_URL_PREPENDTEXT_PROPERTY);
 970  0
                 AnchorHtmlData anchor = new AnchorHtmlData(getReturnHrefUsingParameters(props, context, returnKeys), HtmlData.getTitleText(returnUrlAnchorLabel, dataObject, returnKeys,
 971  
                         businessObjectRestrictions));
 972  0
                 anchor.setDisplayText(returnUrlAnchorLabel);
 973  0
                 if (returnTarget != null) {
 974  0
                         anchor.setTarget(returnTarget);
 975  0
                         if (!returnTarget.equals("_self")
 976  
                                         && !returnTarget.equals("_parent")) {
 977  
                                 // Build up script to set the value(s) on the form and close
 978  
                                 // the fancybox. In order to trigger validation : get focus and then loose(blur()) focus.
 979  
                                 // Prevent default onclick for the anchor.
 980  
 //                                StringBuilder script = new StringBuilder();
 981  
 //                                for (Object key : getFieldConversions().keySet()) {
 982  
 //                                        if (props.containsKey(getFieldConversions().get(key))) {
 983  
 //                                                Object fieldName = getFieldConversions().get(key)
 984  
 //                                                                .replace("'", "\\'");
 985  
 //                                                Object value = props
 986  
 //                                                                .get(getFieldConversions().get(key));
 987  
 //                                                script = script
 988  
 //                                                                .append("var returnField = parent.$('#iframeportlet').contents().find("
 989  
 //                                                                                + "'[name=&quot;"
 990  
 //                                                                                + fieldName
 991  
 //                                                                                + "&quot;]');"
 992  
 //                                                                                + "returnField.val('"
 993  
 //                                                                                + value
 994  
 //                                                                                + "');"
 995  
 //                                                                                + "returnField.focus();returnField.blur();returnField.focus();");
 996  
 //                                        }
 997  
 //                                }
 998  
 //                                anchor.setOnclick(script.append("parent.$.fancybox.close();return false").toString());
 999  0
                                 anchor.setOnclick("parent.$.fancybox.close();");
 1000  
                         }
 1001  
                 }
 1002  0
                 return anchor;
 1003  
         }
 1004  
 
 1005  
         protected String getReturnHrefUsingParameters(Properties props, Map<String, Object> context, List returnKeys) {
 1006  0
                 if (StringUtils.isNotBlank(getReturnLocation())) {
 1007  0
                         String href = UrlFactory.parameterizeUrl(getReturnLocation(), props);
 1008  0
                         return addToReturnHref(href, context);
 1009  
                 }
 1010  0
                 return "";
 1011  
         }
 1012  
 
 1013  
         protected String addToReturnHref(String href, Map<String, Object> context) {
 1014  0
                 StringBuffer buffer = new StringBuffer(href);
 1015  
                  // TODO delyea - Figure out how to impelement Anchors in new UIF
 1016  
 //                String lookupAnchor = "";
 1017  
 //                if (StringUtils.isNotEmpty(anchor)) {
 1018  
 //                        lookupAnchor = anchor;
 1019  
 //                }
 1020  
 //                buffer.append("&anchor=" + lookupAnchor + "&docNum=" + (StringUtils.isEmpty(getDocNum()) ? "" : getDocNum()));
 1021  0
                 buffer.append("&" + UifParameters.DOC_NUM + "=" + (StringUtils.isEmpty(getDocNum()) ? "" : getDocNum()));
 1022  0
                 return buffer.toString();
 1023  
         }
 1024  
 
 1025  
         protected Properties getReturnUrlParameters(Object dataObject, Map<String,String> fieldConversionValues, String lookupImpl, List<String> returnKeys) {
 1026  0
                 Properties props = new Properties();
 1027  0
                 props.put(KNSConstants.DISPATCH_REQUEST_PARAMETER, KNSConstants.RETURN_METHOD_TO_CALL);
 1028  0
                 if (getReturnFormKey() != null) {
 1029  0
                         props.put(UifParameters.FORM_KEY, getReturnFormKey());
 1030  
                 }
 1031  0
                 if (lookupImpl != null) {
 1032  0
                         props.put(KNSConstants.REFRESH_CALLER, lookupImpl);
 1033  
                 }
 1034  0
                 if (getDocNum() != null) {
 1035  0
                         props.put(UifParameters.DOC_NUM, getDocNum());
 1036  
                 }
 1037  
 
 1038  0
                 if (getReferencesToRefresh() != null) {
 1039  0
                         props.put(KNSConstants.REFERENCES_TO_REFRESH, getReferencesToRefresh());
 1040  
                 }
 1041  
 
 1042  0
                 Iterator<String> returnKeysIt = returnKeys.iterator();
 1043  0
                 while (returnKeysIt.hasNext()) {
 1044  0
                         String fieldNm = returnKeysIt.next();
 1045  
 
 1046  0
                         Object fieldVal = ObjectUtils.getPropertyValue(dataObject, fieldNm);
 1047  0
                         if (fieldVal == null) {
 1048  0
                                 fieldVal = StringUtils.EMPTY;
 1049  
                         }
 1050  
 
 1051  0
                         if (getBusinessObjectAuthorizationService().attributeValueNeedsToBeEncryptedOnFormsAndLinks(getDataObjectClass(), fieldNm)) {
 1052  
                                 try {
 1053  0
                                         fieldVal = getEncryptionService().encrypt(fieldVal) + EncryptionService.ENCRYPTION_POST_PREFIX;
 1054  0
                                 } catch (GeneralSecurityException e) {
 1055  0
                                         LOG.error("Exception while trying to encrypted value for inquiry framework.", e);
 1056  0
                                         throw new RuntimeException(e);
 1057  0
                                 }
 1058  
 
 1059  
                         }
 1060  
 
 1061  
                         // need to format date in url
 1062  0
                         if (fieldVal instanceof Date) {
 1063  0
                                 DateFormatter dateFormatter = new DateFormatter();
 1064  0
                                 fieldVal = dateFormatter.format(fieldVal);
 1065  
                         }
 1066  
 
 1067  0
                         if (fieldConversionValues.containsKey(fieldNm)) {
 1068  0
                                 fieldNm = fieldConversionValues.get(fieldNm);
 1069  
                         }
 1070  
 
 1071  0
                         props.put(fieldNm, fieldVal.toString());
 1072  0
                 }
 1073  
 
 1074  0
                 return props;
 1075  
         }
 1076  
 
 1077  
         /**
 1078  
          * @return a List of the names of fields which are marked in data dictionary as return fields.
 1079  
          */
 1080  
         protected List<String> getReturnKeys() {
 1081  
                 List<String> returnKeys;
 1082  0
                 if (fieldConversions != null && !fieldConversions.isEmpty()) {
 1083  0
                         returnKeys = new ArrayList<String>(fieldConversions.keySet());
 1084  
                 } else {
 1085  0
                         returnKeys = getDataObjectMetaDataService().listPrimaryKeyFieldNames(getDataObjectClass());
 1086  
                 }
 1087  
 
 1088  0
                 return returnKeys;
 1089  
         }
 1090  
 
 1091  
     /**
 1092  
      * Determines whether a given data object that's returned as one of the lookup's results is considered returnable, which means that for
 1093  
      * single-value lookups, a "return value" link may be rendered, and for multiple value lookups, a checkbox is rendered.
 1094  
      *
 1095  
      * Note that this can be part of an authorization mechanism, but not the complete authorization mechanism.  The component that invoked the lookup/
 1096  
      * lookup caller (e.g. document, nesting lookup, etc.) needs to check that the object that was passed to it was returnable as well because there
 1097  
      * are ways around this method (e.g. crafting a custom return URL).
 1098  
      *
 1099  
      * @param dataObject an object from the search result set
 1100  
      * @return true if the row is returnable and false if it is not
 1101  
      */
 1102  
         protected boolean isResultReturnable(Object dataObject) {
 1103  0
                 return true;
 1104  
         }
 1105  
 
 1106  
         /**
 1107  
          * @see org.kuali.rice.kns.uif.service.LookupViewHelperService#getConditionallyReadOnlyPropertyNames()
 1108  
          */
 1109  
         public Set<String> getConditionallyReadOnlyPropertyNames() {
 1110  0
                 return new HashSet<String>();
 1111  
         }
 1112  
 
 1113  
         /**
 1114  
          * @see org.kuali.rice.kns.uif.service.LookupViewHelperService#getConditionallyRequiredPropertyNames()
 1115  
          */
 1116  
         public Set<String> getConditionallyRequiredPropertyNames() {
 1117  0
                 return new HashSet<String>();
 1118  
         }
 1119  
 
 1120  
         /**
 1121  
          * @see org.kuali.rice.kns.uif.service.LookupViewHelperService#getConditionallyHiddenPropertyNames()
 1122  
          */
 1123  
         public Set<String> getConditionallyHiddenPropertyNames() {
 1124  0
                 return new HashSet<String>();
 1125  
         }
 1126  
          
 1127  
         /**
 1128  
      * @return the atLeastOneRowReturnable
 1129  
      */
 1130  
     public boolean isAtLeastOneRowReturnable() {
 1131  0
             return this.atLeastOneRowReturnable;
 1132  
     }
 1133  
 
 1134  
     /**
 1135  
      * @param atLeastOneRowReturnable the atLeastOneRowReturnable to set
 1136  
      */
 1137  
     public void setAtLeastOneRowReturnable(boolean atLeastOneRowReturnable) {
 1138  0
             this.atLeastOneRowReturnable = atLeastOneRowReturnable;
 1139  0
     }
 1140  
 
 1141  
         /**
 1142  
      * @return the atLeastOneRowHasActions
 1143  
      */
 1144  
     public boolean isAtLeastOneRowHasActions() {
 1145  0
             return this.atLeastOneRowHasActions;
 1146  
     }
 1147  
 
 1148  
         /**
 1149  
      * @param atLeastOneRowHasActions the atLeastOneRowHasActions to set
 1150  
      */
 1151  
     public void setAtLeastOneRowHasActions(boolean atLeastOneRowHasActions) {
 1152  0
             this.atLeastOneRowHasActions = atLeastOneRowHasActions;
 1153  0
     }
 1154  
 
 1155  
         /**
 1156  
          * @return the dataObjectClass
 1157  
          */
 1158  
         public Class<?> getDataObjectClass() {
 1159  0
                 return this.dataObjectClass;
 1160  
         }
 1161  
 
 1162  
         /**
 1163  
          * @param dataObjectClass
 1164  
          *            the dataObjectClass to set
 1165  
          */
 1166  
         public void setDataObjectClass(Class<?> dataObjectClass) {
 1167  0
                 this.dataObjectClass = dataObjectClass;
 1168  0
         }
 1169  
 
 1170  
         /**
 1171  
          * @return the returnLocation
 1172  
          */
 1173  
         public String getReturnLocation() {
 1174  0
                 return this.returnLocation;
 1175  
         }
 1176  
 
 1177  
         /**
 1178  
          * @param returnLocation
 1179  
          *            the returnLocation to set
 1180  
          */
 1181  
         public void setReturnLocation(String returnLocation) {
 1182  0
                 this.returnLocation = returnLocation;
 1183  0
         }
 1184  
 
 1185  
         /**
 1186  
          * @return the docNum
 1187  
          */
 1188  
         public String getDocNum() {
 1189  0
                 return this.docNum;
 1190  
         }
 1191  
 
 1192  
         /**
 1193  
          * @param docNum
 1194  
          *            the docNum to set
 1195  
          */
 1196  
         public void setDocNum(String docNum) {
 1197  0
                 this.docNum = docNum;
 1198  0
         }
 1199  
 
 1200  
         /**
 1201  
          * @return the referencesToRefresh
 1202  
          */
 1203  
         public String getReferencesToRefresh() {
 1204  0
                 return this.referencesToRefresh;
 1205  
         }
 1206  
 
 1207  
         /**
 1208  
          * @param referencesToRefresh
 1209  
          *            the referencesToRefresh to set
 1210  
          */
 1211  
         public void setReferencesToRefresh(String referencesToRefresh) {
 1212  0
                 this.referencesToRefresh = referencesToRefresh;
 1213  0
         }
 1214  
 
 1215  
         /**
 1216  
          * @return the fieldConversions
 1217  
          */
 1218  
         public Map<String, String> getFieldConversions() {
 1219  0
                 return this.fieldConversions;
 1220  
         }
 1221  
 
 1222  
         /**
 1223  
          * @param fieldConversions
 1224  
          *            the fieldConversions to set
 1225  
          */
 1226  
         public void setFieldConversions(Map<String, String> fieldConversions) {
 1227  0
                 this.fieldConversions = fieldConversions;
 1228  0
         }
 1229  
 
 1230  
         /**
 1231  
          * @return the parameters
 1232  
          */
 1233  
         public Map getParameters() {
 1234  0
                 return this.parameters;
 1235  
         }
 1236  
 
 1237  
         /**
 1238  
          * @param parameters
 1239  
          *            the parameters to set
 1240  
          */
 1241  
         public void setParameters(Map parameters) {
 1242  0
                 this.parameters = parameters;
 1243  0
         }
 1244  
 
 1245  
         /**
 1246  
          * @return the readOnlyFieldsList
 1247  
          */
 1248  
         public List<String> getReadOnlyFieldsList() {
 1249  0
                 return this.readOnlyFieldsList;
 1250  
         }
 1251  
 
 1252  
         /**
 1253  
          * @param readOnlyFieldsList
 1254  
          *            the readOnlyFieldsList to set
 1255  
          */
 1256  
         public void setReadOnlyFieldsList(List<String> readOnlyFieldsList) {
 1257  0
                 this.readOnlyFieldsList = readOnlyFieldsList;
 1258  0
         }
 1259  
 
 1260  
         /**
 1261  
          * @return the defaultSortAttributeNames
 1262  
          */
 1263  
         public List<String> getDefaultSortAttributeNames() {
 1264  0
                 return this.defaultSortAttributeNames;
 1265  
         }
 1266  
 
 1267  
         /**
 1268  
          * @param defaultSortAttributeNames
 1269  
          *            the defaultSortAttributeNames to set
 1270  
          */
 1271  
         public void setDefaultSortAttributeNames(List<String> defaultSortAttributeNames) {
 1272  0
                 this.defaultSortAttributeNames = defaultSortAttributeNames;
 1273  0
         }
 1274  
 
 1275  
         /**
 1276  
      * @return the returnFormKey
 1277  
      */
 1278  
     public String getReturnFormKey() {
 1279  0
             return this.returnFormKey;
 1280  
     }
 1281  
 
 1282  
         /**
 1283  
      * @param returnFormKey the returnFormKey to set
 1284  
      */
 1285  
     public void setReturnFormKey(String returnFormKey) {
 1286  0
             this.returnFormKey = returnFormKey;
 1287  0
     }
 1288  
 
 1289  
         /**
 1290  
          * @return the sortAscending
 1291  
          */
 1292  
         public boolean isSortAscending() {
 1293  0
                 return this.sortAscending;
 1294  
         }
 1295  
 
 1296  
         /**
 1297  
          * @param sortAscending
 1298  
          *            the sortAscending to set
 1299  
          */
 1300  
         public void setSortAscending(boolean sortAscending) {
 1301  0
                 this.sortAscending = sortAscending;
 1302  0
         }
 1303  
 
 1304  
         public LookupService getLookupService() {
 1305  0
                 return lookupService != null ? lookupService : KNSServiceLocatorWeb.getLookupService();
 1306  
         }
 1307  
 
 1308  
         public void setLookupService(LookupService lookupService) {
 1309  0
                 this.lookupService = lookupService;
 1310  0
         }
 1311  
 
 1312  
         public EncryptionService getEncryptionService() {
 1313  0
                 return encryptionService != null ? encryptionService : CoreApiServiceLocator.getEncryptionService();
 1314  
         }
 1315  
 
 1316  
         public void setEncryptionService(EncryptionService encryptionService) {
 1317  0
                 this.encryptionService = encryptionService;
 1318  0
         }
 1319  
 
 1320  
         /**
 1321  
          * Gets the businessObjectDictionaryService attribute.
 1322  
          * 
 1323  
          * @return Returns the businessObjectDictionaryService.
 1324  
          */
 1325  
         public BusinessObjectDictionaryService getBusinessObjectDictionaryService() {
 1326  0
                 return businessObjectDictionaryService != null ? businessObjectDictionaryService : KNSServiceLocatorWeb.getBusinessObjectDictionaryService();
 1327  
         }
 1328  
 
 1329  
         /**
 1330  
          * Sets the businessObjectDictionaryService attribute value.
 1331  
          * 
 1332  
          * @param businessObjectDictionaryService
 1333  
          *            The businessObjectDictionaryService to set.
 1334  
          */
 1335  
         public void setBusinessObjectDictionaryService(BusinessObjectDictionaryService businessObjectDictionaryService) {
 1336  0
                 this.businessObjectDictionaryService = businessObjectDictionaryService;
 1337  0
         }
 1338  
 
 1339  
         /**
 1340  
      * @return the dataObjectMetaDataService
 1341  
      */
 1342  
     public DataObjectMetaDataService getDataObjectMetaDataService() {
 1343  0
                 return dataObjectMetaDataService != null ? dataObjectMetaDataService : KNSServiceLocatorWeb.getDataObjectMetaDataService();
 1344  
     }
 1345  
 
 1346  
         /**
 1347  
      * @param dataObjectMetaDataService the dataObjectMetaDataService to set
 1348  
      */
 1349  
     public void setDataObjectMetaDataService(DataObjectMetaDataService dataObjectMetaDataService) {
 1350  0
             this.dataObjectMetaDataService = dataObjectMetaDataService;
 1351  0
     }
 1352  
 
 1353  
         /**
 1354  
          * Gets the persistenceStructureService attribute.
 1355  
          * 
 1356  
          * @return Returns the persistenceStructureService.
 1357  
          */
 1358  
         public PersistenceStructureService getPersistenceStructureService() {
 1359  0
                 return persistenceStructureService != null ? persistenceStructureService : KNSServiceLocator.getPersistenceStructureService();
 1360  
         }
 1361  
 
 1362  
         /**
 1363  
          * Sets the persistenceStructureService attribute value.
 1364  
          * 
 1365  
          * @param persistenceStructureService
 1366  
          *            The persistenceStructureService to set.
 1367  
          */
 1368  
         public void setPersistenceStructureService(PersistenceStructureService persistenceStructureService) {
 1369  0
                 this.persistenceStructureService = persistenceStructureService;
 1370  0
         }
 1371  
 
 1372  
         public BusinessObjectAuthorizationService getBusinessObjectAuthorizationService() {
 1373  0
                 return businessObjectAuthorizationService != null ? businessObjectAuthorizationService : KNSServiceLocatorWeb.getBusinessObjectAuthorizationService();
 1374  
         }
 1375  
 
 1376  
         public void setBusinessObjectAuthorizationService(BusinessObjectAuthorizationService businessObjectAuthorizationService) {
 1377  0
                 this.businessObjectAuthorizationService = businessObjectAuthorizationService;
 1378  0
         }
 1379  
 
 1380  
         public MaintenanceDocumentDictionaryService getMaintenanceDocumentDictionaryService() {
 1381  0
                 return maintenanceDocumentDictionaryService != null ? maintenanceDocumentDictionaryService : KNSServiceLocatorWeb.getMaintenanceDocumentDictionaryService();
 1382  
         }
 1383  
 
 1384  
         public void setMaintenanceDocumentDictionaryService(MaintenanceDocumentDictionaryService maintenanceDocumentDictionaryService) {
 1385  0
                 this.maintenanceDocumentDictionaryService = maintenanceDocumentDictionaryService;
 1386  0
         }
 1387  
 
 1388  
 }