Fix STS compatibility issues; other improvements
Revert changes to ParserContext, ReaderContext, and XmlReaderContext
These changes cause cross-version incompatibilities at tooling time
-- for instance, an STS version that ships with Spring 3.0.5
classloads the ParserContext defined in that version, whereas it
classloads NamespaceHandlers and BeanDefinitionParsers (by default)
from the user application classpath, which may be building against
3.1.0. If so, the changes introduced to these types in 3.1.0 are
incompatible with expectations in the 3.0.5 world and cause all
manner of problems. In this case, it was NoSuchMethodError due to
the newly-added XmlReaderContext.getProblemReporter() method; also
IncompatibleClassChangeError due to the introduction of the
ComponentRegistrar interface on ParserContext.
Each of these problems have been mitigated, though the solutions
are not ideal. The method mentioned has been removed, and instead
the problemReporter field is now accessed reflectively.
ParserContext now no longer implements ComponentRegistrar, and
rather a ComponentRegistrarAdapter class has been introduced that
passes method calls through to a ParserContext delegate.
Introduce AbstractSpecificationBeanDefinitionParser
AbstractSpecificationBeanDefinitionParser has been introduced in
order to improve the programming model for BeanDefinitionParsers
that have been refactored to the new FeatureSpecification model.
This new base class and it's template method implementation of
parse/doParse ensure that common concerns like (1) adapting a
ParserContext into a SpecificationContext, (2) setting source and
source name on the specification, and (3) actually executing the
specification are all managed by the base class. The subclass
implementation of doParse need only actually parse XML, populate
and return the FeatureSpecification object. This change removed
the many duplicate 'createSpecificationContext' methods that had
been lingering.
Minor improvement to BeanDefinitionReaderUtils API
Introduced new BeanDefinitionReaderUtils#registerWithGeneratedName
variant that accepts BeanDefinition as opposed to
AbstractBeanDefinition, as BeanDefinition is all that is actually
necessary to satisfy the needs of the method implementation. The
latter variant accepting AbstractBeanDefinition has been deprecated
but remains intact and delegates to the new variant in order to
maintain binary compatibility.
This commit is contained in:
parent
939da34869
commit
9cc125531b
|
|
@ -19,6 +19,7 @@ package org.springframework.aop.config;
|
||||||
import org.springframework.beans.factory.config.BeanDefinition;
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
|
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
|
||||||
import org.springframework.beans.factory.parsing.ComponentRegistrar;
|
import org.springframework.beans.factory.parsing.ComponentRegistrar;
|
||||||
|
import org.springframework.beans.factory.parsing.ComponentRegistrarAdapter;
|
||||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||||
import org.springframework.beans.factory.xml.ParserContext;
|
import org.springframework.beans.factory.xml.ParserContext;
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
|
|
@ -63,7 +64,7 @@ public abstract class AopNamespaceUtils {
|
||||||
BeanDefinition beanDefinition = AopConfigUtils.registerAutoProxyCreatorIfNecessary(
|
BeanDefinition beanDefinition = AopConfigUtils.registerAutoProxyCreatorIfNecessary(
|
||||||
parserContext.getRegistry(), parserContext.extractSource(sourceElement));
|
parserContext.getRegistry(), parserContext.extractSource(sourceElement));
|
||||||
useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
|
useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
|
||||||
registerComponentIfNecessary(beanDefinition, parserContext);
|
registerComponentIfNecessary(beanDefinition, new ComponentRegistrarAdapter(parserContext));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void registerAutoProxyCreatorIfNecessary(
|
public static void registerAutoProxyCreatorIfNecessary(
|
||||||
|
|
@ -86,7 +87,7 @@ public abstract class AopNamespaceUtils {
|
||||||
BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAutoProxyCreatorIfNecessary(
|
BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAutoProxyCreatorIfNecessary(
|
||||||
parserContext.getRegistry(), parserContext.extractSource(sourceElement));
|
parserContext.getRegistry(), parserContext.extractSource(sourceElement));
|
||||||
useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
|
useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
|
||||||
registerComponentIfNecessary(beanDefinition, parserContext);
|
registerComponentIfNecessary(beanDefinition, new ComponentRegistrarAdapter(parserContext));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void registerAspectJAnnotationAutoProxyCreatorIfNecessary(
|
public static void registerAspectJAnnotationAutoProxyCreatorIfNecessary(
|
||||||
|
|
@ -95,7 +96,7 @@ public abstract class AopNamespaceUtils {
|
||||||
BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(
|
BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(
|
||||||
parserContext.getRegistry(), parserContext.extractSource(sourceElement));
|
parserContext.getRegistry(), parserContext.extractSource(sourceElement));
|
||||||
useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
|
useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
|
||||||
registerComponentIfNecessary(beanDefinition, parserContext);
|
registerComponentIfNecessary(beanDefinition, new ComponentRegistrarAdapter(parserContext));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -107,7 +108,7 @@ public abstract class AopNamespaceUtils {
|
||||||
public static void registerAutoProxyCreatorIfNecessary(ParserContext parserContext, Object source) {
|
public static void registerAutoProxyCreatorIfNecessary(ParserContext parserContext, Object source) {
|
||||||
BeanDefinition beanDefinition = AopConfigUtils.registerAutoProxyCreatorIfNecessary(
|
BeanDefinition beanDefinition = AopConfigUtils.registerAutoProxyCreatorIfNecessary(
|
||||||
parserContext.getRegistry(), source);
|
parserContext.getRegistry(), source);
|
||||||
registerComponentIfNecessary(beanDefinition, parserContext);
|
registerComponentIfNecessary(beanDefinition, new ComponentRegistrarAdapter(parserContext));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2002-2011 the original author or authors.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.springframework.beans.factory.parsing;
|
|
||||||
|
|
||||||
import org.springframework.beans.factory.config.BeanDefinition;
|
|
||||||
|
|
||||||
public interface BeanDefinitionRegistrar {
|
|
||||||
|
|
||||||
String registerWithGeneratedName(BeanDefinition beanDefinition);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -16,9 +16,20 @@
|
||||||
|
|
||||||
package org.springframework.beans.factory.parsing;
|
package org.springframework.beans.factory.parsing;
|
||||||
|
|
||||||
public interface ComponentRegistrar extends BeanDefinitionRegistrar {
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO SPR-7420: document
|
||||||
|
*
|
||||||
|
* @author Chris Beams
|
||||||
|
* @since 3.1
|
||||||
|
*/
|
||||||
|
public interface ComponentRegistrar {
|
||||||
|
|
||||||
|
String registerWithGeneratedName(BeanDefinition beanDefinition);
|
||||||
|
|
||||||
void registerBeanComponent(BeanComponentDefinition component);
|
void registerBeanComponent(BeanComponentDefinition component);
|
||||||
|
|
||||||
void registerComponent(ComponentDefinition component);
|
void registerComponent(ComponentDefinition component);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2002-2011 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.beans.factory.parsing;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
|
import org.springframework.beans.factory.xml.ParserContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO SPR-7420: document
|
||||||
|
* <p>Adapter is necessary as opposed to having ParserContext
|
||||||
|
* implement ComponentRegistrar directly due to tooling issues.
|
||||||
|
* STS may ship with a version of Spring older that 3.1 (when
|
||||||
|
* this type was introduced), and will run into
|
||||||
|
* IncompatibleClassChangeErrors when it's (3.0.5) ParserContext
|
||||||
|
* tries to mix with our (3.1.0) BeanDefinitionParser
|
||||||
|
* (and related) infrastructure.
|
||||||
|
*
|
||||||
|
* @author Chris Beams
|
||||||
|
* @since 3.1
|
||||||
|
*/
|
||||||
|
public class ComponentRegistrarAdapter implements ComponentRegistrar {
|
||||||
|
|
||||||
|
private final ParserContext parserContext;
|
||||||
|
|
||||||
|
public ComponentRegistrarAdapter(ParserContext parserContext) {
|
||||||
|
this.parserContext = parserContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String registerWithGeneratedName(BeanDefinition beanDefinition) {
|
||||||
|
return this.parserContext.getReaderContext().registerWithGeneratedName(beanDefinition);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void registerBeanComponent(BeanComponentDefinition component) {
|
||||||
|
this.parserContext.registerBeanComponent(component);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void registerComponent(ComponentDefinition component) {
|
||||||
|
this.parserContext.registerComponent(component);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -30,13 +30,12 @@ public class ReaderContext {
|
||||||
|
|
||||||
private final Resource resource;
|
private final Resource resource;
|
||||||
|
|
||||||
|
private final ProblemReporter problemReporter;
|
||||||
|
|
||||||
private final ReaderEventListener eventListener;
|
private final ReaderEventListener eventListener;
|
||||||
|
|
||||||
private final SourceExtractor sourceExtractor;
|
private final SourceExtractor sourceExtractor;
|
||||||
|
|
||||||
// TODO SPR-7420: review exposing problem reporter
|
|
||||||
protected final ProblemReporter problemReporter;
|
|
||||||
|
|
||||||
|
|
||||||
public ReaderContext(Resource resource, ProblemReporter problemReporter,
|
public ReaderContext(Resource resource, ProblemReporter problemReporter,
|
||||||
ReaderEventListener eventListener, SourceExtractor sourceExtractor) {
|
ReaderEventListener eventListener, SourceExtractor sourceExtractor) {
|
||||||
|
|
|
||||||
|
|
@ -166,12 +166,24 @@ public class BeanDefinitionReaderUtils {
|
||||||
* for the given bean definition or the definition cannot be registered
|
* for the given bean definition or the definition cannot be registered
|
||||||
*/
|
*/
|
||||||
public static String registerWithGeneratedName(
|
public static String registerWithGeneratedName(
|
||||||
AbstractBeanDefinition definition, BeanDefinitionRegistry registry)
|
BeanDefinition definition, BeanDefinitionRegistry registry)
|
||||||
throws BeanDefinitionStoreException {
|
throws BeanDefinitionStoreException {
|
||||||
|
|
||||||
String generatedName = generateBeanName(definition, registry, false);
|
String generatedName = generateBeanName(definition, registry, false);
|
||||||
registry.registerBeanDefinition(generatedName, definition);
|
registry.registerBeanDefinition(generatedName, definition);
|
||||||
return generatedName;
|
return generatedName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated since Spring 3.1 in favor of
|
||||||
|
* {@link #registerWithGeneratedName(BeanDefinition, BeanDefinitionRegistry)}
|
||||||
|
* and its more general signature.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public static String registerWithGeneratedName(
|
||||||
|
AbstractBeanDefinition definition, BeanDefinitionRegistry registry)
|
||||||
|
throws BeanDefinitionStoreException {
|
||||||
|
return registerWithGeneratedName((BeanDefinition)definition, registry);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ import java.util.Stack;
|
||||||
import org.springframework.beans.factory.config.BeanDefinition;
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
|
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
|
||||||
import org.springframework.beans.factory.parsing.ComponentDefinition;
|
import org.springframework.beans.factory.parsing.ComponentDefinition;
|
||||||
import org.springframework.beans.factory.parsing.ComponentRegistrar;
|
|
||||||
import org.springframework.beans.factory.parsing.CompositeComponentDefinition;
|
import org.springframework.beans.factory.parsing.CompositeComponentDefinition;
|
||||||
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
|
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
|
||||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||||
|
|
@ -37,7 +36,7 @@ import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||||
* @see XmlReaderContext
|
* @see XmlReaderContext
|
||||||
* @see BeanDefinitionParserDelegate
|
* @see BeanDefinitionParserDelegate
|
||||||
*/
|
*/
|
||||||
public final class ParserContext implements ComponentRegistrar {
|
public final class ParserContext {
|
||||||
|
|
||||||
private final XmlReaderContext readerContext;
|
private final XmlReaderContext readerContext;
|
||||||
|
|
||||||
|
|
@ -122,8 +121,4 @@ public final class ParserContext implements ComponentRegistrar {
|
||||||
registerComponent(component);
|
registerComponent(component);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String registerWithGeneratedName(BeanDefinition beanDefinition) {
|
|
||||||
return this.readerContext.registerWithGeneratedName(beanDefinition);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -83,9 +83,4 @@ public class XmlReaderContext extends ReaderContext {
|
||||||
return generatedName;
|
return generatedName;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO SPR-7420: review exposing problem reporter
|
|
||||||
public ProblemReporter getProblemReporter() {
|
|
||||||
return this.problemReporter;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,11 +16,9 @@
|
||||||
|
|
||||||
package org.springframework.context.annotation;
|
package org.springframework.context.annotation;
|
||||||
|
|
||||||
import org.springframework.beans.factory.config.BeanDefinition;
|
|
||||||
import org.springframework.beans.factory.xml.BeanDefinitionParser;
|
|
||||||
import org.springframework.beans.factory.xml.ParserContext;
|
import org.springframework.beans.factory.xml.ParserContext;
|
||||||
import org.springframework.beans.factory.xml.XmlReaderContext;
|
import org.springframework.context.config.AbstractSpecificationBeanDefinitionParser;
|
||||||
import org.springframework.context.config.SpecificationContext;
|
import org.springframework.context.config.FeatureSpecification;
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
import org.w3c.dom.Node;
|
import org.w3c.dom.Node;
|
||||||
import org.w3c.dom.NodeList;
|
import org.w3c.dom.NodeList;
|
||||||
|
|
@ -38,11 +36,10 @@ import org.w3c.dom.NodeList;
|
||||||
* @see ComponentScanSpec
|
* @see ComponentScanSpec
|
||||||
* @see ComponentScanExecutor
|
* @see ComponentScanExecutor
|
||||||
*/
|
*/
|
||||||
public class ComponentScanBeanDefinitionParser implements BeanDefinitionParser {
|
public class ComponentScanBeanDefinitionParser extends AbstractSpecificationBeanDefinitionParser {
|
||||||
|
|
||||||
public BeanDefinition parse(Element element, ParserContext parserContext) {
|
public FeatureSpecification doParse(Element element, ParserContext parserContext) {
|
||||||
XmlReaderContext readerContext = parserContext.getReaderContext();
|
ClassLoader classLoader = parserContext.getReaderContext().getResourceLoader().getClassLoader();
|
||||||
ClassLoader classLoader = readerContext.getResourceLoader().getClassLoader();
|
|
||||||
|
|
||||||
ComponentScanSpec spec =
|
ComponentScanSpec spec =
|
||||||
ComponentScanSpec.forDelimitedPackages(element.getAttribute("base-package"))
|
ComponentScanSpec.forDelimitedPackages(element.getAttribute("base-package"))
|
||||||
|
|
@ -51,7 +48,9 @@ public class ComponentScanBeanDefinitionParser implements BeanDefinitionParser {
|
||||||
.resourcePattern(element.getAttribute("resource-pattern"))
|
.resourcePattern(element.getAttribute("resource-pattern"))
|
||||||
.beanNameGenerator(element.getAttribute("name-generator"), classLoader)
|
.beanNameGenerator(element.getAttribute("name-generator"), classLoader)
|
||||||
.scopeMetadataResolver(element.getAttribute("scope-resolver"), classLoader)
|
.scopeMetadataResolver(element.getAttribute("scope-resolver"), classLoader)
|
||||||
.scopedProxyMode(element.getAttribute("scoped-proxy"));
|
.scopedProxyMode(element.getAttribute("scoped-proxy"))
|
||||||
|
.beanDefinitionDefaults(parserContext.getDelegate().getBeanDefinitionDefaults())
|
||||||
|
.autowireCandidatePatterns(parserContext.getDelegate().getAutowireCandidatePatterns());
|
||||||
|
|
||||||
// Parse exclude and include filter elements.
|
// Parse exclude and include filter elements.
|
||||||
NodeList nodeList = element.getChildNodes();
|
NodeList nodeList = element.getChildNodes();
|
||||||
|
|
@ -70,26 +69,7 @@ public class ComponentScanBeanDefinitionParser implements BeanDefinitionParser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
spec.beanDefinitionDefaults(parserContext.getDelegate().getBeanDefinitionDefaults())
|
return spec;
|
||||||
.autowireCandidatePatterns(parserContext.getDelegate().getAutowireCandidatePatterns())
|
|
||||||
.source(readerContext.extractSource(element))
|
|
||||||
.sourceName(element.getTagName())
|
|
||||||
.execute(createSpecificationContext(parserContext));
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Adapt the given ParserContext instance into an SpecificationContext.
|
|
||||||
// TODO SPR-7420: create a common ParserContext-to-SpecificationContext adapter utility
|
|
||||||
// or otherwise unify these two types
|
|
||||||
private SpecificationContext createSpecificationContext(ParserContext parserContext) {
|
|
||||||
SpecificationContext specificationContext = new SpecificationContext();
|
|
||||||
specificationContext.setRegistry(parserContext.getRegistry());
|
|
||||||
specificationContext.setRegistrar(parserContext);
|
|
||||||
specificationContext.setResourceLoader(parserContext.getReaderContext().getResourceLoader());
|
|
||||||
specificationContext.setEnvironment(parserContext.getDelegate().getEnvironment());
|
|
||||||
specificationContext.setProblemReporter(parserContext.getReaderContext().getProblemReporter());
|
|
||||||
return specificationContext;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -107,6 +107,7 @@ class ConfigurationClassBeanDefinitionReader {
|
||||||
this.sourceExtractor = sourceExtractor;
|
this.sourceExtractor = sourceExtractor;
|
||||||
this.problemReporter = problemReporter;
|
this.problemReporter = problemReporter;
|
||||||
this.metadataReaderFactory = metadataReaderFactory;
|
this.metadataReaderFactory = metadataReaderFactory;
|
||||||
|
// TODO SPR-7420: see about passing in the SpecificationContext created in ConfigurationClassPostProcessor
|
||||||
this.specificationContext = new SpecificationContext();
|
this.specificationContext = new SpecificationContext();
|
||||||
this.specificationContext.setRegistry(this.registry);
|
this.specificationContext.setRegistry(this.registry);
|
||||||
this.specificationContext.setRegistrar(new SimpleComponentRegistrar(this.registry));
|
this.specificationContext.setRegistrar(new SimpleComponentRegistrar(this.registry));
|
||||||
|
|
@ -171,7 +172,7 @@ class ConfigurationClassBeanDefinitionReader {
|
||||||
}
|
}
|
||||||
|
|
||||||
// no bean definition exists yet -> this must be an imported configuration class (@Import).
|
// no bean definition exists yet -> this must be an imported configuration class (@Import).
|
||||||
GenericBeanDefinition configBeanDef = new GenericBeanDefinition();
|
BeanDefinition configBeanDef = new GenericBeanDefinition();
|
||||||
String className = configClass.getMetadata().getClassName();
|
String className = configClass.getMetadata().getClassName();
|
||||||
configBeanDef.setBeanClassName(className);
|
configBeanDef.setBeanClassName(className);
|
||||||
if (checkConfigurationClassCandidate(configBeanDef, this.metadataReaderFactory)) {
|
if (checkConfigurationClassCandidate(configBeanDef, this.metadataReaderFactory)) {
|
||||||
|
|
|
||||||
|
|
@ -354,8 +354,6 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO SPR-7420: consider unifying the two through a superinterface.
|
|
||||||
// TODO SPR-7420: create a common ParserContext-to-SpecificationContext adapter util
|
|
||||||
private SpecificationContext createSpecificationContext(ConfigurableListableBeanFactory beanFactory) {
|
private SpecificationContext createSpecificationContext(ConfigurableListableBeanFactory beanFactory) {
|
||||||
final BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
|
final BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
|
||||||
SpecificationContext specificationContext = new SpecificationContext();
|
SpecificationContext specificationContext = new SpecificationContext();
|
||||||
|
|
@ -363,8 +361,7 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
|
||||||
specificationContext.setResourceLoader(this.resourceLoader);
|
specificationContext.setResourceLoader(this.resourceLoader);
|
||||||
specificationContext.setRegistry(registry);
|
specificationContext.setRegistry(registry);
|
||||||
specificationContext.setRegistrar(new SimpleComponentRegistrar(registry));
|
specificationContext.setRegistrar(new SimpleComponentRegistrar(registry));
|
||||||
// TODO SPR-7420: how to get hold of the current problem reporter here?
|
specificationContext.setProblemReporter(this.problemReporter);
|
||||||
specificationContext.setProblemReporter(new FailFastProblemReporter());
|
|
||||||
return specificationContext;
|
return specificationContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,6 @@ import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
|
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
|
||||||
import org.springframework.beans.factory.parsing.ComponentDefinition;
|
import org.springframework.beans.factory.parsing.ComponentDefinition;
|
||||||
import org.springframework.beans.factory.parsing.ComponentRegistrar;
|
import org.springframework.beans.factory.parsing.ComponentRegistrar;
|
||||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
|
||||||
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
|
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
|
||||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||||
|
|
||||||
|
|
@ -30,7 +29,7 @@ import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||||
* @author Chris Beams
|
* @author Chris Beams
|
||||||
* @since 3.1
|
* @since 3.1
|
||||||
*/
|
*/
|
||||||
public class SimpleComponentRegistrar implements ComponentRegistrar {
|
class SimpleComponentRegistrar implements ComponentRegistrar {
|
||||||
|
|
||||||
private final BeanDefinitionRegistry registry;
|
private final BeanDefinitionRegistry registry;
|
||||||
|
|
||||||
|
|
@ -39,7 +38,7 @@ public class SimpleComponentRegistrar implements ComponentRegistrar {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String registerWithGeneratedName(BeanDefinition beanDefinition) {
|
public String registerWithGeneratedName(BeanDefinition beanDefinition) {
|
||||||
return BeanDefinitionReaderUtils.registerWithGeneratedName((AbstractBeanDefinition)beanDefinition, this.registry);
|
return BeanDefinitionReaderUtils.registerWithGeneratedName(beanDefinition, this.registry);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void registerBeanComponent(BeanComponentDefinition component) {
|
public void registerBeanComponent(BeanComponentDefinition component) {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,74 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2002-2011 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.context.config;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
|
import org.springframework.beans.factory.parsing.ComponentRegistrarAdapter;
|
||||||
|
import org.springframework.beans.factory.parsing.ProblemReporter;
|
||||||
|
import org.springframework.beans.factory.parsing.ReaderContext;
|
||||||
|
import org.springframework.beans.factory.xml.BeanDefinitionParser;
|
||||||
|
import org.springframework.beans.factory.xml.ParserContext;
|
||||||
|
import org.w3c.dom.Element;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO SPR-7420: document
|
||||||
|
*
|
||||||
|
* @author Chris Beams
|
||||||
|
* @since 3.1
|
||||||
|
*/
|
||||||
|
public abstract class AbstractSpecificationBeanDefinitionParser implements BeanDefinitionParser {
|
||||||
|
|
||||||
|
public final BeanDefinition parse(Element element, ParserContext parserContext) {
|
||||||
|
FeatureSpecification spec = doParse(element, parserContext);
|
||||||
|
if (spec instanceof SourceAwareSpecification) {
|
||||||
|
((SourceAwareSpecification)spec).source(parserContext.getReaderContext().extractSource(element));
|
||||||
|
((SourceAwareSpecification)spec).sourceName(element.getTagName());
|
||||||
|
}
|
||||||
|
spec.execute(specificationContextFrom(parserContext));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract protected FeatureSpecification doParse(Element element, ParserContext parserContext);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adapt the given ParserContext into a SpecificationContext.
|
||||||
|
*/
|
||||||
|
private SpecificationContext specificationContextFrom(ParserContext parserContext) {
|
||||||
|
SpecificationContext specContext = new SpecificationContext();
|
||||||
|
specContext.setRegistry(parserContext.getRegistry());
|
||||||
|
specContext.setRegistrar(new ComponentRegistrarAdapter(parserContext));
|
||||||
|
specContext.setResourceLoader(parserContext.getReaderContext().getResourceLoader());
|
||||||
|
specContext.setEnvironment(parserContext.getDelegate().getEnvironment());
|
||||||
|
try {
|
||||||
|
// access the reader context's problem reporter reflectively in order to
|
||||||
|
// compensate for tooling (STS) constraints around introduction of changes
|
||||||
|
// to parser context / reader context classes.
|
||||||
|
Field field = ReaderContext.class.getDeclaredField("problemReporter");
|
||||||
|
field.setAccessible(true);
|
||||||
|
ProblemReporter problemReporter = (ProblemReporter)field.get(parserContext.getReaderContext());
|
||||||
|
specContext.setProblemReporter(problemReporter);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
throw new IllegalStateException(
|
||||||
|
"Could not access field 'ReaderContext#problemReporter' on object " +
|
||||||
|
parserContext.getReaderContext(), ex);
|
||||||
|
}
|
||||||
|
return specContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -73,6 +73,7 @@ import org.springframework.web.servlet.config.MvcViewControllersTests;
|
||||||
MvcResourcesTests.class,
|
MvcResourcesTests.class,
|
||||||
MvcDefaultServletHandlerTests.class,
|
MvcDefaultServletHandlerTests.class,
|
||||||
MvcNamespaceTests.class
|
MvcNamespaceTests.class
|
||||||
|
})
|
||||||
*/
|
*/
|
||||||
public class FeatureTestSuite {
|
public class FeatureTestSuite {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,10 +17,9 @@
|
||||||
package org.springframework.transaction.config;
|
package org.springframework.transaction.config;
|
||||||
|
|
||||||
import org.springframework.aop.config.AopNamespaceUtils;
|
import org.springframework.aop.config.AopNamespaceUtils;
|
||||||
import org.springframework.beans.factory.config.BeanDefinition;
|
|
||||||
import org.springframework.beans.factory.xml.BeanDefinitionParser;
|
|
||||||
import org.springframework.beans.factory.xml.ParserContext;
|
import org.springframework.beans.factory.xml.ParserContext;
|
||||||
import org.springframework.context.config.SpecificationContext;
|
import org.springframework.context.config.AbstractSpecificationBeanDefinitionParser;
|
||||||
|
import org.springframework.context.config.FeatureSpecification;
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -41,7 +40,7 @@ import org.w3c.dom.Element;
|
||||||
* @since 2.0
|
* @since 2.0
|
||||||
* @see TxAnnotationDriven
|
* @see TxAnnotationDriven
|
||||||
*/
|
*/
|
||||||
class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
|
class AnnotationDrivenBeanDefinitionParser extends AbstractSpecificationBeanDefinitionParser {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The bean name of the internally managed transaction advisor (mode="proxy").
|
* The bean name of the internally managed transaction advisor (mode="proxy").
|
||||||
|
|
@ -61,29 +60,12 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
|
||||||
* {@link AopNamespaceUtils#registerAutoProxyCreatorIfNecessary register an AutoProxyCreator}
|
* {@link AopNamespaceUtils#registerAutoProxyCreatorIfNecessary register an AutoProxyCreator}
|
||||||
* with the container as necessary.
|
* with the container as necessary.
|
||||||
*/
|
*/
|
||||||
public BeanDefinition parse(Element element, ParserContext parserContext) {
|
@Override
|
||||||
new TxAnnotationDriven(element.getAttribute("transaction-manager"))
|
protected FeatureSpecification doParse(Element element, ParserContext parserContext) {
|
||||||
|
return new TxAnnotationDriven(element.getAttribute("transaction-manager"))
|
||||||
.order(element.getAttribute("order"))
|
.order(element.getAttribute("order"))
|
||||||
.mode(element.getAttribute("mode"))
|
.mode(element.getAttribute("mode"))
|
||||||
.proxyTargetClass(Boolean.valueOf(element.getAttribute("proxy-target-class")))
|
.proxyTargetClass(Boolean.valueOf(element.getAttribute("proxy-target-class")));
|
||||||
.source(parserContext.extractSource(element))
|
|
||||||
.sourceName(element.getTagName())
|
|
||||||
.execute(createSpecificationContext(parserContext));
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adapt the given ParserContext instance into an SpecificationContext.
|
|
||||||
*
|
|
||||||
* TODO SPR-7420: consider unifying the two through a superinterface.
|
|
||||||
* TODO SPR-7420: create a common ParserContext-to-SpecificationContext adapter util
|
|
||||||
*/
|
|
||||||
private SpecificationContext createSpecificationContext(ParserContext parserContext) {
|
|
||||||
SpecificationContext specificationContext = new SpecificationContext();
|
|
||||||
specificationContext.setRegistry(parserContext.getRegistry());
|
|
||||||
specificationContext.setRegistrar(parserContext);
|
|
||||||
specificationContext.setProblemReporter(parserContext.getReaderContext().getProblemReporter());
|
|
||||||
return specificationContext;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,12 +16,12 @@
|
||||||
|
|
||||||
package org.springframework.web.servlet.config;
|
package org.springframework.web.servlet.config;
|
||||||
|
|
||||||
import org.springframework.beans.factory.config.BeanDefinition;
|
|
||||||
import org.springframework.beans.factory.config.BeanDefinitionHolder;
|
import org.springframework.beans.factory.config.BeanDefinitionHolder;
|
||||||
import org.springframework.beans.factory.support.ManagedList;
|
import org.springframework.beans.factory.support.ManagedList;
|
||||||
import org.springframework.beans.factory.xml.BeanDefinitionParser;
|
import org.springframework.beans.factory.xml.BeanDefinitionParser;
|
||||||
import org.springframework.beans.factory.xml.ParserContext;
|
import org.springframework.beans.factory.xml.ParserContext;
|
||||||
import org.springframework.context.config.SpecificationContext;
|
import org.springframework.context.config.AbstractSpecificationBeanDefinitionParser;
|
||||||
|
import org.springframework.context.config.FeatureSpecification;
|
||||||
import org.springframework.util.xml.DomUtils;
|
import org.springframework.util.xml.DomUtils;
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
|
|
||||||
|
|
@ -30,22 +30,18 @@ import org.w3c.dom.Element;
|
||||||
* to configure a Spring MVC web application.
|
* to configure a Spring MVC web application.
|
||||||
*
|
*
|
||||||
* @author Rossen Stoyanchev
|
* @author Rossen Stoyanchev
|
||||||
|
* @author Chris Beams
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
* @see MvcAnnotationDriven
|
* @see MvcAnnotationDriven
|
||||||
* @see MvcAnnotationDrivenExecutor
|
* @see MvcAnnotationDrivenExecutor
|
||||||
*/
|
*/
|
||||||
class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
|
class AnnotationDrivenBeanDefinitionParser extends AbstractSpecificationBeanDefinitionParser {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses the {@code <mvc:annotation-driven/>} tag.
|
* Parses the {@code <mvc:annotation-driven/>} tag.
|
||||||
*/
|
*/
|
||||||
public BeanDefinition parse(Element element, ParserContext parserContext) {
|
@Override
|
||||||
MvcAnnotationDriven spec = createSpecification(element, parserContext);
|
protected FeatureSpecification doParse(Element element, ParserContext parserContext) {
|
||||||
spec.execute(createSpecificationContext(parserContext));
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private MvcAnnotationDriven createSpecification(Element element, ParserContext parserContext) {
|
|
||||||
MvcAnnotationDriven spec = new MvcAnnotationDriven();
|
MvcAnnotationDriven spec = new MvcAnnotationDriven();
|
||||||
if (element.hasAttribute("conversion-service")) {
|
if (element.hasAttribute("conversion-service")) {
|
||||||
String conversionService = element.getAttribute("conversion-service");
|
String conversionService = element.getAttribute("conversion-service");
|
||||||
|
|
@ -70,8 +66,6 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
|
||||||
spec.argumentResolvers(extractBeanSubElements(resolversElement, parserContext));
|
spec.argumentResolvers(extractBeanSubElements(resolversElement, parserContext));
|
||||||
}
|
}
|
||||||
|
|
||||||
spec.source(parserContext.extractSource(element));
|
|
||||||
spec.sourceName(element.getTagName());
|
|
||||||
return spec;
|
return spec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -86,18 +80,4 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adapt the given ParserContext instance into an SpecificationContext.
|
|
||||||
*
|
|
||||||
* TODO SPR-7420: consider unifying the two through a superinterface.
|
|
||||||
* TODO SPR-7420: create a common ParserContext-to-SpecificationContext adapter util
|
|
||||||
*/
|
|
||||||
private SpecificationContext createSpecificationContext(ParserContext parserContext) {
|
|
||||||
SpecificationContext executorContext = new SpecificationContext();
|
|
||||||
executorContext.setRegistry(parserContext.getRegistry());
|
|
||||||
executorContext.setRegistrar(parserContext);
|
|
||||||
executorContext.setProblemReporter(parserContext.getReaderContext().getProblemReporter());
|
|
||||||
return executorContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,10 +16,10 @@
|
||||||
|
|
||||||
package org.springframework.web.servlet.config;
|
package org.springframework.web.servlet.config;
|
||||||
|
|
||||||
import org.springframework.beans.factory.config.BeanDefinition;
|
|
||||||
import org.springframework.beans.factory.xml.BeanDefinitionParser;
|
import org.springframework.beans.factory.xml.BeanDefinitionParser;
|
||||||
import org.springframework.beans.factory.xml.ParserContext;
|
import org.springframework.beans.factory.xml.ParserContext;
|
||||||
import org.springframework.context.config.SpecificationContext;
|
import org.springframework.context.config.AbstractSpecificationBeanDefinitionParser;
|
||||||
|
import org.springframework.context.config.FeatureSpecification;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
|
import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
|
||||||
import org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter;
|
import org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter;
|
||||||
|
|
@ -33,38 +33,19 @@ import org.w3c.dom.Element;
|
||||||
* {@link HttpRequestHandlerAdapter} if necessary.
|
* {@link HttpRequestHandlerAdapter} if necessary.
|
||||||
*
|
*
|
||||||
* @author Rossen Stoyanchev
|
* @author Rossen Stoyanchev
|
||||||
|
* @author Chris Beams
|
||||||
* @since 3.0.4
|
* @since 3.0.4
|
||||||
*/
|
*/
|
||||||
class DefaultServletHandlerBeanDefinitionParser implements BeanDefinitionParser {
|
class DefaultServletHandlerBeanDefinitionParser extends AbstractSpecificationBeanDefinitionParser {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses the {@code <mvc:default-servlet-handler/>} tag.
|
* Parses the {@code <mvc:default-servlet-handler/>} tag.
|
||||||
*/
|
*/
|
||||||
public BeanDefinition parse(Element element, ParserContext parserContext) {
|
public FeatureSpecification doParse(Element element, ParserContext parserContext) {
|
||||||
MvcDefaultServletHandler spec = createSpecification(element, parserContext);
|
|
||||||
spec.execute(createSpecificationContext(parserContext));
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private MvcDefaultServletHandler createSpecification(Element element, ParserContext parserContext) {
|
|
||||||
String defaultServletHandler = element.getAttribute("default-servlet-handler");
|
String defaultServletHandler = element.getAttribute("default-servlet-handler");
|
||||||
MvcDefaultServletHandler spec = StringUtils.hasText(defaultServletHandler) ? new MvcDefaultServletHandler(
|
return StringUtils.hasText(defaultServletHandler) ?
|
||||||
defaultServletHandler) : new MvcDefaultServletHandler();
|
new MvcDefaultServletHandler(defaultServletHandler) :
|
||||||
return spec;
|
new MvcDefaultServletHandler();
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adapt the given ParserContext instance into an SpecificationContext.
|
|
||||||
*
|
|
||||||
* TODO SPR-7420: consider unifying the two through a superinterface.
|
|
||||||
* TODO SPR-7420: create a common ParserContext-to-SpecificationContext adapter util
|
|
||||||
*/
|
|
||||||
private SpecificationContext createSpecificationContext(ParserContext parserContext) {
|
|
||||||
SpecificationContext context = new SpecificationContext();
|
|
||||||
context.setRegistry(parserContext.getRegistry());
|
|
||||||
context.setRegistrar(parserContext);
|
|
||||||
context.setProblemReporter(parserContext.getReaderContext().getProblemReporter());
|
|
||||||
return context;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,10 +16,9 @@
|
||||||
|
|
||||||
package org.springframework.web.servlet.config;
|
package org.springframework.web.servlet.config;
|
||||||
|
|
||||||
import org.springframework.beans.factory.config.BeanDefinition;
|
|
||||||
import org.springframework.beans.factory.xml.BeanDefinitionParser;
|
|
||||||
import org.springframework.beans.factory.xml.ParserContext;
|
import org.springframework.beans.factory.xml.ParserContext;
|
||||||
import org.springframework.context.config.SpecificationContext;
|
import org.springframework.context.config.AbstractSpecificationBeanDefinitionParser;
|
||||||
|
import org.springframework.context.config.FeatureSpecification;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
|
|
||||||
|
|
@ -32,32 +31,16 @@ import org.w3c.dom.Element;
|
||||||
* @see MvcResources
|
* @see MvcResources
|
||||||
* @see MvcResourcesExecutor
|
* @see MvcResourcesExecutor
|
||||||
*/
|
*/
|
||||||
class ResourcesBeanDefinitionParser implements BeanDefinitionParser {
|
class ResourcesBeanDefinitionParser extends AbstractSpecificationBeanDefinitionParser {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses the {@code <mvc:resources/>} tag
|
* Parses the {@code <mvc:resources/>} tag
|
||||||
*/
|
*/
|
||||||
public BeanDefinition parse(Element element, ParserContext parserContext) {
|
public FeatureSpecification doParse(Element element, ParserContext parserContext) {
|
||||||
MvcResources spec = createSpecification(element, parserContext);
|
|
||||||
if (spec != null) {
|
|
||||||
spec.execute(createSpecificationContext(parserContext));
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private MvcResources createSpecification(Element element, ParserContext parserContext) {
|
|
||||||
String mapping = element.getAttribute("mapping");
|
String mapping = element.getAttribute("mapping");
|
||||||
if (!StringUtils.hasText(mapping)) {
|
String[] locations =
|
||||||
parserContext.getReaderContext().error("The 'mapping' attribute is required.",
|
StringUtils.commaDelimitedListToStringArray(element.getAttribute("location"));
|
||||||
parserContext.extractSource(element));
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
String[] locations = StringUtils.commaDelimitedListToStringArray(element.getAttribute("location"));
|
|
||||||
if (locations.length == 0) {
|
|
||||||
parserContext.getReaderContext().error("The 'location' attribute is required.",
|
|
||||||
parserContext.extractSource(element));
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
MvcResources spec = new MvcResources(mapping, locations);
|
MvcResources spec = new MvcResources(mapping, locations);
|
||||||
if (element.hasAttribute("cache-period")) {
|
if (element.hasAttribute("cache-period")) {
|
||||||
spec.cachePeriod(element.getAttribute("cache-period"));
|
spec.cachePeriod(element.getAttribute("cache-period"));
|
||||||
|
|
@ -65,23 +48,8 @@ class ResourcesBeanDefinitionParser implements BeanDefinitionParser {
|
||||||
if (element.hasAttribute("order")) {
|
if (element.hasAttribute("order")) {
|
||||||
spec.order(element.getAttribute("order"));
|
spec.order(element.getAttribute("order"));
|
||||||
}
|
}
|
||||||
spec.source(parserContext.extractSource(element));
|
|
||||||
spec.sourceName(element.getTagName());
|
|
||||||
return spec;
|
return spec;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adapt the given ParserContext instance into an SpecificationContext.
|
|
||||||
*
|
|
||||||
* TODO SPR-7420: consider unifying the two through a superinterface.
|
|
||||||
* TODO SPR-7420: create a common ParserContext-to-SpecificationContext adapter util
|
|
||||||
*/
|
|
||||||
private SpecificationContext createSpecificationContext(ParserContext parserContext) {
|
|
||||||
SpecificationContext context = new SpecificationContext();
|
|
||||||
context.setRegistry(parserContext.getRegistry());
|
|
||||||
context.setRegistrar(parserContext);
|
|
||||||
context.setProblemReporter(parserContext.getReaderContext().getProblemReporter());
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,10 +16,9 @@
|
||||||
|
|
||||||
package org.springframework.web.servlet.config;
|
package org.springframework.web.servlet.config;
|
||||||
|
|
||||||
import org.springframework.beans.factory.config.BeanDefinition;
|
|
||||||
import org.springframework.beans.factory.xml.BeanDefinitionParser;
|
|
||||||
import org.springframework.beans.factory.xml.ParserContext;
|
import org.springframework.beans.factory.xml.ParserContext;
|
||||||
import org.springframework.context.config.SpecificationContext;
|
import org.springframework.context.config.AbstractSpecificationBeanDefinitionParser;
|
||||||
|
import org.springframework.context.config.FeatureSpecification;
|
||||||
import org.springframework.web.servlet.mvc.ParameterizableViewController;
|
import org.springframework.web.servlet.mvc.ParameterizableViewController;
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
|
|
||||||
|
|
@ -32,33 +31,15 @@ import org.w3c.dom.Element;
|
||||||
* @see MvcViewControllers
|
* @see MvcViewControllers
|
||||||
* @see MvcViewControllersExecutor
|
* @see MvcViewControllersExecutor
|
||||||
*/
|
*/
|
||||||
class ViewControllerBeanDefinitionParser implements BeanDefinitionParser {
|
class ViewControllerBeanDefinitionParser extends AbstractSpecificationBeanDefinitionParser {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses the {@code <mvc:view-controller/>} tag.
|
* Parses the {@code <mvc:view-controller/>} tag.
|
||||||
*/
|
*/
|
||||||
public BeanDefinition parse(Element element, ParserContext parserContext) {
|
public FeatureSpecification doParse(Element element, ParserContext parserContext) {
|
||||||
String path = element.getAttribute("path");
|
String path = element.getAttribute("path");
|
||||||
String viewName = element.getAttribute("view-name");
|
String viewName = element.getAttribute("view-name");
|
||||||
new MvcViewControllers(path, viewName.isEmpty() ? null : viewName)
|
return new MvcViewControllers(path, viewName.isEmpty() ? null : viewName);
|
||||||
.source(parserContext.extractSource(element))
|
|
||||||
.sourceName(element.getTagName())
|
|
||||||
.execute(createSpecificationContext(parserContext));
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adapt the given ParserContext instance into an SpecificationContext.
|
|
||||||
*
|
|
||||||
* TODO SPR-7420: consider unifying the two through a superinterface.
|
|
||||||
* TODO SPR-7420: create a common ParserContext-to-SpecificationContext adapter util
|
|
||||||
*/
|
|
||||||
private SpecificationContext createSpecificationContext(ParserContext parserContext) {
|
|
||||||
SpecificationContext context = new SpecificationContext();
|
|
||||||
context.setRegistry(parserContext.getRegistry());
|
|
||||||
context.setRegistrar(parserContext);
|
|
||||||
context.setProblemReporter(parserContext.getReaderContext().getProblemReporter());
|
|
||||||
return context;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue