Coverage Report - org.kuali.rice.kns.uif.service.impl.LookupViewHelperServiceImpl
 
Classes in this File Line Coverage Branch Coverage Complexity
LookupViewHelperServiceImpl
0%
0/478
0%
0/252
2.739
 
 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  0
         protected boolean hideReturnLink = 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  0
     private boolean suppressActions = false;
 112  0
     private boolean showMaintenanceLinks = false;
 113  
 
 114  
         protected List<String> defaultSortAttributeNames;
 115  
         // TODO delyea: where to take into account the sort ascending value (old KNS appeared to ignore?)
 116  
         protected boolean sortAscending;
 117  
 
 118  
         /**
 119  
          * Default Constructor
 120  
          * 
 121  
          */
 122  
         public LookupViewHelperServiceImpl() {
 123  0
                 super();
 124  0
         }
 125  
 
 126  
         /**
 127  
      * @see org.kuali.rice.kns.uif.service.impl.ViewHelperServiceImpl#populateViewFromRequestParameters(org.kuali.rice.kns.uif.container.View, java.util.Map)
 128  
      */
 129  
     @Override
 130  
     public void populateViewFromRequestParameters(View view, Map<String, String> parameters) {
 131  0
             super.populateViewFromRequestParameters(view, parameters);
 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(), entry.getValue());
 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  0
                                 StringBuilder script = new StringBuilder();
 981  0
                                 for (Object key : getFieldConversions().keySet()) {
 982  0
                                         if (props.containsKey(getFieldConversions().get(key))) {
 983  0
                                                 Object fieldName = getFieldConversions().get(key)
 984  
                                                                 .replace("'", "\\'");
 985  0
                                                 Object value = props
 986  
                                                                 .get(getFieldConversions().get(key));
 987  0
                                                 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  0
                                         }
 997  
                                 }
 998  0
                                 anchor.setOnclick(script.append("parent.$.fancybox.close();return false").toString());
 999  
                         }
 1000  
                 }
 1001  0
                 return anchor;
 1002  
         }
 1003  
 
 1004  
         protected String getReturnHrefUsingParameters(Properties props, Map<String, Object> context, List returnKeys) {
 1005  0
                 if (StringUtils.isNotBlank(getReturnLocation())) {
 1006  0
                         String href = UrlFactory.parameterizeUrl(getReturnLocation(), props);
 1007  0
                         return addToReturnHref(href, context);
 1008  
                 }
 1009  0
                 return "";
 1010  
         }
 1011  
 
 1012  
         protected String addToReturnHref(String href, Map<String, Object> context) {
 1013  0
                 StringBuffer buffer = new StringBuffer(href);
 1014  
                  // TODO delyea - Figure out how to impelement Anchors in new UIF
 1015  
 //                String lookupAnchor = "";
 1016  
 //                if (StringUtils.isNotEmpty(anchor)) {
 1017  
 //                        lookupAnchor = anchor;
 1018  
 //                }
 1019  
 //                buffer.append("&anchor=" + lookupAnchor + "&docNum=" + (StringUtils.isEmpty(getDocNum()) ? "" : getDocNum()));
 1020  0
                 buffer.append("&" + UifParameters.DOC_NUM + "=" + (StringUtils.isEmpty(getDocNum()) ? "" : getDocNum()));
 1021  0
                 return buffer.toString();
 1022  
         }
 1023  
 
 1024  
         protected Properties getReturnUrlParameters(Object dataObject, Map<String,String> fieldConversionValues, String lookupImpl, List<String> returnKeys) {
 1025  0
                 Properties props = new Properties();
 1026  0
                 props.put(KNSConstants.DISPATCH_REQUEST_PARAMETER, KNSConstants.RETURN_METHOD_TO_CALL);
 1027  0
                 if (getReturnFormKey() != null) {
 1028  0
                         props.put(UifParameters.FORM_KEY, getReturnFormKey());
 1029  
                 }
 1030  0
                 if (lookupImpl != null) {
 1031  0
                         props.put(KNSConstants.REFRESH_CALLER, lookupImpl);
 1032  
                 }
 1033  0
                 if (getDocNum() != null) {
 1034  0
                         props.put(UifParameters.DOC_NUM, getDocNum());
 1035  
                 }
 1036  
 
 1037  0
                 if (getReferencesToRefresh() != null) {
 1038  0
                         props.put(KNSConstants.REFERENCES_TO_REFRESH, getReferencesToRefresh());
 1039  
                 }
 1040  
 
 1041  0
                 Iterator<String> returnKeysIt = returnKeys.iterator();
 1042  0
                 while (returnKeysIt.hasNext()) {
 1043  0
                         String fieldNm = returnKeysIt.next();
 1044  
 
 1045  0
                         Object fieldVal = ObjectUtils.getPropertyValue(dataObject, fieldNm);
 1046  0
                         if (fieldVal == null) {
 1047  0
                                 fieldVal = StringUtils.EMPTY;
 1048  
                         }
 1049  
 
 1050  0
                         if (getBusinessObjectAuthorizationService().attributeValueNeedsToBeEncryptedOnFormsAndLinks(getDataObjectClass(), fieldNm)) {
 1051  
                                 try {
 1052  0
                                         fieldVal = getEncryptionService().encrypt(fieldVal) + EncryptionService.ENCRYPTION_POST_PREFIX;
 1053  0
                                 } catch (GeneralSecurityException e) {
 1054  0
                                         LOG.error("Exception while trying to encrypted value for inquiry framework.", e);
 1055  0
                                         throw new RuntimeException(e);
 1056  0
                                 }
 1057  
 
 1058  
                         }
 1059  
 
 1060  
                         // need to format date in url
 1061  0
                         if (fieldVal instanceof Date) {
 1062  0
                                 DateFormatter dateFormatter = new DateFormatter();
 1063  0
                                 fieldVal = dateFormatter.format(fieldVal);
 1064  
                         }
 1065  
 
 1066  0
                         if (fieldConversionValues.containsKey(fieldNm)) {
 1067  0
                                 fieldNm = fieldConversionValues.get(fieldNm);
 1068  
                         }
 1069  
 
 1070  0
                         props.put(fieldNm, fieldVal.toString());
 1071  0
                 }
 1072  
 
 1073  0
                 return props;
 1074  
         }
 1075  
 
 1076  
         /**
 1077  
          * @return a List of the names of fields which are marked in data dictionary as return fields.
 1078  
          */
 1079  
         protected List<String> getReturnKeys() {
 1080  
                 List<String> returnKeys;
 1081  0
                 if (fieldConversions != null && !fieldConversions.isEmpty()) {
 1082  0
                         returnKeys = new ArrayList<String>(fieldConversions.keySet());
 1083  
                 } else {
 1084  0
                         returnKeys = getDataObjectMetaDataService().listPrimaryKeyFieldNames(getDataObjectClass());
 1085  
                 }
 1086  
 
 1087  0
                 return returnKeys;
 1088  
         }
 1089  
 
 1090  
     /**
 1091  
      * Determines whether a given data object that's returned as one of the lookup's results is considered returnable, which means that for
 1092  
      * single-value lookups, a "return value" link may be rendered, and for multiple value lookups, a checkbox is rendered.
 1093  
      *
 1094  
      * Note that this can be part of an authorization mechanism, but not the complete authorization mechanism.  The component that invoked the lookup/
 1095  
      * 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
 1096  
      * are ways around this method (e.g. crafting a custom return URL).
 1097  
      *
 1098  
      * @param dataObject an object from the search result set
 1099  
      * @return true if the row is returnable and false if it is not
 1100  
      */
 1101  
         protected boolean isResultReturnable(Object dataObject) {
 1102  0
                 return true;
 1103  
         }
 1104  
 
 1105  
         /**
 1106  
          * @see org.kuali.rice.kns.uif.service.LookupViewHelperService#getConditionallyReadOnlyPropertyNames()
 1107  
          */
 1108  
         public Set<String> getConditionallyReadOnlyPropertyNames() {
 1109  0
                 return new HashSet<String>();
 1110  
         }
 1111  
 
 1112  
         /**
 1113  
          * @see org.kuali.rice.kns.uif.service.LookupViewHelperService#getConditionallyRequiredPropertyNames()
 1114  
          */
 1115  
         public Set<String> getConditionallyRequiredPropertyNames() {
 1116  0
                 return new HashSet<String>();
 1117  
         }
 1118  
 
 1119  
         /**
 1120  
          * @see org.kuali.rice.kns.uif.service.LookupViewHelperService#getConditionallyHiddenPropertyNames()
 1121  
          */
 1122  
         public Set<String> getConditionallyHiddenPropertyNames() {
 1123  0
                 return new HashSet<String>();
 1124  
         }
 1125  
          
 1126  
         /**
 1127  
      * @return the atLeastOneRowReturnable
 1128  
      */
 1129  
     public boolean isAtLeastOneRowReturnable() {
 1130  0
             return this.atLeastOneRowReturnable;
 1131  
     }
 1132  
 
 1133  
     /**
 1134  
      * @param atLeastOneRowReturnable the atLeastOneRowReturnable to set
 1135  
      */
 1136  
     public void setAtLeastOneRowReturnable(boolean atLeastOneRowReturnable) {
 1137  0
             this.atLeastOneRowReturnable = atLeastOneRowReturnable;
 1138  0
     }
 1139  
 
 1140  
         /**
 1141  
      * @return the atLeastOneRowHasActions
 1142  
      */
 1143  
     public boolean isAtLeastOneRowHasActions() {
 1144  0
             return this.atLeastOneRowHasActions;
 1145  
     }
 1146  
 
 1147  
         /**
 1148  
      * @param atLeastOneRowHasActions the atLeastOneRowHasActions to set
 1149  
      */
 1150  
     public void setAtLeastOneRowHasActions(boolean atLeastOneRowHasActions) {
 1151  0
             this.atLeastOneRowHasActions = atLeastOneRowHasActions;
 1152  0
     }
 1153  
 
 1154  
         /**
 1155  
      * @return the suppressActions
 1156  
      */
 1157  
     public boolean isSuppressActions() {
 1158  0
             return this.suppressActions;
 1159  
     }
 1160  
 
 1161  
         /**
 1162  
      * @param suppressActions the suppressActions to set
 1163  
      */
 1164  
     public void setSuppressActions(boolean suppressActions) {
 1165  0
             this.suppressActions = suppressActions;
 1166  0
     }
 1167  
 
 1168  
     /**
 1169  
      * Gets the showMaintenanceLinks attribute.
 1170  
      * @return Returns the showMaintenanceLinks.
 1171  
      */
 1172  
     public boolean isShowMaintenanceLinks() {
 1173  0
         return showMaintenanceLinks;
 1174  
     }
 1175  
 
 1176  
     /**
 1177  
      * Sets the showMaintenanceLinks attribute value.
 1178  
      * @param showMaintenanceLinks The showMaintenanceLinks to set.
 1179  
      */
 1180  
     public void setShowMaintenanceLinks(boolean showMaintenanceLinks) {
 1181  0
         this.showMaintenanceLinks = showMaintenanceLinks;
 1182  0
     }
 1183  
 
 1184  
         /**
 1185  
          * @return the dataObjectClass
 1186  
          */
 1187  
         public Class<?> getDataObjectClass() {
 1188  0
                 return this.dataObjectClass;
 1189  
         }
 1190  
 
 1191  
         /**
 1192  
          * @param dataObjectClass
 1193  
          *            the dataObjectClass to set
 1194  
          */
 1195  
         public void setDataObjectClass(Class<?> dataObjectClass) {
 1196  0
                 this.dataObjectClass = dataObjectClass;
 1197  0
         }
 1198  
 
 1199  
         /**
 1200  
          * @return the returnLocation
 1201  
          */
 1202  
         public String getReturnLocation() {
 1203  0
                 return this.returnLocation;
 1204  
         }
 1205  
 
 1206  
         /**
 1207  
          * @param returnLocation
 1208  
          *            the returnLocation to set
 1209  
          */
 1210  
         public void setReturnLocation(String returnLocation) {
 1211  0
                 this.returnLocation = returnLocation;
 1212  0
         }
 1213  
 
 1214  
         /**
 1215  
      * @return the hideReturnLink
 1216  
      */
 1217  
     public boolean isHideReturnLink() {
 1218  0
             return this.hideReturnLink;
 1219  
     }
 1220  
 
 1221  
         /**
 1222  
      * @param hideReturnLink the hideReturnLink to set
 1223  
      */
 1224  
     public void setHideReturnLink(boolean hideReturnLink) {
 1225  0
             this.hideReturnLink = hideReturnLink;
 1226  0
     }
 1227  
 
 1228  
         /**
 1229  
          * @return the docNum
 1230  
          */
 1231  
         public String getDocNum() {
 1232  0
                 return this.docNum;
 1233  
         }
 1234  
 
 1235  
         /**
 1236  
          * @param docNum
 1237  
          *            the docNum to set
 1238  
          */
 1239  
         public void setDocNum(String docNum) {
 1240  0
                 this.docNum = docNum;
 1241  0
         }
 1242  
 
 1243  
         /**
 1244  
          * @return the referencesToRefresh
 1245  
          */
 1246  
         public String getReferencesToRefresh() {
 1247  0
                 return this.referencesToRefresh;
 1248  
         }
 1249  
 
 1250  
         /**
 1251  
          * @param referencesToRefresh
 1252  
          *            the referencesToRefresh to set
 1253  
          */
 1254  
         public void setReferencesToRefresh(String referencesToRefresh) {
 1255  0
                 this.referencesToRefresh = referencesToRefresh;
 1256  0
         }
 1257  
 
 1258  
         /**
 1259  
          * @return the fieldConversions
 1260  
          */
 1261  
         public Map<String, String> getFieldConversions() {
 1262  0
                 return this.fieldConversions;
 1263  
         }
 1264  
 
 1265  
         /**
 1266  
          * @param fieldConversions
 1267  
          *            the fieldConversions to set
 1268  
          */
 1269  
         public void setFieldConversions(Map<String, String> fieldConversions) {
 1270  0
                 this.fieldConversions = fieldConversions;
 1271  0
         }
 1272  
 
 1273  
         /**
 1274  
          * @return the parameters
 1275  
          */
 1276  
         public Map getParameters() {
 1277  0
                 return this.parameters;
 1278  
         }
 1279  
 
 1280  
         /**
 1281  
          * @param parameters
 1282  
          *            the parameters to set
 1283  
          */
 1284  
         public void setParameters(Map parameters) {
 1285  0
                 this.parameters = parameters;
 1286  0
         }
 1287  
 
 1288  
         /**
 1289  
          * @return the readOnlyFieldsList
 1290  
          */
 1291  
         public List<String> getReadOnlyFieldsList() {
 1292  0
                 return this.readOnlyFieldsList;
 1293  
         }
 1294  
 
 1295  
         /**
 1296  
          * @param readOnlyFieldsList
 1297  
          *            the readOnlyFieldsList to set
 1298  
          */
 1299  
         public void setReadOnlyFieldsList(List<String> readOnlyFieldsList) {
 1300  0
                 this.readOnlyFieldsList = readOnlyFieldsList;
 1301  0
         }
 1302  
 
 1303  
         /**
 1304  
          * @return the defaultSortAttributeNames
 1305  
          */
 1306  
         public List<String> getDefaultSortAttributeNames() {
 1307  0
                 return this.defaultSortAttributeNames;
 1308  
         }
 1309  
 
 1310  
         /**
 1311  
          * @param defaultSortAttributeNames
 1312  
          *            the defaultSortAttributeNames to set
 1313  
          */
 1314  
         public void setDefaultSortAttributeNames(List<String> defaultSortAttributeNames) {
 1315  0
                 this.defaultSortAttributeNames = defaultSortAttributeNames;
 1316  0
         }
 1317  
 
 1318  
         /**
 1319  
      * @return the returnFormKey
 1320  
      */
 1321  
     public String getReturnFormKey() {
 1322  0
             return this.returnFormKey;
 1323  
     }
 1324  
 
 1325  
         /**
 1326  
      * @param returnFormKey the returnFormKey to set
 1327  
      */
 1328  
     public void setReturnFormKey(String returnFormKey) {
 1329  0
             this.returnFormKey = returnFormKey;
 1330  0
     }
 1331  
 
 1332  
         /**
 1333  
          * @return the sortAscending
 1334  
          */
 1335  
         public boolean isSortAscending() {
 1336  0
                 return this.sortAscending;
 1337  
         }
 1338  
 
 1339  
         /**
 1340  
          * @param sortAscending
 1341  
          *            the sortAscending to set
 1342  
          */
 1343  
         public void setSortAscending(boolean sortAscending) {
 1344  0
                 this.sortAscending = sortAscending;
 1345  0
         }
 1346  
 
 1347  
         public LookupService getLookupService() {
 1348  0
                 return lookupService != null ? lookupService : KNSServiceLocatorWeb.getLookupService();
 1349  
         }
 1350  
 
 1351  
         public void setLookupService(LookupService lookupService) {
 1352  0
                 this.lookupService = lookupService;
 1353  0
         }
 1354  
 
 1355  
         public EncryptionService getEncryptionService() {
 1356  0
                 return encryptionService != null ? encryptionService : CoreApiServiceLocator.getEncryptionService();
 1357  
         }
 1358  
 
 1359  
         public void setEncryptionService(EncryptionService encryptionService) {
 1360  0
                 this.encryptionService = encryptionService;
 1361  0
         }
 1362  
 
 1363  
         /**
 1364  
          * Gets the businessObjectDictionaryService attribute.
 1365  
          * 
 1366  
          * @return Returns the businessObjectDictionaryService.
 1367  
          */
 1368  
         public BusinessObjectDictionaryService getBusinessObjectDictionaryService() {
 1369  0
                 return businessObjectDictionaryService != null ? businessObjectDictionaryService : KNSServiceLocatorWeb.getBusinessObjectDictionaryService();
 1370  
         }
 1371  
 
 1372  
         /**
 1373  
          * Sets the businessObjectDictionaryService attribute value.
 1374  
          * 
 1375  
          * @param businessObjectDictionaryService
 1376  
          *            The businessObjectDictionaryService to set.
 1377  
          */
 1378  
         public void setBusinessObjectDictionaryService(BusinessObjectDictionaryService businessObjectDictionaryService) {
 1379  0
                 this.businessObjectDictionaryService = businessObjectDictionaryService;
 1380  0
         }
 1381  
 
 1382  
         /**
 1383  
      * @return the dataObjectMetaDataService
 1384  
      */
 1385  
     public DataObjectMetaDataService getDataObjectMetaDataService() {
 1386  0
                 return dataObjectMetaDataService != null ? dataObjectMetaDataService : KNSServiceLocatorWeb.getDataObjectMetaDataService();
 1387  
     }
 1388  
 
 1389  
         /**
 1390  
      * @param dataObjectMetaDataService the dataObjectMetaDataService to set
 1391  
      */
 1392  
     public void setDataObjectMetaDataService(DataObjectMetaDataService dataObjectMetaDataService) {
 1393  0
             this.dataObjectMetaDataService = dataObjectMetaDataService;
 1394  0
     }
 1395  
 
 1396  
         /**
 1397  
          * Gets the persistenceStructureService attribute.
 1398  
          * 
 1399  
          * @return Returns the persistenceStructureService.
 1400  
          */
 1401  
         public PersistenceStructureService getPersistenceStructureService() {
 1402  0
                 return persistenceStructureService != null ? persistenceStructureService : KNSServiceLocator.getPersistenceStructureService();
 1403  
         }
 1404  
 
 1405  
         /**
 1406  
          * Sets the persistenceStructureService attribute value.
 1407  
          * 
 1408  
          * @param persistenceStructureService
 1409  
          *            The persistenceStructureService to set.
 1410  
          */
 1411  
         public void setPersistenceStructureService(PersistenceStructureService persistenceStructureService) {
 1412  0
                 this.persistenceStructureService = persistenceStructureService;
 1413  0
         }
 1414  
 
 1415  
         public BusinessObjectAuthorizationService getBusinessObjectAuthorizationService() {
 1416  0
                 return businessObjectAuthorizationService != null ? businessObjectAuthorizationService : KNSServiceLocatorWeb.getBusinessObjectAuthorizationService();
 1417  
         }
 1418  
 
 1419  
         public void setBusinessObjectAuthorizationService(BusinessObjectAuthorizationService businessObjectAuthorizationService) {
 1420  0
                 this.businessObjectAuthorizationService = businessObjectAuthorizationService;
 1421  0
         }
 1422  
 
 1423  
         public MaintenanceDocumentDictionaryService getMaintenanceDocumentDictionaryService() {
 1424  0
                 return maintenanceDocumentDictionaryService != null ? maintenanceDocumentDictionaryService : KNSServiceLocatorWeb.getMaintenanceDocumentDictionaryService();
 1425  
         }
 1426  
 
 1427  
         public void setMaintenanceDocumentDictionaryService(MaintenanceDocumentDictionaryService maintenanceDocumentDictionaryService) {
 1428  0
                 this.maintenanceDocumentDictionaryService = maintenanceDocumentDictionaryService;
 1429  0
         }
 1430  
 
 1431  
 }