001/**
002 * Copyright 2005-2016 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.krad.service.impl;
017
018import org.kuali.rice.coreservice.api.CoreServiceApiServiceLocator;
019import org.kuali.rice.coreservice.api.namespace.Namespace;
020import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader;
021import org.kuali.rice.coreservice.framework.parameter.ParameterConstants;
022import org.kuali.rice.krad.bo.BusinessObject;
023import org.kuali.rice.krad.bo.ExternalizableBusinessObject;
024import org.kuali.rice.krad.document.TransactionalDocument;
025import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
026import org.kuali.rice.krad.service.KualiModuleService;
027import org.kuali.rice.krad.service.ModuleService;
028import org.kuali.rice.krad.service.ModuleServiceNotFoundException;
029import org.kuali.rice.krad.util.KRADConstants;
030import org.springframework.beans.factory.InitializingBean;
031import org.springframework.beans.factory.NoSuchBeanDefinitionException;
032import org.springframework.context.ApplicationContext;
033import org.springframework.context.ApplicationContextAware;
034
035import java.util.ArrayList;
036import java.util.List;
037
038public class KualiModuleServiceImpl implements KualiModuleService, InitializingBean, ApplicationContextAware {
039
040    private List<ModuleService> installedModuleServices = new ArrayList<ModuleService>();
041    private boolean loadRiceInstalledModuleServices;
042    private ApplicationContext applicationContext;
043    
044    /**
045         * @param applicationContext the applicationContext to set
046         */
047        @Override
048        public void setApplicationContext(ApplicationContext applicationContext) {
049                this.applicationContext = applicationContext;
050        }
051
052        @Override
053        public List<ModuleService> getInstalledModuleServices() {
054        return installedModuleServices;
055    }
056
057    @Override
058        public ModuleService getModuleService(String moduleId) {
059        for (ModuleService moduleService : installedModuleServices) {
060            if ( moduleService.getModuleConfiguration().getNamespaceCode().equals( moduleId ) ) {
061                return moduleService;
062            }
063        } 
064        return null;
065    }
066
067    @Override
068        public ModuleService getModuleServiceByNamespaceCode(String namespaceCode) {
069        for (ModuleService moduleService : installedModuleServices) {
070            if ( moduleService.getModuleConfiguration().getNamespaceCode().equals( namespaceCode ) ) {
071                return moduleService;
072            }
073        } 
074        return null;
075    }
076
077    @Override
078        public boolean isModuleServiceInstalled(String namespaceCode) {
079        for (ModuleService moduleService : installedModuleServices) {
080            if ( moduleService.getModuleConfiguration().getNamespaceCode().equals( namespaceCode ) ) {
081                return true;
082            }
083        } 
084        return false;
085    }
086
087    @Override
088        public ModuleService getResponsibleModuleService(Class boClass) {
089        if(boClass==null) {
090                        return null;
091                }
092        for (ModuleService moduleService : installedModuleServices) {
093            if ( moduleService.isResponsibleFor( boClass ) ) {
094                return moduleService;
095            }
096        }
097        //Throwing exception only for externalizable business objects
098        if(ExternalizableBusinessObject.class.isAssignableFrom(boClass)){
099            String message;
100                if(!boClass.isInterface()) {
101                                message = "There is no responsible module for the externalized business object class: "+boClass;
102                        } else {
103                                message = "There is no responsible module for the externalized business object interface: "+boClass;
104                        }
105                throw new ModuleServiceNotFoundException(message);
106        } 
107        //Returning null for business objects other than externalizable to keep the framework backward compatible
108        return null;
109    }
110
111    @Override
112        public ModuleService getResponsibleModuleServiceForJob(String jobName){
113        for(ModuleService moduleService : installedModuleServices){
114            if(moduleService.isResponsibleForJob(jobName)){
115                return moduleService;
116            }
117        }
118        return null;
119    }
120    
121    @Override
122        public void setInstalledModuleServices(List<ModuleService> installedModuleServices) {
123        this.installedModuleServices = installedModuleServices;
124    }
125
126    @Override
127        public List<String> getDataDictionaryPackages() {
128        List<String> packages  = new ArrayList<String>();
129        for ( ModuleService moduleService : installedModuleServices ) {
130            if ( moduleService.getModuleConfiguration().getDataDictionaryPackages() != null ) {
131                packages.addAll( moduleService.getModuleConfiguration().getDataDictionaryPackages() );
132            }
133        }
134        return packages;
135    }
136
137    @Override
138        public String getNamespaceName(final String namespaceCode){
139        Namespace parameterNamespace = CoreServiceApiServiceLocator.getNamespaceService().getNamespace(namespaceCode);
140        return parameterNamespace==null ? "" : parameterNamespace.getName();
141    }
142    
143        /**
144         * @param loadRiceInstalledModuleServices the loadRiceInstalledModuleServices to set
145         */
146        public void setLoadRiceInstalledModuleServices(
147                        boolean loadRiceInstalledModuleServices) {
148                this.loadRiceInstalledModuleServices = loadRiceInstalledModuleServices;
149        }
150
151        /***
152         * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
153         */
154        @Override
155        public void afterPropertiesSet() throws Exception {
156                if(loadRiceInstalledModuleServices){
157                        try {
158                                installedModuleServices.addAll(
159                                                GlobalResourceLoader.<KualiModuleService>getService(KualiModuleService.class.getSimpleName().substring(0, 1).toLowerCase() + KualiModuleService.class.getSimpleName().substring(1)).getInstalledModuleServices());
160                        } catch ( NoSuchBeanDefinitionException ex ) {
161                                installedModuleServices.addAll( ((KualiModuleService)applicationContext.getBean( KRADServiceLocatorWeb.KUALI_MODULE_SERVICE )).getInstalledModuleServices() );
162                        }
163                }
164        }
165
166    @Override
167    public String getNamespaceCode(Class<?> documentClass) {
168        if (documentClass == null) {
169            throw new IllegalArgumentException("documentClass must not be null");
170        }
171
172        if (documentClass.isAnnotationPresent(ParameterConstants.NAMESPACE.class)) {
173            return (documentClass.getAnnotation(ParameterConstants.NAMESPACE.class)).namespace();
174        }
175        ModuleService moduleService = getResponsibleModuleService(documentClass);
176        if (moduleService != null) {
177            return moduleService.getModuleConfiguration().getNamespaceCode();
178        }
179        if (documentClass.getName().startsWith("org.kuali.rice.krad")) {
180            return KRADConstants.KNS_NAMESPACE;
181        }
182        if (documentClass.getName().startsWith("org.kuali.rice.edl")) {
183            return "KR-EDL";
184        }
185        if (documentClass.getName().startsWith("org.kuali.rice.kew")) {
186            return "KR-WKFLW";
187        }
188        if (documentClass.getName().startsWith("org.kuali.rice.edl")) {
189                return "KR-WKFLW";
190        }
191        if (documentClass.getName().startsWith("org.kuali.rice.kim")) {
192            return "KR-IDM";
193        }
194        if (documentClass.getName().startsWith("org.kuali.rice.core")) {
195            return "KR-CORE";
196        }
197        throw new IllegalArgumentException("Unable to determine the namespace code for documentClass " + documentClass.getName());
198    }
199
200    @Override
201    public String getComponentCode(Class<?> documentClass) {
202        if (documentClass == null) {
203            throw new IllegalArgumentException("documentClass must not be null");
204        }
205
206        if (documentClass.isAnnotationPresent(ParameterConstants.COMPONENT.class)) {
207            return documentClass.getAnnotation(ParameterConstants.COMPONENT.class).component();
208        } else if (TransactionalDocument.class.isAssignableFrom(documentClass)) {
209            return documentClass.getSimpleName().replace("Document", "");
210        } else if (BusinessObject.class.isAssignableFrom(documentClass)) {
211            return documentClass.getSimpleName();
212        }
213        throw new IllegalArgumentException("Unable to determine the component code for documentClass " + documentClass.getName());
214    }
215
216}
217