View Javadoc

1   /**
2    * Copyright 2005-2012 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.core.api.resourceloader;
17  
18  import org.apache.commons.lang.StringUtils;
19  import org.kuali.rice.core.api.config.CoreConfigHelper;
20  import org.kuali.rice.core.api.exception.RiceRemoteServiceConnectionException;
21  import org.kuali.rice.core.api.exception.RiceRuntimeException;
22  import org.kuali.rice.core.api.reflect.ObjectDefinition;
23  import org.kuali.rice.core.api.util.ClassLoaderUtils;
24  
25  import javax.xml.namespace.QName;
26  import java.util.HashMap;
27  import java.util.Map;
28  
29  /**
30   * Wrapper on all the Resource loaders.  This is what programmers typically use to get in the resource loading
31   * framework.
32   *
33   * @author Kuali Rice Team (rice.collab@kuali.org)
34   */
35  public class GlobalResourceLoader {
36  
37  	private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(GlobalResourceLoader.class);
38  
39  	private static Map<ClassLoader, ResourceLoader> rootResourceLoaders = new HashMap<ClassLoader, ResourceLoader>();
40  
41  	private static boolean initializing;
42  
43  	public static synchronized ResourceLoader getResourceLoader() {
44  		ClassLoader classLoader = ClassLoaderUtils.getDefaultClassLoader();
45  		return getResourceLoaderCheckParent(classLoader);
46  	}
47  
48  	private static synchronized ResourceLoader getResourceLoaderCheckParent(ClassLoader classLoader) {
49          ResourceLoader resourceLoader = getResourceLoader(classLoader);
50  
51          if (resourceLoader != null && classLoader.getParent() != null) {
52              ResourceLoader parentResourceLoader = getResourceLoaderCheckParent(classLoader.getParent());
53  
54              if (parentResourceLoader != null) {
55                  resourceLoader = new ParentChildResourceLoader(parentResourceLoader, resourceLoader);
56  		    }
57  	    }
58  
59  	    if (resourceLoader == null && classLoader.getParent() != null) {
60  		    resourceLoader = getResourceLoaderCheckParent(classLoader.getParent());
61  	    }
62  	    return resourceLoader;
63  	}
64  
65  	public static synchronized ResourceLoader getResourceLoader(ClassLoader classloader) {
66  		return rootResourceLoaders.get(classloader);
67  	}
68  
69  	public static synchronized void start() throws Exception {
70  		try {
71  			initializing = true;
72  			ResourceLoader internalResourceLoader = getResourceLoader();
73  			if (internalResourceLoader == null) {
74  				throw new RiceRuntimeException("Cannot start GlobalResourceLoader because no resource loaders have been added for the current ContextClassLoader :" + Thread.currentThread().getContextClassLoader());
75  			}
76  			internalResourceLoader.start();
77  		} finally {
78  			initializing = false;
79  		}
80  	}
81  
82  	public static synchronized void addResourceLoader(ResourceLoader resourceLoader) {
83  		initialize();
84  		if (resourceLoader == null) {
85  			throw new ResourceLoaderException("Attempted to add a null resource loader to the Global resource loader.");
86  		}
87  		LOG.info("Adding ResourceLoader " + resourceLoader.getName() + " to GlobalResourceLoader");
88  		getResourceLoader().addResourceLoader(resourceLoader);
89  	}
90  
91  	public static synchronized void addResourceLoaderFirst(ResourceLoader resourceLoader) {
92  		initialize();
93  		if (resourceLoader == null) {
94  			throw new ResourceLoaderException("Attempted to add a null resource loader to the Global resource loader.");
95  		}
96  		LOG.info("Adding ResourceLoader " + resourceLoader.getName() + " to GlobalResourceLoader");
97  		getResourceLoader().addResourceLoaderFirst(resourceLoader);
98  	}
99  
100 	protected static synchronized void initialize() {
101 		if (getResourceLoader(ClassLoaderUtils.getDefaultClassLoader()) == null) {
102 			LOG.info("Creating CompositeResourceLoader in GlobalResourceLoader");
103 			rootResourceLoaders.put(ClassLoaderUtils.getDefaultClassLoader(), new ResourceLoaderContainer(new QName(CoreConfigHelper.getApplicationId(), ResourceLoader.ROOT_RESOURCE_LOADER_NAME)));
104 		}
105 	}
106 
107 	public static synchronized ResourceLoader getResourceLoader(QName name) {
108 		return getResourceLoader().getResourceLoader(name);
109 	}
110 
111 	/**
112 	 * Stop the resource loader for the current context classloader.  Don't stop or clear them all
113 	 * because the stop was issued from the context of a single classloader.
114 	 *
115 	 * @throws Exception
116 	 */
117 	public static synchronized void stop() throws Exception {
118 		LOG.info("Stopping the GlobalResourceLoader...");
119 		if (getResourceLoader(ClassLoaderUtils.getDefaultClassLoader()) != null) {
120 			LOG.info("Destroying GlobalResourceLoader");
121 			getResourceLoader(ClassLoaderUtils.getDefaultClassLoader()).stop();
122 			rootResourceLoaders.remove(ClassLoaderUtils.getDefaultClassLoader());
123 		}
124 		LOG.info("...GlobalResourceLoader successfully stopped.");
125 	}
126 
127 	public static <T extends Object> T getService(QName serviceName) {
128 		if (serviceName == null) {
129 			throw new IllegalArgumentException("The service name must be non-null.");
130 		}
131 		LOG.debug("GlobalResourceLoader fetching service " + serviceName);
132 		try {
133 			return getResourceLoader().<T>getService(serviceName);
134 		} catch (RiceRemoteServiceConnectionException ex) {
135 			LOG.warn(ex.getMessage());
136 			return null;
137 		}
138 	}
139 
140 	public static <T extends Object> T getService(String localServiceName) {
141 		if (StringUtils.isEmpty(localServiceName)) {
142 			throw new IllegalArgumentException("The service name must be non-null.");
143 		}
144 		return GlobalResourceLoader.<T>getService(new QName(localServiceName));
145 	}
146 
147 	public static <T extends Object> T getObject(ObjectDefinition objectDefinition) {
148 		return getResourceLoader().<T>getObject(objectDefinition);
149 	}
150 
151 	public static boolean isInitialized() {
152 		return getResourceLoader() != null;
153 	}
154 
155 	public static void logContents() {
156 		if (LOG.isInfoEnabled()) {
157 			LOG.info(getResourceLoader().getContents("", false));
158 		}
159 	}
160 	
161 	public static void logAllContents() {
162 		if (LOG.isInfoEnabled()) {
163 			LOG.info("######################### Logging All Contents ###########################");
164 			for (ResourceLoader rl : rootResourceLoaders.values()) {
165 				LOG.info("Logging contents for ResourceLoader: " + rl.getName() + "\n" + rl.getContents("  ", true));
166 			}
167 			LOG.info("###################### Done Logging All Contents #########################");
168 		}
169 	}
170 
171 	public static synchronized boolean isInitializing() {
172 		return initializing;
173 	}
174 
175 	public static synchronized void setInitializing(boolean initializing) {
176 		GlobalResourceLoader.initializing = initializing;
177 	}
178 }