View Javadoc

1   /**
2    * Copyright 2005-2014 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.krad.bo;
17  
18  import org.kuali.rice.krad.service.DataDictionaryService;
19  import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
20  import org.kuali.rice.krad.service.PersistenceService;
21  import org.springframework.beans.factory.InitializingBean;
22  import org.springframework.context.ApplicationContext;
23  import org.springframework.context.ApplicationContextAware;
24  
25  import javax.persistence.EntityManager;
26  import java.lang.reflect.Modifier;
27  import java.util.ArrayList;
28  import java.util.Collections;
29  import java.util.List;
30  import java.util.Map;
31  
32  /**
33   * This class contains various configuration properties for a Rice module.
34   *
35   * <p>
36   * The Rice framework is  composed of several separate modules, each of which is
37   * responsible for providing a set of functionality. These include:
38   * <ul>
39   *      <li>KEW - the Rice enterprise workflow module
40   *      <li>KIM - the Rice identity management module
41   *      <li>KSB - the Rice service bus
42   *      <li>KRAD - the Rice rapid application development module
43   *      <li>KRMS - the Rice business rules management syste
44   *      <li>eDocLite - a Rice framework for creating simple documents quickly
45   *      <li>...as well as several others. Refer to the Rice documentation for a complete list.
46   * </ul>
47   * <br>
48   * Client Applications will also have their own module configurations. A client application could create a single
49   * module or multiple modules, depending on how it is organized.
50   * <br>
51   * This ModuleConfiguration object is created during Spring initialization. The properties of this ModuleConfiguration
52   * are specified in the module's SpringBean definition XML configuration file.
53   *</p>
54   *
55   * @author Kuali Rice Team (rice.collab@kuali.org)
56   *
57   */
58  public class ModuleConfiguration implements InitializingBean, ApplicationContextAware {
59  
60      /**
61       * the module's namespace.
62       */
63  	protected String namespaceCode;
64  	protected ApplicationContext applicationContext;
65  
66      /**
67       * the package name prefixes for classes used in this module
68       */
69  	protected List<String> packagePrefixes;
70  
71      /**
72       * a list of entity description files to be loaded during initialization of the persistence service.
73       * <p>
74       * Currently only used by OJB repository service implementation.
75       * </p>
76       */
77  	protected List<String> databaseRepositoryFilePaths;
78  
79      /**
80       * the list of data dictionary packages to be loaded for this module by the data dictionary service during system
81       * startup.
82       */
83  	protected List<String> dataDictionaryPackages;
84  
85  	protected List<String> scriptConfigurationFilePaths;
86  
87  	protected List<String> jobNames;
88  
89  	protected List<String> triggerNames;
90  
91      protected List<String> resourceBundleNames;
92  
93  	//optional
94  	protected String dataSourceName;
95  
96  	//optional
97  	protected EntityManager entityManager;
98  
99  	protected Map<Class, Class> externalizableBusinessObjectImplementations;
100 
101 	protected boolean initializeDataDictionary;
102 
103 	protected PersistenceService persistenceService;
104 
105     /**
106      * the implementation of the data dictionary service to use for this module.
107      */
108 	protected DataDictionaryService dataDictionaryService;
109 
110     /**
111      *  Constructor for a ModuleConfiguration.
112      *
113      *  <p>
114      *  Initializes the arrays of this ModuleConfiguration to empty ArrayLists.
115      *  </p>
116      */
117 	public ModuleConfiguration() {
118 		databaseRepositoryFilePaths = new ArrayList<String>();
119 		dataDictionaryPackages = new ArrayList<String>();
120 		scriptConfigurationFilePaths = new ArrayList<String>();
121 		jobNames = new ArrayList<String>();
122 		triggerNames = new ArrayList<String>();
123         resourceBundleNames = new ArrayList<String>();
124 	}
125 
126     /**
127      * Performs additional custom initialization after the bean is created and it's properties are set by the
128      * Spring framework.
129      *
130      * <p>
131      * Loads the data dictionary packages configured for this module.
132      * Also loads any OJB database repository files configured.
133      * </p>
134      *
135      * @throws Exception
136      */
137 	@Override
138     public void afterPropertiesSet() throws Exception {
139         if (isInitializeDataDictionary() && getDataDictionaryPackages() != null &&
140                 !getDataDictionaryPackages().isEmpty()) {
141             if (getDataDictionaryService() == null) {
142                 setDataDictionaryService(KRADServiceLocatorWeb.getDataDictionaryService());
143             }
144 
145             if (getDataDictionaryService() == null) {
146                 setDataDictionaryService((DataDictionaryService) applicationContext.getBean(
147                         KRADServiceLocatorWeb.DATA_DICTIONARY_SERVICE));
148             }
149 
150             if (dataDictionaryService != null) {
151                 dataDictionaryService.addDataDictionaryLocations(getNamespaceCode(), getDataDictionaryPackages());
152             }
153         }
154 
155         if (getDatabaseRepositoryFilePaths() != null) {
156             for (String repositoryLocation : getDatabaseRepositoryFilePaths()) {
157                 // Need the OJB persistence service because it is the only one ever using the database repository files
158                 if (getPersistenceService() == null) {
159                     setPersistenceService(KRADServiceLocatorWeb.getPersistenceServiceOjb());
160                 }
161                 if (persistenceService == null) {
162                     setPersistenceService((PersistenceService) applicationContext.getBean(
163                             KRADServiceLocatorWeb.PERSISTENCE_SERVICE_OJB));
164                 }
165                 getPersistenceService().loadRepositoryDescriptor(repositoryLocation);
166             }
167         }
168     }
169 
170 	/**
171      * Retrieves the database repository file paths to be used by the persistence service configured for this module.
172      *
173      * <p>
174      * Used by the OBJ persistence service to load entity descriptors.
175      * The file paths are returned as a List of Strings. If no file paths are configured,
176      * an empty list is returned.  This method should never return null.
177      * </p>
178      *
179 	 * @return a List containing the databaseRepositoryFilePaths
180 	 */
181 	public List<String> getDatabaseRepositoryFilePaths() {
182 		return this.databaseRepositoryFilePaths;
183 	}
184 
185 	/**
186      * Initializes the list of database repository files to load during persistence service initialization.
187      *
188      * <p>
189      * The repository file names are listed in the module's Spring bean configuration file.
190      * This property is set during Spring initialization.
191      * </p>
192      *
193 	 * @param databaseRepositoryFilePaths the List of entity descriptor files to load.
194 	 */
195 	public void setDatabaseRepositoryFilePaths(
196 			List<String> databaseRepositoryFilePaths) {
197 		this.trimList(databaseRepositoryFilePaths);
198 		this.databaseRepositoryFilePaths = databaseRepositoryFilePaths;
199 	}
200 
201 	/**
202      * Returns a list of data dictionary packages configured for this ModuleConfiguration.
203      *
204      * <p>
205      * If no data dictionary packages are defined, will return an empty list.
206      * Should never return null.
207      * </p>
208      *
209 	 * @return a List of Strings containing the names of the dataDictionaryPackages
210 	 */
211 	public List<String> getDataDictionaryPackages() {
212 		return this.dataDictionaryPackages;
213 	}
214 
215 	/**
216      * Initializes the list of data dictionary packages associated with this ModuleConfiguration.
217      *
218      * <p>
219      * The data dictionary packages are listed in the module's Spring bean configuration file.
220      * This property is set during Spring initialization.
221      * </p>
222      *
223 	 * @param dataDictionaryPackages a List of Strings containing the dataDictionaryPackages.
224 	 */
225 	public void setDataDictionaryPackages(List<String> dataDictionaryPackages) {
226 		this.trimList(dataDictionaryPackages);
227 		this.dataDictionaryPackages = dataDictionaryPackages;
228 	}
229 
230 	/**
231 	 * @return the externalizableBusinessObjectImplementations
232 	 */
233 	public Map<Class, Class> getExternalizableBusinessObjectImplementations() {
234 		if (this.externalizableBusinessObjectImplementations == null)
235 			return null;
236 		return Collections.unmodifiableMap(this.externalizableBusinessObjectImplementations);
237 	}
238 
239 	/**
240 	 * @param externalizableBusinessObjectImplementations the externalizableBusinessObjectImplementations to set
241 	 */
242 	public void setExternalizableBusinessObjectImplementations(
243 			Map<Class, Class> externalizableBusinessObjectImplementations) {
244 		if (externalizableBusinessObjectImplementations != null) {
245 			for (Class implClass : externalizableBusinessObjectImplementations.values()) {
246 				int implModifiers = implClass.getModifiers();
247 				if (Modifier.isInterface(implModifiers) || Modifier.isAbstract(implModifiers)) {
248 					throw new RuntimeException("Externalizable business object implementation class " +
249 							implClass.getName() + " must be a non-interface, non-abstract class");
250 				}
251 			}
252 		}
253 		this.externalizableBusinessObjectImplementations = externalizableBusinessObjectImplementations;
254 	}
255 
256 	public List<String> getPackagePrefixes(){
257 		return this.packagePrefixes;
258 	}
259 
260 	public void setPackagePrefixes(List<String> packagePrefixes){
261 		this.trimList(packagePrefixes);
262 		this.packagePrefixes = packagePrefixes;
263 	}
264 
265 	public void setInitializeDataDictionary(boolean initializeDataDictionary){
266 		this.initializeDataDictionary = initializeDataDictionary;
267 	}
268 
269 	public List<String> getScriptConfigurationFilePaths(){
270 		return this.scriptConfigurationFilePaths;
271 	}
272 
273 	/**
274 	 * @return the jobNames
275 	 */
276 	public List<String> getJobNames() {
277 		return this.jobNames;
278 	}
279 
280 	/**
281 	 * @param jobNames the jobNames to set
282 	 */
283 	public void setJobNames(List<String> jobNames) {
284 		this.jobNames = jobNames;
285 	}
286 
287 	/**
288 	 * @return the triggerNames
289 	 */
290 	public List<String> getTriggerNames() {
291 		return this.triggerNames;
292 	}
293 
294 	/**
295 	 * @param triggerNames the triggerNames to set
296 	 */
297 	public void setTriggerNames(List<String> triggerNames) {
298 		this.triggerNames = triggerNames;
299 	}
300 
301     /**
302      * List of resource bundle names that will provides messages for this module
303      *
304      * <p>
305      * Each bundle will point to a resource property file that contain key/value message pairs. The properties
306      * file should be on the classpath and the name is given by specifying the fully qualified class name
307      * (dot notation).
308      * </p>
309      *
310      * @return List<String> resource bundle names
311      * @see java.util.ResourceBundle
312      */
313     public List<String> getResourceBundleNames() {
314         return resourceBundleNames;
315     }
316 
317     /**
318      * Setter for the list of resource bundle names that provides messages for the module
319      *
320      * @param resourceBundleNames
321      */
322     public void setResourceBundleNames(List<String> resourceBundleNames) {
323         this.resourceBundleNames = resourceBundleNames;
324     }
325 
326     /**
327 	 * @return the initializeDataDictionary
328 	 */
329 	public boolean isInitializeDataDictionary() {
330 		return this.initializeDataDictionary;
331 	}
332 
333 	/**
334 	 * @param scriptConfigurationFilePaths the scriptConfigurationFilePaths to set
335 	 */
336 	public void setScriptConfigurationFilePaths(
337 			List<String> scriptConfigurationFilePaths) {
338 		this.scriptConfigurationFilePaths = scriptConfigurationFilePaths;
339 	}
340 
341 	/**
342 	 * @return the namespaceCode
343 	 */
344 	public String getNamespaceCode() {
345 		return this.namespaceCode;
346 	}
347 
348 	/**
349 	 * @param namespaceCode the namespaceCode to set
350 	 */
351 	public void setNamespaceCode(String namespaceCode) {
352 		this.namespaceCode = namespaceCode;
353 	}
354 
355 	@Override
356 	public void setApplicationContext(ApplicationContext applicationContext) {
357 		this.applicationContext = applicationContext;
358 	}
359 
360 	/**
361 	 * @return the dataDictionaryService
362 	 */
363 	public DataDictionaryService getDataDictionaryService() {
364 		return this.dataDictionaryService;
365 	}
366 
367 	/**
368 	 * @param dataDictionaryService the dataDictionaryService to set
369 	 */
370 	public void setDataDictionaryService(DataDictionaryService dataDictionaryService) {
371 		this.dataDictionaryService = dataDictionaryService;
372 	}
373 
374 	/**
375 	 * @return the persistenceService
376 	 */
377 	public PersistenceService getPersistenceService() {
378 		return this.persistenceService;
379 	}
380 
381 	/**
382 	 * @param persistenceService the persistenceService to set
383 	 */
384 	public void setPersistenceService(PersistenceService persistenceService) {
385 		this.persistenceService = persistenceService;
386 	}
387 
388     public String getDataSourceName() {
389         return this.dataSourceName;
390     }
391 
392     public void setDataSourceName(String dataSourceName) {
393         this.dataSourceName = dataSourceName;
394     }
395 
396     public EntityManager getEntityManager() {
397         return this.entityManager;
398     }
399 
400     public void setEntityManager(EntityManager entityManager) {
401         this.entityManager = entityManager;
402     }
403 
404     /**
405 	 *
406 	 * This method passes by reference. It will alter the list passed in.
407 	 *
408 	 * @param stringList
409 	 */
410 	protected void trimList(List<String> stringList){
411 		if(stringList != null){
412 			// we need to trim whitespace from the stringList. Because trim() creates a new string
413 			// we have to explicitly put the new string back into the list
414 			for(int i=0; i<stringList.size(); i++){
415 				String elmt = stringList.get(i);
416 				elmt = elmt.trim();
417 				stringList.set(i, elmt);
418 			}
419 		}
420 	}
421 
422 }