001/**
002 * Copyright 2005-2018 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.kuali.rice.kns.inquiry;
017
018import org.apache.commons.collections.BidiMap;
019import org.apache.commons.collections.CollectionUtils;
020import org.apache.commons.collections.bidimap.DualHashBidiMap;
021import org.apache.commons.lang.StringUtils;
022import org.kuali.rice.core.api.CoreApiServiceLocator;
023import org.kuali.rice.core.api.config.property.ConfigurationService;
024import org.kuali.rice.core.api.encryption.EncryptionService;
025import org.kuali.rice.core.web.format.Formatter;
026import org.kuali.rice.kns.datadictionary.InquirySectionDefinition;
027import org.kuali.rice.kns.lookup.HtmlData;
028import org.kuali.rice.kns.lookup.HtmlData.AnchorHtmlData;
029import org.kuali.rice.kns.lookup.LookupUtils;
030import org.kuali.rice.kns.service.BusinessObjectAuthorizationService;
031import org.kuali.rice.kns.service.BusinessObjectDictionaryService;
032import org.kuali.rice.kns.service.BusinessObjectMetaDataService;
033import org.kuali.rice.kns.service.KNSServiceLocator;
034import org.kuali.rice.kns.util.InactiveRecordsHidingUtils;
035import org.kuali.rice.kns.web.ui.Section;
036import org.kuali.rice.kns.web.ui.SectionBridge;
037import org.kuali.rice.krad.bo.BusinessObject;
038import org.kuali.rice.krad.bo.DataObjectRelationship;
039import org.kuali.rice.krad.bo.DocumentHeader;
040import org.kuali.rice.krad.bo.ExternalizableBusinessObject;
041import org.kuali.rice.krad.datadictionary.AttributeSecurity;
042import org.kuali.rice.krad.inquiry.InquirableImpl;
043import org.kuali.rice.krad.lookup.CollectionIncomplete;
044import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
045import org.kuali.rice.krad.service.LookupService;
046import org.kuali.rice.krad.service.ModuleService;
047import org.kuali.rice.krad.util.ExternalizableBusinessObjectUtils;
048import org.kuali.rice.krad.util.GlobalVariables;
049import org.kuali.rice.krad.util.KRADConstants;
050import org.kuali.rice.krad.util.ObjectUtils;
051import org.kuali.rice.krad.util.UrlFactory;
052
053import java.security.GeneralSecurityException;
054import java.util.ArrayList;
055import java.util.Collection;
056import java.util.Collections;
057import java.util.HashMap;
058import java.util.Iterator;
059import java.util.List;
060import java.util.Map;
061import java.util.Properties;
062
063/**
064 * Kuali inquirable implementation. Implements methods necessary to retrieve the
065 * business object and render the ui.
066 * 
067 * NOTE: this class is not thread safe. When using this class or any subclasses
068 * in Spring, make sure that this is not a singleton service, or serious errors
069 * may occur.
070 * 
071 * @author Kuali Rice Team (rice.collab@kuali.org)
072 *
073 * @deprecated Use {@link org.kuali.rice.krad.inquiry.InquirableImpl}.
074 */
075@Deprecated
076public class KualiInquirableImpl extends InquirableImpl implements Inquirable {
077        private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(KualiInquirableImpl.class);
078
079        protected LookupService lookupService;
080        protected BusinessObjectAuthorizationService businessObjectAuthorizationService;
081        protected BusinessObjectDictionaryService businessObjectDictionaryService;
082        protected BusinessObjectMetaDataService businessObjectMetaDataService;
083        protected EncryptionService encryptionService;
084
085        protected Map<String, Boolean> inactiveRecordDisplay;
086
087        public static final String INQUIRY_TITLE_PREFIX = "title.inquiry.url.value.prependtext";
088
089        /**
090         * Default constructor, initializes services from spring
091         */
092        public KualiInquirableImpl() {
093                inactiveRecordDisplay = new HashMap<String, Boolean>();
094        }
095
096        /**
097         * TODO: generics do not match between call to module service and call to
098         * lookup service
099         * 
100         * @see Inquirable#retrieveDataObject(java.util.Map)
101         */
102        @SuppressWarnings({ "rawtypes", "unchecked" })
103        @Override
104        public Object retrieveDataObject(Map fieldValues) {
105                if (getDataObjectClass() == null) {
106                        LOG.error("Data object class not set in inquirable.");
107                        throw new RuntimeException(
108                                        "Data object class not set in inquirable.");
109                }
110
111                Collection<Object> searchResults = null;
112                ModuleService moduleService = KRADServiceLocatorWeb
113                                .getKualiModuleService().getResponsibleModuleService(
114                                                getDataObjectClass());
115                if (moduleService != null
116                                && moduleService.isExternalizable(getDataObjectClass())) {
117                        BusinessObject bo = moduleService.getExternalizableBusinessObject(
118                                        getBusinessObjectClass(), fieldValues);
119                        if (bo != null) {
120                                ArrayList<Object> list = new ArrayList<Object>(1);
121                                list.add(bo);
122                                searchResults = new CollectionIncomplete<Object>(list, 1L);
123                        }
124                } else {
125                        // TODO: If this is to get a single BO, why using the lookup
126                        // service?
127                        searchResults = getLookupService()
128                                        .findCollectionBySearch(getDataObjectClass(), fieldValues);
129                }
130                
131                Object foundObject = null;
132                if (CollectionUtils.isNotEmpty(searchResults)) {
133                        foundObject = searchResults.iterator().next();
134                }
135                
136                return foundObject;
137        }
138
139    /**
140         * Return a business object by searching with map, the map keys should be a
141         * property name of the business object, with the map value as the value to
142         * search for.
143         */
144    @Deprecated
145        public BusinessObject getBusinessObject(Map fieldValues) {
146                return (BusinessObject) retrieveDataObject(fieldValues);
147        }
148
149        /**
150         * Objects extending KualiInquirableBase must specify the Section objects
151         * used to display the inquiry result.
152         */
153        @Deprecated
154        public List<Section> getSections(BusinessObject bo) {
155
156                List<Section> sections = new ArrayList<Section>();
157                if (getBusinessObjectClass() == null) {
158                        LOG.error("Business object class not set in inquirable.");
159                        throw new RuntimeException("Business object class not set in inquirable.");
160                }
161
162                InquiryRestrictions inquiryRestrictions = KNSServiceLocator.getBusinessObjectAuthorizationService()
163                                .getInquiryRestrictions(bo, GlobalVariables.getUserSession().getPerson());
164
165                Collection<InquirySectionDefinition> inquirySections = getBusinessObjectDictionaryService().getInquirySections(
166                                getBusinessObjectClass());
167                for (Iterator<InquirySectionDefinition> iter = inquirySections.iterator(); iter.hasNext();) {
168                        InquirySectionDefinition inquirySection = iter.next();
169                        if (!inquiryRestrictions.isHiddenSectionId(inquirySection.getId())) {
170                                Section section = SectionBridge.toSection(this, inquirySection, bo, inquiryRestrictions);
171                                sections.add(section);
172                        }
173                }
174
175                return sections;
176        }
177
178        /**
179         * Helper method to build an inquiry url for a result field.
180         * 
181         * @param bo
182         *            the business object instance to build the urls for
183         * @param propertyName
184         *            the property which links to an inquirable
185         * @return String url to inquiry
186         */
187        @Deprecated
188        public HtmlData getInquiryUrl(BusinessObject businessObject, String attributeName, boolean forceInquiry) {
189                Properties parameters = new Properties();
190                AnchorHtmlData hRef = new AnchorHtmlData(KRADConstants.EMPTY_STRING, KRADConstants.EMPTY_STRING);
191                parameters.put(KRADConstants.DISPATCH_REQUEST_PARAMETER, "start");
192
193                Class inquiryBusinessObjectClass = null;
194                String attributeRefName = "";
195                boolean isPkReference = false;
196
197                boolean doesNestedReferenceHaveOwnPrimitiveReference = false;
198                BusinessObject nestedBusinessObject = null;
199
200                Class businessObjectClass = ObjectUtils.materializeClassForProxiedObject(businessObject);
201                if (attributeName.equals(getBusinessObjectDictionaryService().getTitleAttribute(businessObjectClass))) {
202                        inquiryBusinessObjectClass = businessObjectClass;
203                        isPkReference = true;
204                }
205                else {
206                        if (ObjectUtils.isNestedAttribute(attributeName)) {
207                                // if we have a reference object, we should determine if we
208                                // should either provide an inquiry link to
209                                // the reference object itself, or some other nested primitive.
210
211                                // for example, if the attribute is
212                                // "referenceObject.someAttribute", and there is no primitive
213                                // reference for
214                                // "someAttribute", then an inquiry link is provided to the
215                                // "referenceObject". If it does have a primitive reference,
216                                // then
217                                // the inquiry link is directed towards it instead
218                                String nestedReferenceName = ObjectUtils.getNestedAttributePrefix(attributeName);
219                                Object nestedReferenceObject = ObjectUtils.getNestedValue(businessObject, nestedReferenceName);
220
221                                if (ObjectUtils.isNotNull(nestedReferenceObject) && nestedReferenceObject instanceof BusinessObject) {
222                                        nestedBusinessObject = (BusinessObject) nestedReferenceObject;
223                                        String nestedAttributePrimitive = ObjectUtils.getNestedAttributePrimitive(attributeName);
224                                        Class nestedBusinessObjectClass = ObjectUtils
225                                                        .materializeClassForProxiedObject(nestedBusinessObject);
226
227                                        if (nestedAttributePrimitive.equals(getBusinessObjectDictionaryService().getTitleAttribute(
228                                                        nestedBusinessObjectClass))) {
229                                                // we are going to inquiry the record that contains the
230                                                // attribute we're rendering an inquiry URL for
231                                                inquiryBusinessObjectClass = nestedBusinessObjectClass;
232                                                // I know it's already set to false, just to show how
233                                                // this variable is set
234                                                doesNestedReferenceHaveOwnPrimitiveReference = false;
235                                        }
236                                        else {
237                                                Map primitiveReference = LookupUtils.getPrimitiveReference(nestedBusinessObject,
238                                                                nestedAttributePrimitive);
239                                                if (primitiveReference != null && !primitiveReference.isEmpty()) {
240                                                        attributeRefName = (String) primitiveReference.keySet().iterator().next();
241                                                        inquiryBusinessObjectClass = (Class) primitiveReference.get(attributeRefName);
242                                                        doesNestedReferenceHaveOwnPrimitiveReference = true;
243                                                }
244                                                else {
245                                                        // we are going to inquiry the record that contains
246                                                        // the attribute we're rendering an inquiry URL for
247                                                        inquiryBusinessObjectClass = ObjectUtils
248                                                                        .materializeClassForProxiedObject(nestedBusinessObject);
249                                                        // I know it's already set to false, just to show
250                                                        // how this variable is set
251                                                        doesNestedReferenceHaveOwnPrimitiveReference = false;
252                                                }
253                                        }
254                                }
255                        }
256                        else {
257                                Map primitiveReference = LookupUtils.getPrimitiveReference(businessObject, attributeName);
258                                if (primitiveReference != null && !primitiveReference.isEmpty()) {
259                                        attributeRefName = (String) primitiveReference.keySet().iterator().next();
260                                        inquiryBusinessObjectClass = (Class) primitiveReference.get(attributeRefName);
261                                }
262                        }
263                }
264
265                if (inquiryBusinessObjectClass != null && DocumentHeader.class.isAssignableFrom(inquiryBusinessObjectClass)) {
266                        String documentNumber = (String) ObjectUtils.getPropertyValue(businessObject, attributeName);
267                        if (!StringUtils.isBlank(documentNumber)) {
268                                // if NullPointerException on the following line, maybe the
269                                // Spring bean wasn't injected w/ KualiConfigurationException,
270                                // or if
271                                // instances of a sub-class of this class are not Spring
272                                // created, then override getKualiConfigurationService() in the
273                                // subclass
274                                // to return the configuration service from a Spring service
275                                // locator (or set it).
276                                hRef.setHref(getKualiConfigurationService().getPropertyValueAsString(KRADConstants.WORKFLOW_URL_KEY)
277                                                + KRADConstants.DOCHANDLER_DO_URL + documentNumber + KRADConstants.DOCHANDLER_URL_CHUNK);
278                        }
279                        return hRef;
280                }
281
282                if (inquiryBusinessObjectClass == null
283                                || getBusinessObjectDictionaryService().isInquirable(inquiryBusinessObjectClass) == null
284                                || !getBusinessObjectDictionaryService().isInquirable(inquiryBusinessObjectClass).booleanValue()) {
285                        return hRef;
286                }
287
288                synchronized (SUPER_CLASS_TRANSLATOR_LIST) {
289                        for (Class clazz : SUPER_CLASS_TRANSLATOR_LIST) {
290                                if (clazz.isAssignableFrom(inquiryBusinessObjectClass)) {
291                                        inquiryBusinessObjectClass = clazz;
292                                        break;
293                                }
294                        }
295                }
296
297                if (!inquiryBusinessObjectClass.isInterface()
298                                && ExternalizableBusinessObject.class.isAssignableFrom(inquiryBusinessObjectClass)) {
299                        inquiryBusinessObjectClass = ExternalizableBusinessObjectUtils
300                                        .determineExternalizableBusinessObjectSubInterface(inquiryBusinessObjectClass);
301                }
302
303                parameters.put(KRADConstants.BUSINESS_OBJECT_CLASS_ATTRIBUTE, inquiryBusinessObjectClass.getName());
304
305                // listPrimaryKeyFieldNames returns an unmodifiable list. So a copy is
306                // necessary.
307                List<String> keys = new ArrayList<String>(KRADServiceLocatorWeb.getLegacyDataAdapter().listPrimaryKeyFieldNames(
308                                inquiryBusinessObjectClass));
309
310                if (keys == null) {
311                        keys = Collections.emptyList();
312                }
313
314                DataObjectRelationship dataObjectRelationship = null;
315
316                if (attributeRefName != null && !"".equals(attributeRefName)) {
317                        dataObjectRelationship = getBusinessObjectMetaDataService().getBusinessObjectRelationship(
318                                        businessObject, attributeRefName);
319
320                        if (dataObjectRelationship != null && dataObjectRelationship.getParentToChildReferences() != null) {
321                                for (String targetNamePrimaryKey : dataObjectRelationship.getParentToChildReferences().values()) {
322                                        keys.add(targetNamePrimaryKey);
323                                }
324                        }
325                }
326                // build key value url parameters used to retrieve the business object
327                String keyName = null;
328                String keyConversion = null;
329                Map<String, String> fieldList = new HashMap<String, String>();
330                for (Iterator iter = keys.iterator(); iter.hasNext();) {
331                        keyName = (String) iter.next();
332                        keyConversion = keyName;
333                        if (ObjectUtils.isNestedAttribute(attributeName)) {
334                                if (doesNestedReferenceHaveOwnPrimitiveReference) {
335                                        String nestedAttributePrefix = ObjectUtils.getNestedAttributePrefix(attributeName);
336                                        // String foreignKeyFieldName =
337                                        // getBusinessObjectMetaDataService().getForeignKeyFieldName(
338                                        // inquiryBusinessObjectClass.getClass(), attributeRefName,
339                                        // keyName);
340
341                                        String foreignKeyFieldName = getBusinessObjectMetaDataService().getForeignKeyFieldName(
342                                                        nestedBusinessObject.getClass(), attributeRefName, keyName);
343                                        keyConversion = nestedAttributePrefix + "." + foreignKeyFieldName;
344                                }
345                                else {
346                                        keyConversion = ObjectUtils.getNestedAttributePrefix(attributeName) + "." + keyName;
347                                }
348                        }
349                        else {
350                                if (isPkReference) {
351                                        keyConversion = keyName;
352                                }
353                                else if (dataObjectRelationship != null) {
354                                        // Using BusinessObjectMetaDataService instead of
355                                        // PersistenceStructureService
356                                        // since otherwise, relationship information from
357                                        // datadictionary is not used at all
358                                        // Also, BOMDS.getBusinessObjectRelationship uses
359                                        // PersistenceStructureService,
360                                        // so both datadictionary and the persistance layer get
361                                        // covered
362                                        /*
363                                         * DataObjectRelationship dataObjectRelationship =
364                                         * getBusinessObjectMetaDataService
365                                         * ().getBusinessObjectRelationship( businessObject,
366                                         * attributeRefName);
367                                         */
368                                        BidiMap bidiMap = new DualHashBidiMap(dataObjectRelationship.getParentToChildReferences());
369                                        keyConversion = (String) bidiMap.getKey(keyName);
370                                        // keyConversion =
371                                        // getPersistenceStructureService().getForeignKeyFieldName(businessObject.getClass(),
372                                        // attributeRefName, keyName);
373                                }
374                        }
375                        Object keyValue = null;
376                        if (keyConversion != null) {
377                                keyValue = ObjectUtils.getPropertyValue(businessObject, keyConversion);
378                        }
379
380                        if (keyValue == null) {
381                                keyValue = "";
382                        }
383                        else if (keyValue instanceof java.sql.Date) { // format the date for
384                                                                                                                        // passing in url
385                                if (Formatter.findFormatter(keyValue.getClass()) != null) {
386                                        Formatter formatter = Formatter.getFormatter(keyValue.getClass());
387                                        keyValue = (String) formatter.format(keyValue);
388                                }
389                        }
390                        else {
391                                keyValue = keyValue.toString();
392                        }
393
394                        // Encrypt value if it is a field that has restriction that prevents
395                        // a value from being shown to user,
396                        // because we don't want the browser history to store the restricted
397                        // attribute's value in the URL
398                        AttributeSecurity attributeSecurity = KRADServiceLocatorWeb.getDataDictionaryService().getAttributeSecurity(
399                                        businessObject.getClass().getName(), keyName);
400                        if (attributeSecurity != null && attributeSecurity.hasRestrictionThatRemovesValueFromUI()) {
401                                try {
402                    if(CoreApiServiceLocator.getEncryptionService().isEnabled()) {
403                                            keyValue = getEncryptionService().encrypt(keyValue);
404                    }
405                                }
406                                catch (GeneralSecurityException e) {
407                                        LOG.error("Exception while trying to encrypted value for inquiry framework.", e);
408                                        throw new RuntimeException(e);
409                                }
410                        }
411
412                        parameters.put(keyName, keyValue);
413                        fieldList.put(keyName, keyValue.toString());
414                }
415
416                return getHyperLink(inquiryBusinessObjectClass, fieldList,
417                                UrlFactory.parameterizeUrl(KRADConstants.INQUIRY_ACTION, parameters));
418        }
419
420        @Deprecated
421        protected AnchorHtmlData getHyperLink(Class inquiryClass, Map<String, String> fieldList, String inquiryUrl) {
422                AnchorHtmlData a = new AnchorHtmlData(inquiryUrl, KRADConstants.EMPTY_STRING);
423                a.setTitle(HtmlData.getTitleText(this.createTitleText(inquiryClass), inquiryClass, fieldList));
424                return a;
425        }
426
427        /**
428         * Gets text to prepend to the inquiry link title
429         * 
430         * @param dataObjectClass
431         *            - data object class being inquired into
432         * @return String title prepend text
433         */
434        @Deprecated
435        protected String createTitleText(Class<?> dataObjectClass) {
436                String titleText = "";
437
438                String titlePrefixProp = getKualiConfigurationService().getPropertyValueAsString(INQUIRY_TITLE_PREFIX);
439                if (StringUtils.isNotBlank(titlePrefixProp)) {
440                        titleText += titlePrefixProp + " ";
441                }
442
443                String objectLabel = getDataDictionaryService().getDataDictionary()
444                                .getBusinessObjectEntry(dataObjectClass.getName()).getObjectLabel();
445                if (StringUtils.isNotBlank(objectLabel)) {
446                        titleText += objectLabel + " ";
447                }
448
449                return titleText;
450        }
451
452        @Deprecated
453        public void addAdditionalSections(List columns, BusinessObject bo) {
454        }
455
456        /**
457         * @see Inquirable#getHtmlMenuBar()
458         */
459        @Deprecated
460        public String getHtmlMenuBar() {
461                // TODO: replace with inquiry menu bar
462                return getBusinessObjectDictionaryService().getLookupMenuBar(getBusinessObjectClass());
463        }
464
465        /**
466         * @see Inquirable#getTitle()
467         */
468        @Deprecated
469        public String getTitle() {
470                return getBusinessObjectDictionaryService().getInquiryTitle(getBusinessObjectClass());
471        }
472
473    /**
474         * @param businessObjectClass
475         *            The dataObjectClass to set.
476         */
477        @Deprecated
478        public void setBusinessObjectClass(Class businessObjectClass) {
479                this.dataObjectClass = businessObjectClass;
480        }
481
482        /**
483     * @return Returns the dataObjectClass.
484     */
485    @Deprecated
486    public Class getBusinessObjectClass() {
487        return dataObjectClass;
488    }
489    
490        /**
491         * @see Inquirable#getInactiveRecordDisplay()
492         */
493        @Deprecated
494        public Map<String, Boolean> getInactiveRecordDisplay() {
495                return inactiveRecordDisplay;
496        }
497
498        /**
499         * @see Inquirable#getShowInactiveRecords(java.lang.String)
500         */
501        @Deprecated
502        public boolean getShowInactiveRecords(String collectionName) {
503                return InactiveRecordsHidingUtils.getShowInactiveRecords(inactiveRecordDisplay, collectionName);
504        }
505
506        /**
507         * @see Inquirable#setShowInactiveRecords(java.lang.String,
508         *      boolean)
509         */
510        @Deprecated
511        public void setShowInactiveRecords(String collectionName, boolean showInactive) {
512                InactiveRecordsHidingUtils.setShowInactiveRecords(inactiveRecordDisplay, collectionName, showInactive);
513        }
514
515        protected LookupService getLookupService() {
516                if (lookupService == null) {
517                        lookupService = KRADServiceLocatorWeb.getLookupService();
518                }
519                return lookupService;
520        }
521
522        public void setLookupService(LookupService lookupService) {
523                this.lookupService = lookupService;
524        }
525
526        protected BusinessObjectDictionaryService getBusinessObjectDictionaryService() {
527                if (businessObjectDictionaryService == null) {
528                        businessObjectDictionaryService = KNSServiceLocator.getBusinessObjectDictionaryService();
529                }
530                return businessObjectDictionaryService;
531        }
532
533        public void setBusinessObjectDictionaryService(BusinessObjectDictionaryService businessObjectDictionaryService) {
534                this.businessObjectDictionaryService = businessObjectDictionaryService;
535        }
536
537        protected EncryptionService getEncryptionService() {
538                if (encryptionService == null) {
539                        encryptionService = CoreApiServiceLocator.getEncryptionService();
540                }
541                return this.encryptionService;
542        }
543
544        public void setEncryptionService(EncryptionService encryptionService) {
545                this.encryptionService = encryptionService;
546        }
547
548        protected ConfigurationService getKualiConfigurationService() {
549                return getConfigurationService();
550        }
551
552        protected BusinessObjectMetaDataService getBusinessObjectMetaDataService() {
553                if (businessObjectMetaDataService == null) {
554                        businessObjectMetaDataService = KNSServiceLocator.getBusinessObjectMetaDataService();
555                }
556                return this.businessObjectMetaDataService;
557        }
558
559        public void setBusinessObjectMetaDataService(BusinessObjectMetaDataService businessObjectMetaDataService) {
560                this.businessObjectMetaDataService = businessObjectMetaDataService;
561        }
562
563        protected BusinessObjectAuthorizationService getBusinessObjectAuthorizationService() {
564                if (this.businessObjectAuthorizationService == null) {
565                        this.businessObjectAuthorizationService = KNSServiceLocator.getBusinessObjectAuthorizationService();
566                }
567                return this.businessObjectAuthorizationService;
568        }
569
570        public void setBusinessObjectAuthorizationService(
571                        BusinessObjectAuthorizationService businessObjectAuthorizationService) {
572                this.businessObjectAuthorizationService = businessObjectAuthorizationService;
573        }
574
575        @Deprecated
576        protected AnchorHtmlData getInquiryUrlForPrimaryKeys(Class clazz, Object businessObject, List<String> primaryKeys,
577                        String displayText) {
578                if (businessObject == null)
579                        return new AnchorHtmlData(KRADConstants.EMPTY_STRING, KRADConstants.EMPTY_STRING);
580
581                Properties parameters = new Properties();
582                parameters.put(KRADConstants.DISPATCH_REQUEST_PARAMETER, KRADConstants.START_METHOD);
583                parameters.put(KRADConstants.BUSINESS_OBJECT_CLASS_ATTRIBUTE, clazz.getName());
584
585                String titleAttributeValue;
586                Map<String, String> fieldList = new HashMap<String, String>();
587                for (String primaryKey : primaryKeys) {
588                        titleAttributeValue = (String) ObjectUtils.getPropertyValue(businessObject, primaryKey);
589                        parameters.put(primaryKey, titleAttributeValue);
590                        fieldList.put(primaryKey, titleAttributeValue);
591                }
592                if (StringUtils.isEmpty(displayText))
593                        return getHyperLink(clazz, fieldList, UrlFactory.parameterizeUrl(KRADConstants.INQUIRY_ACTION, parameters));
594                else
595                        return getHyperLink(clazz, fieldList, UrlFactory.parameterizeUrl(KRADConstants.INQUIRY_ACTION, parameters),
596                                        displayText);
597        }
598
599        @Deprecated
600        protected AnchorHtmlData getHyperLink(Class inquiryClass, Map<String, String> fieldList, String inquiryUrl,
601                        String displayText) {
602                AnchorHtmlData a = new AnchorHtmlData(inquiryUrl, KRADConstants.EMPTY_STRING, displayText);
603                a.setTitle(AnchorHtmlData.getTitleText(getKualiConfigurationService().getPropertyValueAsString(
604                INQUIRY_TITLE_PREFIX)
605                                + " "
606                                + getDataDictionaryService().getDataDictionary().getBusinessObjectEntry(inquiryClass.getName())
607                                                .getObjectLabel() + " ", inquiryClass, fieldList));
608                return a;
609        }
610
611}