Coverage Report - org.kuali.rice.kns.lookup.LookupUtils
 
Classes in this File Line Coverage Branch Coverage Complexity
LookupUtils
0%
0/318
0%
0/204
4.243
 
 1  
 /**
 2  
  * Copyright 2005-2011 The Kuali Foundation
 3  
  *
 4  
  * Licensed under the Educational Community License, Version 2.0 (the "License");
 5  
  * you may not use this file except in compliance with the License.
 6  
  * You may obtain a copy of the License at
 7  
  *
 8  
  * http://www.opensource.org/licenses/ecl2.php
 9  
  *
 10  
  * Unless required by applicable law or agreed to in writing, software
 11  
  * distributed under the License is distributed on an "AS IS" BASIS,
 12  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  
  * See the License for the specific language governing permissions and
 14  
  * limitations under the License.
 15  
  */
 16  
 package org.kuali.rice.kns.lookup;
 17  
 
 18  
 import org.apache.commons.lang.StringUtils;
 19  
 import org.apache.ojb.broker.query.Criteria;
 20  
 import org.kuali.rice.core.api.CoreApiServiceLocator;
 21  
 import org.kuali.rice.core.api.config.property.ConfigurationService;
 22  
 import org.kuali.rice.core.api.datetime.DateTimeService;
 23  
 import org.kuali.rice.core.framework.persistence.platform.DatabasePlatform;
 24  
 import org.kuali.rice.core.framework.services.CoreFrameworkServiceLocator;
 25  
 import org.kuali.rice.kns.service.BusinessObjectMetaDataService;
 26  
 import org.kuali.rice.kns.service.KNSServiceLocator;
 27  
 import org.kuali.rice.kns.util.KNSGlobalVariables;
 28  
 import org.kuali.rice.kns.web.comparator.NullValueComparator;
 29  
 import org.kuali.rice.kns.web.struts.form.KualiForm;
 30  
 import org.kuali.rice.kns.web.struts.form.LookupForm;
 31  
 import org.kuali.rice.kns.web.ui.Field;
 32  
 import org.kuali.rice.kns.web.ui.ResultRow;
 33  
 import org.kuali.rice.krad.bo.BusinessObject;
 34  
 import org.kuali.rice.krad.bo.DataObjectRelationship;
 35  
 import org.kuali.rice.krad.datadictionary.RelationshipDefinition;
 36  
 import org.kuali.rice.krad.datadictionary.control.ControlDefinition;
 37  
 import org.kuali.rice.krad.exception.ClassNotPersistableException;
 38  
 import org.kuali.rice.krad.lookup.SelectiveReferenceRefresher;
 39  
 import org.kuali.rice.krad.service.BusinessObjectDictionaryService;
 40  
 import org.kuali.rice.krad.service.DataDictionaryService;
 41  
 import org.kuali.rice.krad.service.KRADServiceLocator;
 42  
 import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
 43  
 import org.kuali.rice.krad.service.PersistenceStructureService;
 44  
 import org.kuali.rice.krad.util.KRADConstants;
 45  
 import org.kuali.rice.krad.util.ObjectUtils;
 46  
 
 47  
 import java.util.ArrayList;
 48  
 import java.util.Collection;
 49  
 import java.util.Comparator;
 50  
 import java.util.HashMap;
 51  
 import java.util.HashSet;
 52  
 import java.util.Iterator;
 53  
 import java.util.List;
 54  
 import java.util.Map;
 55  
 import java.util.Set;
 56  
 import java.util.StringTokenizer;
 57  
 
 58  
 /**
 59  
  * Utility class for Lookup related utilities and helper methods.
 60  
  */
 61  
 public class LookupUtils {
 62  0
     private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(LookupUtils.class);
 63  
 
 64  0
     public LookupUtils() {
 65  
         // default constructor for Spring to call to start up initialization process
 66  0
     }
 67  
 
 68  
     /**
 69  
      * Removes fields identified in the data dictionary as hidden from the lookup field values.
 70  
      * (This will remove Universal User ID and Person name from search requests when a user ID is entered.)
 71  
      *
 72  
      * @param fieldValues
 73  
      */
 74  
     public static void removeHiddenCriteriaFields(Class businessObjectClass, Map fieldValues) {
 75  0
         List<String> lookupFieldAttributeList =
 76  
                 getBusinessObjectMetaDataService().getLookupableFieldNames(businessObjectClass);
 77  0
         if (lookupFieldAttributeList != null) {
 78  0
             for (Iterator iter = lookupFieldAttributeList.iterator(); iter.hasNext(); ) {
 79  0
                 String attributeName = (String) iter.next();
 80  0
                 if (fieldValues.containsKey(attributeName)) {
 81  0
                     ControlDefinition controlDef = getDataDictionaryService()
 82  
                             .getAttributeControlDefinition(businessObjectClass, attributeName);
 83  0
                     if (controlDef != null && controlDef.isHidden()) {
 84  0
                         fieldValues.remove(attributeName);
 85  
                     }
 86  
                 }
 87  0
             }
 88  
         }
 89  0
     }
 90  
 
 91  
     /**
 92  
      * Parses and returns the lookup result set limit, checking first for the limit
 93  
      * for the BO being looked up, and then the global application limit if there isn't a limit
 94  
      * specific to this BO.
 95  
      *
 96  
      * @param businessObjectClass BO class to search on / get limit for.  If the passed in type is not of type
 97  
      * {@link org.kuali.rice.krad.bo.BusinessObject}, then the application-wide default limit is used.
 98  
      * @return result set limit (or null if there isn't one)
 99  
      */
 100  
     public static Integer getSearchResultsLimit(Class businessObjectClass) {
 101  0
         Integer limit = null;
 102  0
         if (BusinessObject.class.isAssignableFrom(businessObjectClass)) {
 103  0
             limit = getBusinessObjectSearchResultsLimit(businessObjectClass);
 104  
         }
 105  0
         if (limit == null) {
 106  0
             limit = getApplicationSearchResultsLimit();
 107  
         }
 108  0
         return limit;
 109  
     }
 110  
 
 111  
     /**
 112  
      *
 113  
      */
 114  
     public static Integer getApplicationSearchResultsLimit() {
 115  0
         String limitString = CoreFrameworkServiceLocator.getParameterService()
 116  
                 .getParameterValueAsString(KRADConstants.KRAD_NAMESPACE,
 117  
                         KRADConstants.DetailTypes.LOOKUP_PARM_DETAIL_TYPE,
 118  
                         KRADConstants.SystemGroupParameterNames.LOOKUP_RESULTS_LIMIT);
 119  0
         if (limitString != null) {
 120  0
             return Integer.valueOf(limitString);
 121  
         }
 122  0
         return null;
 123  
     }
 124  
 
 125  
     /**
 126  
      * Parses and returns the lookup result set limit for the passed in BO (if one exists)
 127  
      *
 128  
      * @param businessObjectClass
 129  
      * @return result set limit for this BO (or null if the BO doesn't have a limit)
 130  
      */
 131  
     public static Integer getBusinessObjectSearchResultsLimit(Class businessObjectClass) {
 132  0
                 if (!(isMultipleValueLookup())) {
 133  0
                         return getBusinessObjectDictionaryService().getLookupResultSetLimit(businessObjectClass);
 134  
                 } else {
 135  0
                 return getBusinessObjectDictionaryService().getMultipleValueLookupResultSetLimit(businessObjectClass);
 136  
                 }
 137  
     }
 138  
 
 139  
         private static boolean isMultipleValueLookup() {
 140  0
                 KualiForm kualiForm = KNSGlobalVariables.getKualiForm();
 141  0
                 if (kualiForm instanceof LookupForm) {
 142  0
                         LookupForm lookupForm = (LookupForm) kualiForm;
 143  0
                         return lookupForm.isMultipleValues();
 144  
                 } else {
 145  0
                         return false;
 146  
                 }
 147  
         } 
 148  
         
 149  
     /**
 150  
      * This method applies the search results limit to the search criteria for this BO
 151  
      *
 152  
      * @param businessObjectClass BO class to search on / get limit for
 153  
      * @param criteria search criteria
 154  
      * @param platform database platform
 155  
      */
 156  
     public static void applySearchResultsLimit(Class businessObjectClass, Criteria criteria,
 157  
             DatabasePlatform platform) {
 158  0
         Integer limit = getSearchResultsLimit(businessObjectClass);
 159  0
         if (limit != null) {
 160  0
             platform.applyLimit(limit, criteria);
 161  
         }
 162  0
     }
 163  
 
 164  
     /**
 165  
      * Applies the search results limit to the search criteria for this BO (JPA)
 166  
      *
 167  
      * @param businessObjectClass BO class to search on / get limit for
 168  
      * @param criteria search criteria
 169  
      */
 170  
     public static void applySearchResultsLimit(Class businessObjectClass,
 171  
             org.kuali.rice.core.framework.persistence.jpa.criteria.Criteria criteria) {
 172  0
         Integer limit = getSearchResultsLimit(businessObjectClass);
 173  0
         if (limit != null) {
 174  0
             criteria.setSearchLimit(limit);
 175  
         }
 176  0
     }
 177  
 
 178  
     /**
 179  
      * This method the maximum rows per page in a multiple value lookup
 180  
      *
 181  
      * @see org.kuali.KRADConstants.SystemGroupParameterNames#MULTIPLE_VALUE_LOOKUP_RESULTS_PER_PAGE
 182  
      * @return
 183  
      */
 184  
     public static Integer getApplicationMaximumSearchResulsPerPageForMultipleValueLookups() {
 185  0
         String limitString = CoreFrameworkServiceLocator.getParameterService().getParameterValueAsString(KRADConstants.KRAD_NAMESPACE, KRADConstants.DetailTypes.LOOKUP_PARM_DETAIL_TYPE, KRADConstants.SystemGroupParameterNames.MULTIPLE_VALUE_LOOKUP_RESULTS_PER_PAGE);
 186  0
         if (limitString != null) {
 187  0
             return Integer.valueOf(limitString);
 188  
         }
 189  0
         return null;
 190  
     }
 191  
 
 192  
     /**
 193  
      * This makes a , delimited String list of fields separated by a , into a List of target --> lookup readOnlyFieldsList.
 194  
      *
 195  
      * @param readOnlyFields
 196  
      * @return the List representation of the readOnlyFields  String provided.
 197  
      */
 198  
     public static List<String> translateReadOnlyFieldsToList(String readOnlyFieldsString) {
 199  0
         List<String> readOnlyFieldsList = new ArrayList<String>();
 200  0
         if (StringUtils.isNotEmpty(readOnlyFieldsString)) {
 201  0
             if (readOnlyFieldsString.indexOf(",") > 0) {
 202  0
                 StringTokenizer token = new StringTokenizer(readOnlyFieldsString, ",");
 203  0
                 while (token.hasMoreTokens()) {
 204  0
                     String element = token.nextToken();
 205  0
                     readOnlyFieldsList.add(element);
 206  0
                 }
 207  0
             }
 208  
             else {
 209  0
                 readOnlyFieldsList.add(readOnlyFieldsString);
 210  
             }
 211  
         }
 212  0
       return readOnlyFieldsList;
 213  
     }
 214  
 
 215  
     /**
 216  
      * This translates a , delimited list of pairs separated by a : into a Map of target --> lookup field conversions.
 217  
      *
 218  
      * @param conversionFields
 219  
      * @return the Map representation of the fieldConversions String provided.
 220  
      */
 221  
     public static Map translateFieldConversions(String fieldConversionsString) {
 222  0
         Map fieldConversionsMap = new HashMap();
 223  0
         if (StringUtils.isNotEmpty(fieldConversionsString)) {
 224  0
             if (fieldConversionsString.indexOf(",") > 0) {
 225  0
                 StringTokenizer token = new StringTokenizer(fieldConversionsString, ",");
 226  0
                 while (token.hasMoreTokens()) {
 227  0
                     String element = token.nextToken();
 228  0
                     fieldConversionsMap.put(element.substring(0, element.indexOf(":")), element.substring(element.indexOf(":") + 1));
 229  0
                 }
 230  0
             }
 231  
             else {
 232  0
                 fieldConversionsMap.put(fieldConversionsString.substring(0, fieldConversionsString.indexOf(":")), fieldConversionsString.substring(fieldConversionsString.indexOf(":") + 1));
 233  
             }
 234  
         }
 235  0
         return fieldConversionsMap;
 236  
     }
 237  
 
 238  
     @Deprecated
 239  
     public static Field setFieldQuickfinder(BusinessObject businessObject,
 240  
             String attributeName, Field field, List displayedFieldNames) {
 241  0
         return setFieldQuickfinder( businessObject, (String)null, false, 0, attributeName, field, displayedFieldNames );
 242  
     }
 243  
 
 244  
     @Deprecated
 245  
     public static Field setFieldQuickfinder(BusinessObject businessObject,
 246  
             String attributeName, Field field, List displayedFieldNames, SelectiveReferenceRefresher srr) {
 247  0
         return setFieldQuickfinder( businessObject, (String)null, false, 0, attributeName, field, displayedFieldNames, srr );
 248  
     }
 249  
 
 250  
     /**
 251  
      * Sets a fields quickfinder class and field conversions for an attribute.
 252  
      */
 253  
     @Deprecated
 254  
     public static Field setFieldQuickfinder(BusinessObject businessObject, String collectionName, boolean addLine, int index,
 255  
             String attributeName, Field field, List displayedFieldNames, SelectiveReferenceRefresher srr) {
 256  0
         field = setFieldQuickfinder(businessObject, collectionName, addLine, index, attributeName, field, displayedFieldNames);
 257  0
         if (srr != null) {
 258  0
             String collectionPrefix = "";
 259  0
             if ( collectionName != null ) {
 260  0
                 if (addLine) {
 261  0
                     collectionPrefix = KRADConstants.MAINTENANCE_ADD_PREFIX + collectionName + ".";
 262  
                 }
 263  
                 else {
 264  0
                     collectionPrefix = collectionName + "[" + index + "].";
 265  
                 }
 266  
             }
 267  0
             field.setReferencesToRefresh(convertReferencesToSelectCollectionToString(
 268  
                     srr.getAffectedReferencesFromLookup(businessObject, attributeName, collectionPrefix)));
 269  
         }
 270  0
         return field;
 271  
     }
 272  
 
 273  
     /**
 274  
      * Sets a fields quickfinder class and field conversions for an attribute.
 275  
      */
 276  
     @Deprecated
 277  
     public static Field setFieldQuickfinder(BusinessObject businessObject, String collectionName, boolean addLine, int index,
 278  
                                             String attributeName, Field field, List displayedFieldNames) {
 279  0
         boolean noLookup = false;
 280  0
         if (businessObject == null) {
 281  0
             return field;
 282  
         }
 283  
 
 284  0
         Boolean noLookupField = getBusinessObjectDictionaryService().noLookupFieldLookup(businessObject.getClass(), attributeName);
 285  0
         if (noLookupField != null && noLookupField) {
 286  0
             noLookup = true;
 287  
         }
 288  
 
 289  0
          return setFieldQuickfinder(businessObject, collectionName, addLine, index, attributeName, field, displayedFieldNames, noLookup);
 290  
 
 291  
     }
 292  
 
 293  
     @Deprecated
 294  
     public static Field setFieldQuickfinder(BusinessObject businessObject, String collectionName, boolean addLine, int index, String attributeName, Field field, List displayedFieldNames, boolean noLookupField)
 295  
     {
 296  0
          if (businessObject == null) {
 297  0
             return field;
 298  
         }
 299  
 
 300  0
         if (noLookupField) {
 301  0
             return field;
 302  
         }
 303  0
         DataObjectRelationship relationship = null;
 304  0
         if ( LOG.isDebugEnabled() ) {
 305  0
             LOG.debug( "setFieldQuickfinder("+businessObject.getClass().getName()+","+attributeName+","+field+","+displayedFieldNames+")" );
 306  
         }
 307  
 
 308  0
         relationship = getBusinessObjectMetaDataService().getBusinessObjectRelationship(businessObject, businessObject.getClass(), attributeName, "", false);
 309  
 
 310  0
         String collectionPrefix = "";
 311  0
         if ( collectionName != null ) {
 312  0
             if (addLine) {
 313  0
                 collectionPrefix = KRADConstants.MAINTENANCE_ADD_PREFIX + collectionName + ".";
 314  
             }
 315  
             else {
 316  0
                 collectionPrefix = collectionName + "[" + index + "].";
 317  
             }
 318  
         }
 319  
 
 320  0
         if (relationship == null) {
 321  0
             Class c = ObjectUtils.getPropertyType(businessObject, attributeName, getPersistenceStructureService());
 322  
 
 323  0
             if(c!=null) {
 324  0
                 if (attributeName.contains(".")) {
 325  0
                     attributeName = StringUtils.substringBeforeLast( attributeName, "." );
 326  
                 }
 327  
 
 328  0
                 RelationshipDefinition ddReference = getBusinessObjectMetaDataService().getBusinessObjectRelationshipDefinition(businessObject, attributeName);
 329  0
                 relationship = getBusinessObjectMetaDataService().getBusinessObjectRelationship(ddReference, businessObject, businessObject.getClass(), attributeName, "", false);
 330  0
                 if(relationship!=null) {
 331  0
                     field.setQuickFinderClassNameImpl(relationship.getRelatedClass().getName());
 332  0
                     field.setFieldConversions(generateFieldConversions( businessObject, collectionPrefix, relationship, field.getPropertyPrefix(), displayedFieldNames, null));
 333  0
                     field.setLookupParameters(generateLookupParameters( businessObject, collectionPrefix, relationship, field.getPropertyPrefix(), displayedFieldNames, null));
 334  0
                     field.setBaseLookupUrl(LookupUtils.getBaseLookupUrl(false));
 335  0
                     field.setImageSrc(getBusinessObjectDictionaryService().getSearchIconOverride(businessObject.getClass()));
 336  
                 }
 337  
             }
 338  
 
 339  0
             return field;
 340  
         }
 341  0
         if (ObjectUtils.isNestedAttribute(attributeName)) {
 342  
             //first determine the prefix and the attribute we are referring to
 343  0
             String nestedAttributePrefix = StringUtils.substringBeforeLast(attributeName, ".");
 344  
 
 345  0
             field.setQuickFinderClassNameImpl(relationship.getRelatedClass().getName());
 346  0
             field.setFieldConversions( generateFieldConversions( businessObject, collectionPrefix, relationship, field.getPropertyPrefix(), displayedFieldNames, nestedAttributePrefix ) );
 347  0
             field.setLookupParameters( generateLookupParameters( businessObject, collectionPrefix, relationship, field.getPropertyPrefix(), displayedFieldNames, nestedAttributePrefix ) );
 348  0
             field.setBaseLookupUrl(LookupUtils.getBaseLookupUrl(false));
 349  0
         } else {
 350  0
             field.setQuickFinderClassNameImpl(relationship.getRelatedClass().getName());
 351  0
             field.setFieldConversions( generateFieldConversions( businessObject, collectionPrefix, relationship, field.getPropertyPrefix(), displayedFieldNames, null ) );
 352  0
             field.setLookupParameters( generateLookupParameters( businessObject, collectionPrefix, relationship, field.getPropertyPrefix(), displayedFieldNames, null ) );
 353  0
             field.setBaseLookupUrl(LookupUtils.getBaseLookupUrl(false));
 354  
         }
 355  0
         field.setImageSrc(getBusinessObjectDictionaryService().getSearchIconOverride(businessObject.getClass()));
 356  
 
 357  0
         return field;
 358  
     }
 359  
 
 360  0
     private static String BASE_LOOKUP_ACTION_URL = null;
 361  0
     private static String BASE_MULTIPLE_VALUE_LOOKUP_ACTION_URL = null;
 362  0
     private static String BASE_INQUIRY_ACTION_URL = null;
 363  
 
 364  
     /**
 365  
      * @see org.kuali.rice.krad.uif.util.LookupInquiryUtils#getBaseLookupUrl()
 366  
      */
 367  
     @Deprecated
 368  
     public static String getBaseLookupUrl(boolean isMultipleValue) {
 369  0
         ConfigurationService kualiConfigurationService = KRADServiceLocator.getKualiConfigurationService();
 370  0
             if ( isMultipleValue ) {
 371  0
                     if ( BASE_MULTIPLE_VALUE_LOOKUP_ACTION_URL == null ) {
 372  0
                             String lookupUrl = kualiConfigurationService.getPropertyValueAsString(KRADConstants.APPLICATION_URL_KEY);
 373  0
                             if (!lookupUrl.endsWith("/")) {
 374  0
                                     lookupUrl = lookupUrl + "/";
 375  
                             }
 376  0
                                 lookupUrl += "kr/" + KRADConstants.MULTIPLE_VALUE_LOOKUP_ACTION;
 377  0
                                 BASE_MULTIPLE_VALUE_LOOKUP_ACTION_URL = lookupUrl;
 378  
                     }
 379  0
                     return BASE_MULTIPLE_VALUE_LOOKUP_ACTION_URL;
 380  
             } else {
 381  0
                     if ( BASE_LOOKUP_ACTION_URL == null ) {
 382  0
                             String lookupUrl = kualiConfigurationService.getPropertyValueAsString(KRADConstants.APPLICATION_URL_KEY);
 383  0
                             if (!lookupUrl.endsWith("/")) {
 384  0
                                     lookupUrl = lookupUrl + "/";
 385  
                             }
 386  0
                                 lookupUrl += "kr/" + KRADConstants.LOOKUP_ACTION;
 387  0
                                 BASE_LOOKUP_ACTION_URL = lookupUrl;
 388  
                     }
 389  0
                     return BASE_LOOKUP_ACTION_URL;
 390  
             }
 391  
     }
 392  
 
 393  
     @Deprecated
 394  
     public static String getBaseInquiryUrl() {
 395  0
             if ( BASE_INQUIRY_ACTION_URL == null ) {
 396  0
                     StringBuffer inquiryUrl = new StringBuffer( 
 397  
                                     KRADServiceLocator.getKualiConfigurationService().getPropertyValueAsString(
 398  
                             KRADConstants.APPLICATION_URL_KEY) );
 399  0
                         if (inquiryUrl.charAt(inquiryUrl.length()-1) != '/' ) {
 400  0
                                 inquiryUrl.append( '/' );
 401  
                         }
 402  0
                         inquiryUrl.append("kr/");
 403  0
                         inquiryUrl.append( KRADConstants.INQUIRY_ACTION );
 404  0
                         BASE_INQUIRY_ACTION_URL = inquiryUrl.toString();
 405  
             }
 406  0
             return BASE_INQUIRY_ACTION_URL;
 407  
     }
 408  
 
 409  
     public static String transformLookupUrlToMultiple(String lookupUrl) {
 410  0
             return lookupUrl.replace("kr/" + KRADConstants.LOOKUP_ACTION, "kr/" + KRADConstants.MULTIPLE_VALUE_LOOKUP_ACTION);
 411  
     }
 412  
 
 413  
     /**
 414  
      * Sets whether a field should have direct inquiries enabled.  The direct inquiry is the functionality on a page such that if the primary key for
 415  
      * a quickfinder is filled in and the direct inquiry button is pressed, then a new window will popup showing an inquiry page without going through
 416  
      * the lookup first.
 417  
      *
 418  
      * For this method to work properly, it must be called after setFieldQuickfinder
 419  
      * //TODO: chb: that should not be the case -- the relationship object the two rely upon should be established outside of the lookup/quickfinder code
 420  
      *
 421  
      *
 422  
      * @param field
 423  
      */
 424  
     private static void setFieldDirectInquiry(Field field) {
 425  0
         if (StringUtils.isNotBlank(field.getFieldConversions())) {
 426  0
             boolean directInquiriesEnabled = CoreFrameworkServiceLocator.getParameterService().getParameterValueAsBoolean(
 427  
                     KRADConstants.KRAD_NAMESPACE, KRADConstants.DetailTypes.ALL_DETAIL_TYPE, KRADConstants.SystemGroupParameterNames.ENABLE_DIRECT_INQUIRIES_IND);
 428  0
             if (directInquiriesEnabled) {
 429  0
                 if (StringUtils.isNotBlank(field.getFieldConversions())) {
 430  0
                     String fieldConversions = field.getFieldConversions();
 431  0
                     String newInquiryParameters = KRADConstants.EMPTY_STRING;
 432  0
                     String[] conversions = StringUtils.split(fieldConversions, KRADConstants.FIELD_CONVERSIONS_SEPARATOR);
 433  
 
 434  0
                     for (int l = 0; l < conversions.length; l++) {
 435  0
                         String conversion = conversions[l];
 436  
                         //String[] conversionPair = StringUtils.split(conversion, KRADConstants.FIELD_CONVERSION_PAIR_SEPARATOR);
 437  0
                         String[] conversionPair = StringUtils.split(conversion, KRADConstants.FIELD_CONVERSION_PAIR_SEPARATOR, 2);
 438  0
                         String conversionFrom = conversionPair[0];
 439  0
                         String conversionTo = conversionPair[1];
 440  0
                         newInquiryParameters += (conversionTo + KRADConstants.FIELD_CONVERSION_PAIR_SEPARATOR + conversionFrom);
 441  
 
 442  0
                         if (l < conversions.length - 1) {
 443  0
                             newInquiryParameters += KRADConstants.FIELD_CONVERSIONS_SEPARATOR;
 444  
                         }
 445  
                     }
 446  
 
 447  0
                     field.setInquiryParameters(newInquiryParameters);
 448  
                 }
 449  
             }
 450  0
             field.setFieldDirectInquiryEnabled(directInquiriesEnabled);
 451  0
         }
 452  
         else {
 453  0
             field.setFieldDirectInquiryEnabled(false);
 454  
         }
 455  0
     }
 456  
 
 457  
     /**
 458  
      *
 459  
      * @param field
 460  
      * @return the altered Field object
 461  
      */
 462  
     public static Field setFieldDirectInquiry(BusinessObject businessObject, String attributeName, Field field)
 463  
     {
 464  0
                 if (businessObject == null)
 465  
                 {
 466  0
             return field;
 467  
         }
 468  
 
 469  0
         Boolean noDirectInquiry = getBusinessObjectDictionaryService().noDirectInquiryFieldLookup(businessObject.getClass(), attributeName);
 470  
         //check if noDirectInquiry is present and true, but if it's not set in existing data dictionary definitions, don't create a direct inquiry
 471  0
         if (noDirectInquiry != null && noDirectInquiry.booleanValue() || noDirectInquiry == null) {
 472  0
             return field;
 473  
         }
 474  
 
 475  0
         setFieldDirectInquiry(field);
 476  
 
 477  0
         return field;
 478  
     }
 479  
 
 480  0
     private static Map<Class,Map<String,Map>> referencesForForeignKey = new HashMap<Class, Map<String,Map>>();
 481  
 
 482  
     @Deprecated
 483  
     public static Map getPrimitiveReference(BusinessObject businessObject, String attributeName) {
 484  0
         Map chosenReferenceByKeySize = new HashMap();
 485  0
         Map chosenReferenceByFieldName = new HashMap();
 486  
 
 487  0
         Map referenceClasses = null;
 488  
 
 489  
         try {
 490  
             // add special caching of these relationships since the Spring caching is so expensive
 491  0
             Map<String,Map> propMap = referencesForForeignKey.get(businessObject.getClass());
 492  0
             if ( propMap == null ) {
 493  0
                 propMap = new HashMap<String, Map>();
 494  0
                 referencesForForeignKey.put(businessObject.getClass(), propMap);
 495  
             }
 496  0
             if ( propMap.containsKey(attributeName) ) {
 497  0
                 referenceClasses = propMap.get( attributeName );
 498  
             } else {
 499  
                     //KFSMI-709: Make Inquiry Framework use BusinessObjectMetadataService instead of just PersistenceStructureService
 500  0
                     referenceClasses = getBusinessObjectMetaDataService().getReferencesForForeignKey(businessObject, attributeName);
 501  0
                     if(referenceClasses==null || referenceClasses.isEmpty()) {
 502  0
                         if ( getPersistenceStructureService().isPersistable(businessObject.getClass()) ) {
 503  0
                             referenceClasses = getPersistenceStructureService().getReferencesForForeignKey(businessObject.getClass(), attributeName);
 504  
                         }
 505  
                     }
 506  0
                 propMap.put(attributeName, referenceClasses);
 507  
             }
 508  0
         } catch ( ClassNotPersistableException ex ) {
 509  
             // do nothing, there is no quickfinder
 510  0
             Map<String,Map> propMap = referencesForForeignKey.get(businessObject.getClass());
 511  0
             propMap.put(attributeName, null);
 512  0
         }
 513  
 
 514  
         // if field is not fk to any reference class, return field object w no quickfinder
 515  0
         if (referenceClasses == null || referenceClasses.isEmpty()) {
 516  0
             return chosenReferenceByKeySize;
 517  
         }
 518  
 
 519  
         /*
 520  
          * if field is fk to more than one reference, take the class with the least # of pk fields, this should give the correct
 521  
          * grain for the attribute
 522  
          */
 523  0
         int minKeys = Integer.MAX_VALUE;
 524  0
         for (Iterator iter = referenceClasses.keySet().iterator(); iter.hasNext();) {
 525  0
             String attr = (String) iter.next();
 526  0
             Class clazz = (Class) referenceClasses.get(attr);
 527  0
             List pkNames = getBusinessObjectMetaDataService().listPrimaryKeyFieldNames(clazz);
 528  
 
 529  
             // Compare based on key size.
 530  0
             if (pkNames.size() < minKeys) {
 531  0
                 minKeys = pkNames.size();
 532  0
                 chosenReferenceByKeySize.clear();
 533  0
                 chosenReferenceByKeySize.put(attr, clazz);
 534  
             }
 535  
 
 536  
             // Compare based on field name.
 537  0
             if (attributeName.startsWith(attr)) {
 538  0
                 chosenReferenceByFieldName.clear();
 539  0
                 chosenReferenceByFieldName.put(attr, clazz);
 540  
             }
 541  0
         }
 542  
 
 543  
         // If a compatible key was found based on field names, prefer it, otherwise use choice by key size.
 544  0
         return chosenReferenceByFieldName.isEmpty() ? chosenReferenceByKeySize : chosenReferenceByFieldName;
 545  
     }
 546  
 
 547  
     /**
 548  
      *
 549  
      * This method walks through the nested attribute and finds the last business object in the chain and returns it (excluding the
 550  
      * last parameter which is the actual attribute)
 551  
      *
 552  
      * @param attributeName
 553  
      * @return
 554  
      */
 555  
     public static BusinessObject getNestedBusinessObject(BusinessObject bo, String attributeName) {
 556  0
         String[] nestedAttributes = StringUtils.split(attributeName, ".");
 557  
 
 558  0
         BusinessObject childBO = null;
 559  0
         String attributeRefName = "";
 560  0
         Class clazz = null;
 561  0
         if (nestedAttributes.length > 1) {
 562  0
             String attributeStringSoFar = "";
 563  0
             for (int i = 0; i < nestedAttributes.length - 1; i++) {
 564  
                 // we need to build a string of the attribute names depending on which iteration we're in.
 565  
                 // so if the original attributeName string we're using is "a.b.c.d.e", then first iteration would use
 566  
                 // "a", 2nd "a.b", 3rd "a.b.c", etc.
 567  0
                 if (i != 0) {
 568  0
                     attributeStringSoFar = attributeStringSoFar + ".";
 569  
                 }
 570  0
                 attributeStringSoFar = attributeStringSoFar + nestedAttributes[i];
 571  
 
 572  0
                 clazz = ObjectUtils.getPropertyType( bo, attributeStringSoFar, getPersistenceStructureService() );
 573  
 
 574  0
                 if (clazz != null && BusinessObject.class.isAssignableFrom(clazz)) {
 575  
                     try {
 576  0
                             childBO = (BusinessObject) ObjectUtils.createNewObjectFromClass(clazz);
 577  
                     }
 578  0
                     catch (Exception e) {
 579  0
                         return null;
 580  0
                     }
 581  
                 }
 582  
             }
 583  
         }
 584  0
         return childBO;
 585  
     }
 586  
 
 587  
     public static Class getNestedReferenceClass(BusinessObject businessObject, String attributeName) {
 588  0
         BusinessObject bo = getNestedBusinessObject(businessObject, attributeName);
 589  0
         return null == bo ? null : bo.getClass();
 590  
     }
 591  
 
 592  
     @Deprecated
 593  
     private static String generateFieldConversions(BusinessObject businessObject, String collectionName, DataObjectRelationship relationship, String propertyPrefix, List displayedFieldNames, String nestedObjectPrefix) {
 594  0
         String fieldConversions = "";
 595  
 
 596  0
         if ( LOG.isDebugEnabled() ) {
 597  0
             LOG.debug( "generateFieldConversions(" + businessObject.getClass().getName() + "," + collectionName + ",\n" + relationship + "\n," + propertyPrefix + "," + displayedFieldNames + "," + nestedObjectPrefix + ")" );
 598  
         }
 599  
 
 600  
         // get the references for the given property
 601  0
         for ( Map.Entry<String,String> entry : relationship.getParentToChildReferences().entrySet() ) {
 602  0
             String fromField = entry.getValue();
 603  0
             String toField = entry.getKey();
 604  
 
 605  
             // find the displayed to field mapping
 606  0
             if (!displayedFieldNames.contains(toField)) {
 607  0
                 toField = translateToDisplayedField(businessObject.getClass(), toField, displayedFieldNames);
 608  
             }
 609  
 
 610  0
             if (StringUtils.isNotBlank(fieldConversions)) {
 611  0
                 fieldConversions += ",";
 612  
             }
 613  
 
 614  0
             if ( StringUtils.isNotEmpty( propertyPrefix ) ) {
 615  0
                 toField = propertyPrefix + "." + toField;
 616  
             }
 617  
 
 618  0
             if ( StringUtils.isNotEmpty( collectionName ) ) {
 619  0
                 toField = collectionName + toField;
 620  
             }
 621  
 
 622  0
             fieldConversions += fromField + ":" + toField;
 623  0
         }
 624  
 
 625  0
         return fieldConversions;
 626  
     }
 627  
 
 628  
     @Deprecated
 629  
     private static String generateLookupParameters(BusinessObject businessObject, String collectionName, DataObjectRelationship relationship, String propertyPrefix, List displayedFieldNames, String nestedObjectPrefix) {
 630  
 
 631  0
         String lookupParameters = "";
 632  
 
 633  0
         List displayedQFFieldNames = getBusinessObjectDictionaryService().getLookupFieldNames(relationship.getRelatedClass());
 634  0
         for ( Map.Entry<String,String> entry : relationship.getParentToChildReferences().entrySet() ) {
 635  0
             String fromField = entry.getKey();
 636  0
             String toField = entry.getValue();
 637  
 
 638  0
             if ( relationship.getUserVisibleIdentifierKey() == null || relationship.getUserVisibleIdentifierKey().equals( fromField ) ) {
 639  
                 // find the displayed from field mapping
 640  0
                 if (!displayedFieldNames.contains(fromField)) {
 641  0
                     fromField = translateToDisplayedField(businessObject.getClass(), fromField, displayedFieldNames);
 642  
                 }
 643  
 
 644  
                 // translate to field
 645  0
                 if (displayedQFFieldNames != null && !displayedQFFieldNames.contains(toField)) {
 646  0
                     toField = translateToDisplayedField(relationship.getRelatedClass(), toField, displayedQFFieldNames);
 647  
                 }
 648  
 
 649  0
                 if (StringUtils.isNotBlank(lookupParameters)) {
 650  0
                     lookupParameters += ",";
 651  
                 }
 652  
 
 653  0
                 if (propertyPrefix != null && !propertyPrefix.equals("")) {
 654  0
                     fromField = propertyPrefix + "." + fromField;
 655  
                 }
 656  
 
 657  0
                 if ( StringUtils.isNotEmpty( collectionName ) ) {
 658  0
                     fromField = collectionName + fromField;
 659  
                 }
 660  
 
 661  0
                 lookupParameters += fromField + ":" + toField;
 662  
             }
 663  0
         }
 664  
 
 665  0
         return lookupParameters;
 666  
     }
 667  
 
 668  
     @Deprecated
 669  
     private static String translateToDisplayedField(Class businessObjectClass, String fieldName, List displayedFieldNames) {        
 670  0
         if ( getPersistenceStructureService().isPersistable(businessObjectClass) ) {
 671  0
             Map nestedFkMap = getPersistenceStructureService().getNestedForeignKeyMap(businessObjectClass);
 672  
 
 673  
             // translate to primitive fk if nested
 674  
             /*
 675  
              * if (ObjectUtils.isNestedAttribute(fieldName) && nestedFkMap.containsKey(fieldName)) { fieldName = (String)
 676  
              * nestedFkMap.get(fieldName); }
 677  
              */
 678  
 
 679  0
             if (!displayedFieldNames.contains(fieldName)) {
 680  0
                 for (Iterator iterator = displayedFieldNames.iterator(); iterator.hasNext();) {
 681  0
                     String dispField = (String) iterator.next();
 682  
 
 683  0
                     if (nestedFkMap.containsKey(dispField) && nestedFkMap.get(dispField).equals(fieldName)) {
 684  0
                         fieldName = dispField;
 685  
                     }
 686  0
                 }
 687  
             }
 688  
         }
 689  
 
 690  0
         return fieldName;
 691  
     }
 692  
 
 693  
     public static String convertReferencesToSelectCollectionToString(Collection<String> referencesToRefresh) {
 694  0
         StringBuilder buf = new StringBuilder();
 695  0
         for (String reference : referencesToRefresh) {
 696  0
             buf.append(reference).append(KRADConstants.REFERENCES_TO_REFRESH_SEPARATOR);
 697  
         }
 698  0
         if (!referencesToRefresh.isEmpty()) {
 699  
             // we appended one too many separators, remove it
 700  0
             buf.delete(buf.length() - KRADConstants.REFERENCES_TO_REFRESH_SEPARATOR.length(), buf.length());
 701  
         }
 702  0
         return buf.toString();
 703  
     }
 704  
 
 705  
     public static String convertSetOfObjectIdsToString(Set<String> objectIds) {
 706  0
         if (objectIds.isEmpty()) {
 707  0
             return "";
 708  
         }
 709  0
         StringBuilder buf = new StringBuilder();
 710  0
         for (String objectId : objectIds) {
 711  0
             if (objectId.contains(KRADConstants.MULTIPLE_VALUE_LOOKUP_OBJ_IDS_SEPARATOR)) {
 712  0
                 throw new RuntimeException("object ID " + objectId + " contains the selected obj ID separator");
 713  
             }
 714  0
             buf.append(objectId).append(KRADConstants.MULTIPLE_VALUE_LOOKUP_OBJ_IDS_SEPARATOR);
 715  
         }
 716  
         // added one extra separator, remove it
 717  0
         buf.delete(buf.length() - KRADConstants.MULTIPLE_VALUE_LOOKUP_OBJ_IDS_SEPARATOR.length(), buf.length());
 718  
 
 719  0
         return buf.toString();
 720  
     }
 721  
 
 722  
     public static Set<String> convertStringOfObjectIdsToSet(String objectIdsString) {
 723  0
         Set<String> set = new HashSet<String>();
 724  
 
 725  0
         if (StringUtils.isNotBlank(objectIdsString)) {
 726  0
             String[] objectIds = StringUtils.splitByWholeSeparator(objectIdsString, KRADConstants.MULTIPLE_VALUE_LOOKUP_OBJ_IDS_SEPARATOR);
 727  0
             for (String objectId : objectIds) {
 728  0
                 set.add(objectId);
 729  
             }
 730  
         }
 731  0
         return set;
 732  
     }
 733  
 
 734  
     /**
 735  
      * Given a list of results from a lookup, determines the best comparator to use on the String values of each of these columns
 736  
      *
 737  
      * This method exists because each cell (represented by the Column object) lists the comparator that should be used within it based on the property value class,
 738  
      * so we gotta go thru the whole list and determine the best comparator to use
 739  
      *
 740  
      * @param resultsTable
 741  
      * @param column
 742  
      * @return
 743  
      */
 744  
     public static Comparator findBestValueComparatorForColumn(List<ResultRow> resultTable, int column) {
 745  
         // BIG HACK
 746  0
         Comparator comp = NullValueComparator.getInstance();
 747  0
         for (ResultRow row : resultTable) {
 748  0
             Comparator tempComp = row.getColumns().get(column).getValueComparator();
 749  0
             if (tempComp != null && !NullValueComparator.class.equals(tempComp.getClass())) {
 750  0
                 return tempComp;
 751  
             }
 752  0
         }
 753  0
         return comp;
 754  
     }
 755  
 
 756  
     /**
 757  
      * Given 3 sets of object IDs: the set of selected object IDs before rendering the current page,
 758  
      * the set of object IDs rendered on the page, and the set of object IDs selected on the page, computes
 759  
      * the total set of selected object IDs.
 760  
      *
 761  
      * Instead of storing it in a set, returns it in a map with the selected object ID as both the key and value
 762  
      * @param previouslySelectedObjectIds
 763  
      * @param displayedObjectIds
 764  
      * @param selectedObjectIds
 765  
      * @return
 766  
      */
 767  
     public static Map<String, String> generateCompositeSelectedObjectIds(Set<String> previouslySelectedObjectIds, Set<String> displayedObjectIds, Set<String> selectedObjectIds) {
 768  0
         Map<String, String> tempMap = new HashMap<String, String>();
 769  
         // Equivalent to the set operation:
 770  
         // (P - D) union C, where - is the set difference operator
 771  
         // P is the list of object IDs previously passed in, D is the set of displayed object IDs, and C is the set of checked obj IDs
 772  
         // since HTML does not pass a value for non-selected dcheckboxes
 773  
 
 774  
         // first build a map w/ all the previouslySelectedObjectIds as keys
 775  0
         for (String previouslySelectedObjectId : previouslySelectedObjectIds) {
 776  0
             tempMap.put(previouslySelectedObjectId, previouslySelectedObjectId);
 777  
         }
 778  
         // then remove all the displayed elements (any selected displayed elements will be added back in the next loop)
 779  0
         for (String displayedObjectId : displayedObjectIds) {
 780  0
             tempMap.remove(displayedObjectId);
 781  
         }
 782  
         // put back the selected IDs
 783  0
         for (String selectedObjectId : selectedObjectIds) {
 784  0
             tempMap.put(selectedObjectId, selectedObjectId);
 785  
         }
 786  0
         return tempMap;
 787  
     }
 788  
 
 789  
     public static DataDictionaryService getDataDictionaryService() {
 790  0
         return KRADServiceLocatorWeb.getDataDictionaryService();
 791  
     }
 792  
 
 793  
     public static PersistenceStructureService getPersistenceStructureService() {
 794  0
         return KRADServiceLocator.getPersistenceStructureService();
 795  
     }
 796  
 
 797  
     public static BusinessObjectDictionaryService getBusinessObjectDictionaryService() {
 798  0
         return KRADServiceLocatorWeb.getBusinessObjectDictionaryService();
 799  
     }
 800  
 
 801  
     public static BusinessObjectMetaDataService getBusinessObjectMetaDataService() {
 802  0
         return KNSServiceLocator.getBusinessObjectMetaDataService();
 803  
     }
 804  
 
 805  
     public static DateTimeService getDateTimeService() {
 806  0
         return CoreApiServiceLocator.getDateTimeService();
 807  
     }
 808  
 }