001    /**
002     * Copyright 2005-2013 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     */
016    package org.kuali.rice.krad.service.impl;
017    
018    import org.apache.commons.beanutils.PropertyUtils;
019    import org.apache.commons.lang.StringUtils;
020    import org.apache.log4j.Logger;
021    import org.kuali.rice.core.api.CoreApiServiceLocator;
022    import org.kuali.rice.core.api.config.property.ConfigurationService;
023    import org.kuali.rice.coreservice.framework.CoreFrameworkServiceLocator;
024    import org.kuali.rice.coreservice.framework.parameter.ParameterService;
025    import org.kuali.rice.krad.bo.BusinessObject;
026    import org.kuali.rice.krad.bo.DataObjectRelationship;
027    import org.kuali.rice.krad.bo.ExternalizableBusinessObject;
028    import org.kuali.rice.krad.bo.ModuleConfiguration;
029    import org.kuali.rice.krad.datadictionary.BusinessObjectEntry;
030    import org.kuali.rice.krad.datadictionary.PrimitiveAttributeDefinition;
031    import org.kuali.rice.krad.datadictionary.RelationshipDefinition;
032    import org.kuali.rice.krad.service.BusinessObjectNotLookupableException;
033    import org.kuali.rice.krad.service.KRADServiceLocator;
034    import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
035    import org.kuali.rice.krad.service.KualiModuleService;
036    import org.kuali.rice.krad.service.LookupService;
037    import org.kuali.rice.krad.service.ModuleService;
038    import org.kuali.rice.krad.uif.UifParameters;
039    import org.kuali.rice.krad.util.ExternalizableBusinessObjectUtils;
040    import org.kuali.rice.krad.util.KRADConstants;
041    import org.kuali.rice.krad.util.ObjectUtils;
042    import org.kuali.rice.krad.util.UrlFactory;
043    import org.springframework.beans.BeansException;
044    import org.springframework.beans.factory.NoSuchBeanDefinitionException;
045    import org.springframework.context.ApplicationContext;
046    
047    import java.lang.reflect.Modifier;
048    import java.util.HashMap;
049    import java.util.List;
050    import java.util.Map;
051    import java.util.Properties;
052    
053    /**
054     * @author Kuali Rice Team (rice.collab@kuali.org)
055     */
056    public abstract class RemoteModuleServiceBase implements ModuleService {
057        protected static final Logger LOG = Logger.getLogger(RemoteModuleServiceBase.class);
058    
059        protected ModuleConfiguration moduleConfiguration;
060        protected KualiModuleService kualiModuleService;
061        protected ApplicationContext applicationContext;
062        protected ConfigurationService kualiConfigurationService;
063        protected LookupService lookupService;
064    
065        /**
066         * @see org.kuali.rice.krad.service.ModuleService#isResponsibleFor(java.lang.Class)
067         */
068        public boolean isResponsibleFor(Class businessObjectClass) {
069            if (getModuleConfiguration() == null) {
070                throw new IllegalStateException("Module configuration has not been initialized for the module service.");
071            }
072    
073            if (getModuleConfiguration().getPackagePrefixes() == null || businessObjectClass == null) {
074                return false;
075            }
076            for (String prefix : getModuleConfiguration().getPackagePrefixes()) {
077                if (businessObjectClass.getPackage().getName().startsWith(prefix)) {
078                    return true;
079                }
080            }
081            if (ExternalizableBusinessObject.class.isAssignableFrom(businessObjectClass)) {
082                Class externalizableBusinessObjectInterface =
083                        ExternalizableBusinessObjectUtils.determineExternalizableBusinessObjectSubInterface(
084                                businessObjectClass);
085                if (externalizableBusinessObjectInterface != null) {
086                    for (String prefix : getModuleConfiguration().getPackagePrefixes()) {
087                        if (externalizableBusinessObjectInterface.getPackage().getName().startsWith(prefix)) {
088                            return true;
089                        }
090                    }
091                }
092            }
093            return false;
094        }
095    
096        /**
097         * Utility method to check for the presence of a non blank value in the map for the given key
098         * Note: returns false if a null map is passed in.
099         *
100         * @param map the map to retrieve the value from
101         * @param key the key to use
102         * @return true if there is a non-blank value in the map for the given key.
103         */
104        protected static boolean isNonBlankValueForKey(Map<String, Object> map, String key) {
105            if (map == null) return false;
106    
107            Object result = map.get(key);
108            if (result instanceof String) {
109                return !StringUtils.isBlank((String)result);
110            }
111            return result != null;
112        }
113    
114        /**
115         * @see org.kuali.rice.krad.service.ModuleService#isResponsibleFor(java.lang.Class)
116         */
117        public boolean isResponsibleForJob(String jobName) {
118            if (getModuleConfiguration() == null) {
119                throw new IllegalStateException("Module configuration has not been initialized for the module service.");
120            }
121    
122            if (getModuleConfiguration().getJobNames() == null || StringUtils.isEmpty(jobName)) {
123                return false;
124            }
125    
126            return getModuleConfiguration().getJobNames().contains(jobName);
127        }
128    
129    
130        public List listPrimaryKeyFieldNames(Class businessObjectInterfaceClass) {
131            Class clazz = getExternalizableBusinessObjectImplementation(businessObjectInterfaceClass);
132            return KRADServiceLocator.getPersistenceStructureService().listPrimaryKeyFieldNames(clazz);
133        }
134    
135        /**
136         * @see org.kuali.rice.krad.service.ModuleService#getExternalizableBusinessObjectDictionaryEntry(java.lang.Class)
137         */
138        public BusinessObjectEntry getExternalizableBusinessObjectDictionaryEntry(Class businessObjectInterfaceClass) {
139            Class boClass = getExternalizableBusinessObjectImplementation(businessObjectInterfaceClass);
140    
141            return boClass == null ? null : KRADServiceLocatorWeb.getDataDictionaryService().getDataDictionary()
142                    .getBusinessObjectEntryForConcreteClass(boClass.getName());
143        }
144    
145        /**
146         * @see org.kuali.rice.krad.service.ModuleService#getExternalizableDataObjectInquiryUrl(java.lang.Class,
147         * java.util.Properties)
148         */
149        public String getExternalizableDataObjectInquiryUrl(Class<?> inquiryDataObjectClass, Properties parameters) {
150            String baseUrl = getBaseInquiryUrl();
151    
152            // if external business object, replace data object in request with the actual impl object class
153            if (ExternalizableBusinessObject.class.isAssignableFrom(inquiryDataObjectClass)) {
154                Class implementationClass = getExternalizableBusinessObjectImplementation(inquiryDataObjectClass.asSubclass(
155                        ExternalizableBusinessObject.class));
156                if (implementationClass == null) {
157                    throw new RuntimeException("Can't find ExternalizableBusinessObject implementation class for "
158                            + inquiryDataObjectClass.getName());
159                }
160    
161                parameters.put(UifParameters.DATA_OBJECT_CLASS_NAME, implementationClass.getName());
162            }
163    
164            return UrlFactory.parameterizeUrl(baseUrl, parameters);
165        }
166    
167        /**
168         * Returns the base URL to use for inquiry requests to objects within the module
169         *
170         * @return String base inquiry URL
171         */
172        protected String getBaseInquiryUrl() {
173            return getKualiConfigurationService().getPropertyValueAsString(KRADConstants.KRAD_INQUIRY_URL_KEY);
174        }
175    
176        /**
177         * @see org.kuali.rice.krad.service.ModuleService#getExternalizableDataObjectLookupUrl(java.lang.Class,
178         * java.util.Properties)
179         */
180        public String getExternalizableDataObjectLookupUrl(Class<?> lookupDataObjectClass, Properties parameters) {
181            String baseUrl = getBaseLookupUrl();
182    
183            // if external business object, replace data object in request with the actual impl object class
184            if (ExternalizableBusinessObject.class.isAssignableFrom(lookupDataObjectClass)) {
185                Class implementationClass = getExternalizableBusinessObjectImplementation(lookupDataObjectClass.asSubclass(
186                        ExternalizableBusinessObject.class));
187                if (implementationClass == null) {
188                    throw new RuntimeException("Can't find ExternalizableBusinessObject implementation class for "
189                            + lookupDataObjectClass.getName());
190                }
191    
192                parameters.put(UifParameters.DATA_OBJECT_CLASS_NAME, implementationClass.getName());
193            }
194    
195            return UrlFactory.parameterizeUrl(baseUrl, parameters);
196        }
197    
198        /**
199         * Returns the base lookup URL for the Rice server
200         *
201         * @return String base lookup URL
202         */
203        protected String getRiceBaseLookupUrl() {
204            return BaseLookupUrlsHolder.remoteKradBaseLookupUrl;
205        }
206    
207        // Lazy initialization holder class idiom, see Effective Java item #71
208        protected static final class BaseLookupUrlsHolder {
209    
210            public static final String localKradBaseLookupUrl;
211            public static final String remoteKradBaseLookupUrl;
212    
213            static {
214                remoteKradBaseLookupUrl = CoreApiServiceLocator.getKualiConfigurationService().getPropertyValueAsString(KRADConstants.KRAD_SERVER_LOOKUP_URL_KEY);
215                localKradBaseLookupUrl = CoreApiServiceLocator.getKualiConfigurationService().getPropertyValueAsString(KRADConstants.KRAD_LOOKUP_URL_KEY);
216            }
217        }
218    
219        /**
220         * Returns the base URL to use for lookup requests to objects within the module
221         *
222         * @return String base lookup URL
223         */
224        protected String getBaseLookupUrl() {
225            return getRiceBaseLookupUrl();
226        }
227    
228        @Deprecated
229        public String getExternalizableBusinessObjectInquiryUrl(Class inquiryBusinessObjectClass,
230                Map<String, String[]> parameters) {
231            if (!isExternalizable(inquiryBusinessObjectClass)) {
232                return KRADConstants.EMPTY_STRING;
233            }
234            String businessObjectClassAttribute;
235    
236            Class implementationClass = getExternalizableBusinessObjectImplementation(inquiryBusinessObjectClass);
237            if (implementationClass == null) {
238                LOG.error("Can't find ExternalizableBusinessObject implementation class for " + inquiryBusinessObjectClass
239                        .getName());
240                throw new RuntimeException("Can't find ExternalizableBusinessObject implementation class for interface "
241                        + inquiryBusinessObjectClass.getName());
242            }
243            businessObjectClassAttribute = implementationClass.getName();
244            return UrlFactory.parameterizeUrl(getInquiryUrl(inquiryBusinessObjectClass), getUrlParameters(
245                    businessObjectClassAttribute, parameters));
246        }
247    
248        /**
249         * This overridden method ...
250         *
251         * @see org.kuali.rice.krad.service.ModuleService#getExternalizableBusinessObjectLookupUrl(java.lang.Class,
252         *      java.util.Map)
253         */
254        @Deprecated
255        @Override
256        public String getExternalizableBusinessObjectLookupUrl(Class inquiryBusinessObjectClass,
257                Map<String, String> parameters) {
258            Properties urlParameters = new Properties();
259    
260            String riceBaseUrl = CoreApiServiceLocator.getKualiConfigurationService().getPropertyValueAsString(
261                    KRADConstants.KUALI_RICE_URL_KEY);
262            String lookupUrl = riceBaseUrl;
263            if (!lookupUrl.endsWith("/")) {
264                lookupUrl = lookupUrl + "/";
265            }
266            if (parameters.containsKey(KRADConstants.MULTIPLE_VALUE)) {
267                lookupUrl = lookupUrl + KRADConstants.MULTIPLE_VALUE_LOOKUP_ACTION;
268            } else {
269                lookupUrl = lookupUrl + KRADConstants.LOOKUP_ACTION;
270            }
271            for (String paramName : parameters.keySet()) {
272                urlParameters.put(paramName, parameters.get(paramName));
273            }
274    
275            Class clazz = getExternalizableBusinessObjectImplementation(inquiryBusinessObjectClass);
276            urlParameters.put(KRADConstants.BUSINESS_OBJECT_CLASS_ATTRIBUTE, clazz == null ? "" : clazz.getName());
277    
278            return UrlFactory.parameterizeUrl(lookupUrl, urlParameters);
279        }
280    
281        /**
282         * @see org.kuali.rice.krad.service.ModuleService#getExternalizableBusinessObjectsListForLookup(java.lang.Class,
283         *      java.util.Map, boolean)
284         */
285        public <T extends ExternalizableBusinessObject> List<T> getExternalizableBusinessObjectsListForLookup(
286                Class<T> externalizableBusinessObjectClass, Map<String, Object> fieldValues, boolean unbounded) {
287            Class<? extends ExternalizableBusinessObject> implementationClass =
288                    getExternalizableBusinessObjectImplementation(externalizableBusinessObjectClass);
289            if (isExternalizableBusinessObjectLookupable(implementationClass)) {
290                Map<String, String> searchCriteria = new HashMap<String, String>();
291                for (Map.Entry<String, Object> fieldValue : fieldValues.entrySet()) {
292                    if (fieldValue.getValue() != null) {
293                        searchCriteria.put(fieldValue.getKey(), fieldValue.getValue().toString());
294                    } else {
295                        searchCriteria.put(fieldValue.getKey(), null);
296                    }
297                }
298                return (List<T>) getLookupService().findCollectionBySearchHelper(implementationClass, searchCriteria,
299                        unbounded);
300            } else {
301                throw new BusinessObjectNotLookupableException(
302                        "External business object is not a Lookupable:  " + implementationClass);
303            }
304        }
305    
306        /**
307         * This method assumes that the property type for externalizable relationship in the business object is an interface
308         * and gets the concrete implementation for it
309         *
310         * @see org.kuali.rice.krad.service.ModuleService#retrieveExternalizableBusinessObjectIfNecessary(org.kuali.rice.krad.bo.BusinessObject,
311         *      org.kuali.rice.krad.bo.BusinessObject, java.lang.String)
312         */
313        public <T extends ExternalizableBusinessObject> T retrieveExternalizableBusinessObjectIfNecessary(
314                BusinessObject businessObject, T currentInstanceExternalizableBO, String externalizableRelationshipName) {
315    
316            if (businessObject == null) {
317                return null;
318            }
319            Class clazz;
320            try {
321                clazz = getExternalizableBusinessObjectImplementation(PropertyUtils.getPropertyType(businessObject,
322                        externalizableRelationshipName));
323            } catch (Exception iex) {
324                LOG.warn("Exception:"
325                        + iex
326                        + " thrown while trying to get property type for property:"
327                        + externalizableRelationshipName
328                        + " from business object:"
329                        + businessObject);
330                return null;
331            }
332    
333            //Get the business object entry for this business object from data dictionary
334            //using the class name (without the package) as key
335            BusinessObjectEntry entry =
336                    KRADServiceLocatorWeb.getDataDictionaryService().getDataDictionary().getBusinessObjectEntries().get(
337                            businessObject.getClass().getSimpleName());
338            RelationshipDefinition relationshipDefinition = entry.getRelationshipDefinition(externalizableRelationshipName);
339            List<PrimitiveAttributeDefinition> primitiveAttributeDefinitions =
340                    relationshipDefinition.getPrimitiveAttributes();
341    
342            Map<String, Object> fieldValuesInEBO = new HashMap<String, Object>();
343            Object sourcePropertyValue;
344            Object targetPropertyValue = null;
345            boolean sourceTargetPropertyValuesSame = true;
346            for (PrimitiveAttributeDefinition primitiveAttributeDefinition : primitiveAttributeDefinitions) {
347                sourcePropertyValue = ObjectUtils.getPropertyValue(businessObject,
348                        primitiveAttributeDefinition.getSourceName());
349                if (currentInstanceExternalizableBO != null) {
350                    targetPropertyValue = ObjectUtils.getPropertyValue(currentInstanceExternalizableBO,
351                            primitiveAttributeDefinition.getTargetName());
352                }
353                if (sourcePropertyValue == null) {
354                    return null;
355                } else if (targetPropertyValue == null || (targetPropertyValue != null && !targetPropertyValue.equals(
356                        sourcePropertyValue))) {
357                    sourceTargetPropertyValuesSame = false;
358                }
359                fieldValuesInEBO.put(primitiveAttributeDefinition.getTargetName(), sourcePropertyValue);
360            }
361    
362            if (!sourceTargetPropertyValuesSame) {
363                return (T) getExternalizableBusinessObject(clazz, fieldValuesInEBO);
364            }
365            return currentInstanceExternalizableBO;
366        }
367    
368        /**
369         * This method assumes that the externalizableClazz is an interface
370         * and gets the concrete implementation for it
371         *
372         * @see org.kuali.rice.krad.service.ModuleService#retrieveExternalizableBusinessObjectIfNecessary(org.kuali.rice.krad.bo.BusinessObject,
373         *      org.kuali.rice.krad.bo.BusinessObject, java.lang.String)
374         */
375        @Override
376        public List<? extends ExternalizableBusinessObject> retrieveExternalizableBusinessObjectsList(
377                BusinessObject businessObject, String externalizableRelationshipName, Class externalizableClazz) {
378    
379            if (businessObject == null) {
380                return null;
381            }
382            //Get the business object entry for this business object from data dictionary
383            //using the class name (without the package) as key
384            String className = businessObject.getClass().getName();
385            String key = className.substring(className.lastIndexOf(".") + 1);
386            BusinessObjectEntry entry =
387                    KRADServiceLocatorWeb.getDataDictionaryService().getDataDictionary().getBusinessObjectEntries().get(
388                            key);
389            RelationshipDefinition relationshipDefinition = entry.getRelationshipDefinition(externalizableRelationshipName);
390            List<PrimitiveAttributeDefinition> primitiveAttributeDefinitions =
391                    relationshipDefinition.getPrimitiveAttributes();
392            Map<String, Object> fieldValuesInEBO = new HashMap<String, Object>();
393            Object sourcePropertyValue;
394            for (PrimitiveAttributeDefinition primitiveAttributeDefinition : primitiveAttributeDefinitions) {
395                sourcePropertyValue = ObjectUtils.getPropertyValue(businessObject,
396                        primitiveAttributeDefinition.getSourceName());
397                if (sourcePropertyValue == null) {
398                    return null;
399                }
400                fieldValuesInEBO.put(primitiveAttributeDefinition.getTargetName(), sourcePropertyValue);
401            }
402            return getExternalizableBusinessObjectsList(getExternalizableBusinessObjectImplementation(externalizableClazz),
403                    fieldValuesInEBO);
404        }
405    
406        /**
407         * @see org.kuali.rice.krad.service.ModuleService#getExternalizableBusinessObjectImplementation(java.lang.Class)
408         */
409        @Override
410        public <E extends ExternalizableBusinessObject> Class<E> getExternalizableBusinessObjectImplementation(
411                Class<E> externalizableBusinessObjectInterface) {
412            if (getModuleConfiguration() == null) {
413                throw new IllegalStateException("Module configuration has not been initialized for the module service.");
414            }
415            Map<Class, Class> ebos = getModuleConfiguration().getExternalizableBusinessObjectImplementations();
416            if (ebos == null) {
417                return null;
418            }
419            if (ebos.containsValue(externalizableBusinessObjectInterface)) {
420                return externalizableBusinessObjectInterface;
421            } else {
422                Class<E> implementationClass = ebos.get(externalizableBusinessObjectInterface);
423    
424                int implClassModifiers = implementationClass.getModifiers();
425                if (Modifier.isInterface(implClassModifiers) || Modifier.isAbstract(implClassModifiers)) {
426                    throw new RuntimeException("Implementation class must be non-abstract class: ebo interface: "
427                            + externalizableBusinessObjectInterface.getName()
428                            + " impl class: "
429                            + implementationClass.getName()
430                            + " module: "
431                            + getModuleConfiguration().getNamespaceCode());
432                }
433                return implementationClass;
434            }
435    
436        }
437    
438        @Deprecated
439        protected Properties getUrlParameters(String businessObjectClassAttribute, Map<String, String[]> parameters) {
440            Properties urlParameters = new Properties();
441            for (String paramName : parameters.keySet()) {
442                String[] parameterValues = parameters.get(paramName);
443                if (parameterValues.length > 0) {
444                    urlParameters.put(paramName, parameterValues[0]);
445                }
446            }
447            urlParameters.put(KRADConstants.BUSINESS_OBJECT_CLASS_ATTRIBUTE, businessObjectClassAttribute);
448            urlParameters.put(KRADConstants.DISPATCH_REQUEST_PARAMETER, KRADConstants.CONTINUE_WITH_INQUIRY_METHOD_TO_CALL);
449            return urlParameters;
450        }
451    
452        @Deprecated
453        protected String getInquiryUrl(Class inquiryBusinessObjectClass) {
454            String riceBaseUrl = CoreApiServiceLocator.getKualiConfigurationService().getPropertyValueAsString(
455                    KRADConstants.KUALI_RICE_URL_KEY);
456            String inquiryUrl = riceBaseUrl;
457            if (!inquiryUrl.endsWith("/")) {
458                inquiryUrl = inquiryUrl + "/";
459            }
460            return inquiryUrl + KRADConstants.INQUIRY_ACTION;
461        }
462    
463        /**
464         * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
465         */
466        public void afterPropertiesSet() throws Exception {
467            KualiModuleService kualiModuleService = null;
468            try {
469                kualiModuleService = KRADServiceLocatorWeb.getKualiModuleService();
470                if (kualiModuleService == null) {
471                    kualiModuleService = ((KualiModuleService) applicationContext.getBean(
472                            KRADServiceLocatorWeb.KUALI_MODULE_SERVICE));
473                }
474            } catch (NoSuchBeanDefinitionException ex) {
475                kualiModuleService = ((KualiModuleService) applicationContext.getBean(
476                        KRADServiceLocatorWeb.KUALI_MODULE_SERVICE));
477            }
478            kualiModuleService.getInstalledModuleServices().add(this);
479        }
480    
481        /**
482         * @return the moduleConfiguration
483         */
484        public ModuleConfiguration getModuleConfiguration() {
485            return this.moduleConfiguration;
486        }
487    
488        /**
489         * @param moduleConfiguration the moduleConfiguration to set
490         */
491        public void setModuleConfiguration(ModuleConfiguration moduleConfiguration) {
492            this.moduleConfiguration = moduleConfiguration;
493        }
494    
495        /**
496         * @see org.kuali.rice.krad.service.ModuleService#isExternalizable(java.lang.Class)
497         */
498        @Override
499        public boolean isExternalizable(Class boClazz) {
500            if (boClazz == null) {
501                return false;
502            }
503            return ExternalizableBusinessObject.class.isAssignableFrom(boClazz);
504        }
505    
506        public <T extends ExternalizableBusinessObject> T createNewObjectFromExternalizableClass(Class<T> boClass) {
507            try {
508                return (T) getExternalizableBusinessObjectImplementation(boClass).newInstance();
509            } catch (Exception e) {
510                throw new RuntimeException("Unable to create externalizable business object class", e);
511            }
512        }
513    
514        public DataObjectRelationship getBusinessObjectRelationship(Class boClass, String attributeName,
515                String attributePrefix) {
516            return null;
517        }
518    
519    
520        /**
521         * @return the kualiModuleService
522         */
523        public KualiModuleService getKualiModuleService() {
524            return this.kualiModuleService;
525        }
526    
527        /**
528         * @param kualiModuleService the kualiModuleService to set
529         */
530        public void setKualiModuleService(KualiModuleService kualiModuleService) {
531            this.kualiModuleService = kualiModuleService;
532        }
533    
534        protected ConfigurationService getKualiConfigurationService() {
535            if (this.kualiConfigurationService == null) {
536                this.kualiConfigurationService = CoreApiServiceLocator.getKualiConfigurationService();
537            }
538    
539            return this.kualiConfigurationService;
540        }
541    
542        public void setKualiConfigurationService(ConfigurationService kualiConfigurationService) {
543            this.kualiConfigurationService = kualiConfigurationService;
544        }
545    
546        /**
547         * @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext)
548         */
549        @Override
550        public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
551            this.applicationContext = applicationContext;
552        }
553    
554        /**
555         * This overridden method ...
556         *
557         * @see org.kuali.rice.krad.service.ModuleService#listAlternatePrimaryKeyFieldNames(java.lang.Class)
558         */
559        @Override
560        public List<List<String>> listAlternatePrimaryKeyFieldNames(Class businessObjectInterfaceClass) {
561            return null;
562        }
563    
564        /**
565         * This method determines whether or not this module is currently locked
566         *
567         * @see org.kuali.rice.krad.service.ModuleService#isLocked()
568         */
569        @Override
570        public boolean isLocked() {
571            ModuleConfiguration configuration = this.getModuleConfiguration();
572            if (configuration != null) {
573                String namespaceCode = configuration.getNamespaceCode();
574                String componentCode = KRADConstants.DetailTypes.ALL_DETAIL_TYPE;
575                String parameterName = KRADConstants.SystemGroupParameterNames.OLTP_LOCKOUT_ACTIVE_IND;
576                ParameterService parameterService = CoreFrameworkServiceLocator.getParameterService();
577                String shouldLockout = parameterService.getParameterValueAsString(namespaceCode, componentCode,
578                        parameterName);
579                if (StringUtils.isNotBlank(shouldLockout)) {
580                    return parameterService.getParameterValueAsBoolean(namespaceCode, componentCode, parameterName);
581                }
582            }
583            return false;
584        }
585    
586        /**
587         * Gets the lookupService attribute.
588         *
589         * @return Returns the lookupService.
590         */
591        protected LookupService getLookupService() {
592            return lookupService != null ? lookupService : KRADServiceLocatorWeb.getLookupService();
593        }
594    
595        @Override
596        public boolean goToCentralRiceForInquiry() {
597            return false;
598        }
599    }