001: /*
002: * Copyright 2002-2007 the original author or authors.
003: *
004: * Licensed under the Apache 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.apache.org/licenses/LICENSE-2.0
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:
017: package org.springframework.beans.factory.support;
018:
019: import java.io.IOException;
020:
021: import org.apache.commons.logging.Log;
022: import org.apache.commons.logging.LogFactory;
023:
024: import org.springframework.beans.factory.BeanDefinitionStoreException;
025: import org.springframework.core.io.Resource;
026: import org.springframework.core.io.ResourceLoader;
027: import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
028: import org.springframework.core.io.support.ResourcePatternResolver;
029: import org.springframework.util.Assert;
030:
031: /**
032: * Abstract base class for bean definition readers which implement
033: * the {@link BeanDefinitionReader} interface.
034: *
035: * <p>Provides common properties like the bean factory to work on
036: * and the class loader to use for loading bean classes.
037: *
038: * @author Juergen Hoeller
039: * @since 11.12.2003
040: * @see BeanDefinitionReaderUtils
041: */
042: public abstract class AbstractBeanDefinitionReader implements
043: BeanDefinitionReader {
044:
045: protected final Log logger = LogFactory.getLog(getClass());
046:
047: private final BeanDefinitionRegistry beanFactory;
048:
049: private BeanNameGenerator beanNameGenerator = new DefaultBeanNameGenerator();
050:
051: private ResourceLoader resourceLoader;
052:
053: private ClassLoader beanClassLoader;
054:
055: /**
056: * Create a new AbstractBeanDefinitionReader for the given bean factory.
057: * <p>If the passed-in bean factory does not only implement the BeanDefinitionRegistry
058: * interface but also the ResourceLoader interface, it will be used as default
059: * ResourceLoader as well. This will usually be the case for
060: * {@link org.springframework.context.ApplicationContext} implementations.
061: * <p>If given a plain BeanDefinitionRegistry, the default ResourceLoader will be a
062: * {@link org.springframework.core.io.support.PathMatchingResourcePatternResolver}.
063: * @param beanFactory the BeanFactory to load bean definitions into,
064: * in the form of a BeanDefinitionRegistry
065: * @see #setResourceLoader
066: */
067: protected AbstractBeanDefinitionReader(
068: BeanDefinitionRegistry beanFactory) {
069: Assert.notNull(beanFactory, "Bean factory must not be null");
070: this .beanFactory = beanFactory;
071:
072: // Determine ResourceLoader to use.
073: if (this .beanFactory instanceof ResourceLoader) {
074: this .resourceLoader = (ResourceLoader) this .beanFactory;
075: } else {
076: this .resourceLoader = new PathMatchingResourcePatternResolver();
077: }
078: }
079:
080: public BeanDefinitionRegistry getBeanFactory() {
081: return this .beanFactory;
082: }
083:
084: public void setBeanNameGenerator(BeanNameGenerator beanNameGenerator) {
085: this .beanNameGenerator = (beanNameGenerator != null ? beanNameGenerator
086: : new DefaultBeanNameGenerator());
087: }
088:
089: public BeanNameGenerator getBeanNameGenerator() {
090: return this .beanNameGenerator;
091: }
092:
093: /**
094: * Set the ResourceLoader to use for resource locations.
095: * If specifying a ResourcePatternResolver, the bean definition reader
096: * will be capable of resolving resource patterns to Resource arrays.
097: * <p>Default is PathMatchingResourcePatternResolver, also capable of
098: * resource pattern resolving through the ResourcePatternResolver interface.
099: * <p>Setting this to <code>null</code> suggests that absolute resource loading
100: * is not available for this bean definition reader.
101: * @see org.springframework.core.io.support.ResourcePatternResolver
102: * @see org.springframework.core.io.support.PathMatchingResourcePatternResolver
103: */
104: public void setResourceLoader(ResourceLoader resourceLoader) {
105: this .resourceLoader = resourceLoader;
106: }
107:
108: public ResourceLoader getResourceLoader() {
109: return this .resourceLoader;
110: }
111:
112: /**
113: * Set the ClassLoader to use for bean classes.
114: * <p>Default is <code>null</code>, which suggests to not load bean classes
115: * eagerly but rather to just register bean definitions with class names,
116: * with the corresponding Classes to be resolved later (or never).
117: * @see java.lang.Thread#getContextClassLoader()
118: */
119: public void setBeanClassLoader(ClassLoader beanClassLoader) {
120: this .beanClassLoader = beanClassLoader;
121: }
122:
123: public ClassLoader getBeanClassLoader() {
124: return this .beanClassLoader;
125: }
126:
127: public int loadBeanDefinitions(Resource[] resources)
128: throws BeanDefinitionStoreException {
129: Assert.notNull(resources, "Resource array must not be null");
130: int counter = 0;
131: for (int i = 0; i < resources.length; i++) {
132: counter += loadBeanDefinitions(resources[i]);
133: }
134: return counter;
135: }
136:
137: public int loadBeanDefinitions(String location)
138: throws BeanDefinitionStoreException {
139: ResourceLoader resourceLoader = getResourceLoader();
140: if (resourceLoader == null) {
141: throw new BeanDefinitionStoreException(
142: "Cannot import bean definitions from location ["
143: + location
144: + "]: no ResourceLoader available");
145: }
146:
147: if (resourceLoader instanceof ResourcePatternResolver) {
148: // Resource pattern matching available.
149: try {
150: Resource[] resources = ((ResourcePatternResolver) resourceLoader)
151: .getResources(location);
152: int loadCount = loadBeanDefinitions(resources);
153: if (logger.isDebugEnabled()) {
154: logger
155: .debug("Loaded "
156: + loadCount
157: + " bean definitions from location pattern ["
158: + location + "]");
159: }
160: return loadCount;
161: } catch (IOException ex) {
162: throw new BeanDefinitionStoreException(
163: "Could not resolve bean definition resource pattern ["
164: + location + "]", ex);
165: }
166: } else {
167: // Can only load single resources by absolute URL.
168: Resource resource = resourceLoader.getResource(location);
169: int loadCount = loadBeanDefinitions(resource);
170: if (logger.isDebugEnabled()) {
171: logger.debug("Loaded " + loadCount
172: + " bean definitions from location ["
173: + location + "]");
174: }
175: return loadCount;
176: }
177: }
178:
179: public int loadBeanDefinitions(String[] locations)
180: throws BeanDefinitionStoreException {
181: Assert.notNull(locations, "Location array must not be null");
182: int counter = 0;
183: for (int i = 0; i < locations.length; i++) {
184: counter += loadBeanDefinitions(locations[i]);
185: }
186: return counter;
187: }
188:
189: }
|