001: /*
002: * Copyright 2005-2006 The Kuali Foundation.
003: *
004: *
005: * Licensed under the Educational Community License, Version 1.0 (the "License");
006: * you may not use this file except in compliance with the License.
007: * You may obtain a copy of the License at
008: *
009: * http://www.opensource.org/licenses/ecl1.php
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.kuali.rice.resourceloader;
018:
019: import java.util.HashMap;
020: import java.util.HashSet;
021: import java.util.Map;
022: import java.util.Set;
023:
024: import javax.xml.namespace.QName;
025:
026: import org.apache.commons.lang.StringUtils;
027: import org.kuali.rice.RiceConstants;
028: import org.kuali.rice.core.Core;
029: import org.kuali.rice.definition.ObjectDefinition;
030: import org.kuali.rice.util.ClassLoaderUtils;
031:
032: import edu.emory.mathcs.backport.java.util.Collections;
033:
034: /**
035: * A BaseResourceLoader implementation which wraps services with a Proxy that
036: * switches the current context ClassLoader of the Thread.
037: *
038: * @author Kuali Rice Team (kuali-rice@googlegroups.com)
039: */
040: public class BaseWrappingResourceLoader extends BaseResourceLoader {
041:
042: private static final String[] PACKAGES_TO_FILTER = new String[] { "org.springframework" };
043: private Set<QName> servicesToCache = new HashSet<QName>();
044: private Map<QName, Object> serviceCache = Collections
045: .synchronizedMap(new HashMap<QName, Object>());
046:
047: public BaseWrappingResourceLoader(QName name,
048: ClassLoader classLoader, ServiceLocator serviceLocator) {
049: super (name, classLoader, serviceLocator);
050: }
051:
052: public BaseWrappingResourceLoader(QName name,
053: ClassLoader classLoader) {
054: super (name, classLoader);
055: }
056:
057: public BaseWrappingResourceLoader(QName name,
058: ServiceLocator serviceLocator) {
059: super (name, serviceLocator);
060: }
061:
062: public BaseWrappingResourceLoader(QName name) {
063: super (name);
064: }
065:
066: @Override
067: public void start() throws Exception {
068: String servicesToCacheFromConfig = Core
069: .getCurrentContextConfig().getProperty(
070: RiceConstants.SERVICES_TO_CACHE);
071: if (!StringUtils.isEmpty(servicesToCacheFromConfig)) {
072: String[] services = servicesToCacheFromConfig.split(",");
073: for (String serviceName : services) {
074: serviceName = serviceName.trim();
075: try {
076: servicesToCache.add(QName.valueOf(serviceName));
077: LOG.info("Adding service " + serviceName
078: + " to service cache.");
079: } catch (IllegalArgumentException e) {
080: LOG
081: .error("Failed to parse serviceName into QName from property "
082: + RiceConstants.SERVICES_TO_CACHE
083: + ". Service name given was: "
084: + serviceName);
085: }
086: }
087: }
088: super .start();
089: }
090:
091: @Override
092: public Object getService(QName serviceName) {
093: Object service = serviceCache.get(serviceName);
094: if (service != null) {
095: if (LOG.isDebugEnabled()) {
096: LOG.debug("Service with QName " + serviceName
097: + " was retrieved from the service cache.");
098: }
099: return service;
100: }
101: return super .getService(serviceName);
102: }
103:
104: protected Object postProcessService(QName serviceName,
105: Object service) {
106: if (service != null && shouldWrapService(serviceName, service)) {
107: return ContextClassLoaderProxy.wrap(service,
108: ClassLoaderUtils
109: .getInterfacesToProxy(service,
110: getClassLoader(),
111: getPackageNamesToFilter()),
112: getClassLoader());
113: }
114: return service;
115: }
116:
117: protected Object postProcessObject(ObjectDefinition definition,
118: Object object) {
119: if (object != null && shouldWrapObject(definition, object)) {
120: return ContextClassLoaderProxy.wrap(object,
121: ClassLoaderUtils
122: .getInterfacesToProxy(object,
123: getClassLoader(),
124: getPackageNamesToFilter()),
125: getClassLoader(), getClassLoader());
126: }
127: return object;
128: }
129:
130: protected void cacheService(QName serviceName, Object service) {
131: if (shouldCacheService(serviceName, service)) {
132: LOG.debug("Adding service " + serviceName
133: + " to the service cache.");
134: serviceCache.put(serviceName, service);
135: }
136: }
137:
138: protected String[] getPackageNamesToFilter() {
139: return PACKAGES_TO_FILTER;
140: }
141:
142: protected boolean shouldWrapService(QName serviceName,
143: Object service) {
144: return true;
145: }
146:
147: protected boolean shouldCacheService(QName serviceName,
148: Object service) {
149: return servicesToCache.contains(serviceName);
150: }
151:
152: protected boolean shouldWrapObject(ObjectDefinition definition,
153: Object object) {
154: return true;
155: }
156:
157: }
|