001/*
002 * Copyright 2002-2017 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 *      https://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
017package org.springframework.beans.factory.xml;
018
019import java.io.StringReader;
020
021import org.w3c.dom.Document;
022import org.xml.sax.InputSource;
023
024import org.springframework.beans.factory.BeanDefinitionStoreException;
025import org.springframework.beans.factory.config.BeanDefinition;
026import org.springframework.beans.factory.parsing.ProblemReporter;
027import org.springframework.beans.factory.parsing.ReaderContext;
028import org.springframework.beans.factory.parsing.ReaderEventListener;
029import org.springframework.beans.factory.parsing.SourceExtractor;
030import org.springframework.beans.factory.support.BeanDefinitionRegistry;
031import org.springframework.core.env.Environment;
032import org.springframework.core.io.Resource;
033import org.springframework.core.io.ResourceLoader;
034import org.springframework.lang.Nullable;
035
036/**
037 * Extension of {@link org.springframework.beans.factory.parsing.ReaderContext},
038 * specific to use with an {@link XmlBeanDefinitionReader}. Provides access to the
039 * {@link NamespaceHandlerResolver} configured in the {@link XmlBeanDefinitionReader}.
040 *
041 * @author Rob Harrop
042 * @author Juergen Hoeller
043 * @since 2.0
044 */
045public class XmlReaderContext extends ReaderContext {
046
047        private final XmlBeanDefinitionReader reader;
048
049        private final NamespaceHandlerResolver namespaceHandlerResolver;
050
051
052        /**
053         * Construct a new {@code XmlReaderContext}.
054         * @param resource the XML bean definition resource
055         * @param problemReporter the problem reporter in use
056         * @param eventListener the event listener in use
057         * @param sourceExtractor the source extractor in use
058         * @param reader the XML bean definition reader in use
059         * @param namespaceHandlerResolver the XML namespace resolver
060         */
061        public XmlReaderContext(
062                        Resource resource, ProblemReporter problemReporter,
063                        ReaderEventListener eventListener, SourceExtractor sourceExtractor,
064                        XmlBeanDefinitionReader reader, NamespaceHandlerResolver namespaceHandlerResolver) {
065
066                super(resource, problemReporter, eventListener, sourceExtractor);
067                this.reader = reader;
068                this.namespaceHandlerResolver = namespaceHandlerResolver;
069        }
070
071
072        /**
073         * Return the XML bean definition reader in use.
074         */
075        public final XmlBeanDefinitionReader getReader() {
076                return this.reader;
077        }
078
079        /**
080         * Return the bean definition registry to use.
081         * @see XmlBeanDefinitionReader#XmlBeanDefinitionReader(BeanDefinitionRegistry)
082         */
083        public final BeanDefinitionRegistry getRegistry() {
084                return this.reader.getRegistry();
085        }
086
087        /**
088         * Return the resource loader to use, if any.
089         * <p>This will be non-null in regular scenarios,
090         * also allowing access to the resource class loader.
091         * @see XmlBeanDefinitionReader#setResourceLoader
092         * @see ResourceLoader#getClassLoader()
093         */
094        @Nullable
095        public final ResourceLoader getResourceLoader() {
096                return this.reader.getResourceLoader();
097        }
098
099        /**
100         * Return the bean class loader to use, if any.
101         * <p>Note that this will be null in regular scenarios,
102         * as an indication to lazily resolve bean classes.
103         * @see XmlBeanDefinitionReader#setBeanClassLoader
104         */
105        @Nullable
106        public final ClassLoader getBeanClassLoader() {
107                return this.reader.getBeanClassLoader();
108        }
109
110        /**
111         * Return the environment to use.
112         * @see XmlBeanDefinitionReader#setEnvironment
113         */
114        public final Environment getEnvironment() {
115                return this.reader.getEnvironment();
116        }
117
118        /**
119         * Return the namespace resolver.
120         * @see XmlBeanDefinitionReader#setNamespaceHandlerResolver
121         */
122        public final NamespaceHandlerResolver getNamespaceHandlerResolver() {
123                return this.namespaceHandlerResolver;
124        }
125
126
127        // Convenience methods to delegate to
128
129        /**
130         * Call the bean name generator for the given bean definition.
131         * @see XmlBeanDefinitionReader#getBeanNameGenerator()
132         * @see org.springframework.beans.factory.support.BeanNameGenerator#generateBeanName
133         */
134        public String generateBeanName(BeanDefinition beanDefinition) {
135                return this.reader.getBeanNameGenerator().generateBeanName(beanDefinition, getRegistry());
136        }
137
138        /**
139         * Call the bean name generator for the given bean definition
140         * and register the bean definition under the generated name.
141         * @see XmlBeanDefinitionReader#getBeanNameGenerator()
142         * @see org.springframework.beans.factory.support.BeanNameGenerator#generateBeanName
143         * @see BeanDefinitionRegistry#registerBeanDefinition
144         */
145        public String registerWithGeneratedName(BeanDefinition beanDefinition) {
146                String generatedName = generateBeanName(beanDefinition);
147                getRegistry().registerBeanDefinition(generatedName, beanDefinition);
148                return generatedName;
149        }
150
151        /**
152         * Read an XML document from the given String.
153         * @see #getReader()
154         */
155        public Document readDocumentFromString(String documentContent) {
156                InputSource is = new InputSource(new StringReader(documentContent));
157                try {
158                        return this.reader.doLoadDocument(is, getResource());
159                }
160                catch (Exception ex) {
161                        throw new BeanDefinitionStoreException("Failed to read XML document", ex);
162                }
163        }
164
165}