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