diff --git a/org.springframework.aop/src/main/java/org/springframework/aop/config/AopNamespaceUtils.java b/org.springframework.aop/src/main/java/org/springframework/aop/config/AopNamespaceUtils.java index c3985b8934e..a21999ff776 100644 --- a/org.springframework.aop/src/main/java/org/springframework/aop/config/AopNamespaceUtils.java +++ b/org.springframework.aop/src/main/java/org/springframework/aop/config/AopNamespaceUtils.java @@ -19,6 +19,7 @@ package org.springframework.aop.config; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.parsing.BeanComponentDefinition; 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.xml.ParserContext; import org.w3c.dom.Element; @@ -63,7 +64,7 @@ public abstract class AopNamespaceUtils { BeanDefinition beanDefinition = AopConfigUtils.registerAutoProxyCreatorIfNecessary( parserContext.getRegistry(), parserContext.extractSource(sourceElement)); useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement); - registerComponentIfNecessary(beanDefinition, parserContext); + registerComponentIfNecessary(beanDefinition, new ComponentRegistrarAdapter(parserContext)); } public static void registerAutoProxyCreatorIfNecessary( @@ -86,7 +87,7 @@ public abstract class AopNamespaceUtils { BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAutoProxyCreatorIfNecessary( parserContext.getRegistry(), parserContext.extractSource(sourceElement)); useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement); - registerComponentIfNecessary(beanDefinition, parserContext); + registerComponentIfNecessary(beanDefinition, new ComponentRegistrarAdapter(parserContext)); } public static void registerAspectJAnnotationAutoProxyCreatorIfNecessary( @@ -95,7 +96,7 @@ public abstract class AopNamespaceUtils { BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary( parserContext.getRegistry(), parserContext.extractSource(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) { BeanDefinition beanDefinition = AopConfigUtils.registerAutoProxyCreatorIfNecessary( parserContext.getRegistry(), source); - registerComponentIfNecessary(beanDefinition, parserContext); + registerComponentIfNecessary(beanDefinition, new ComponentRegistrarAdapter(parserContext)); } /** diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/factory/parsing/BeanDefinitionRegistrar.java b/org.springframework.beans/src/main/java/org/springframework/beans/factory/parsing/BeanDefinitionRegistrar.java deleted file mode 100644 index 9184b9c0a3b..00000000000 --- a/org.springframework.beans/src/main/java/org/springframework/beans/factory/parsing/BeanDefinitionRegistrar.java +++ /dev/null @@ -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); - -} diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/factory/parsing/ComponentRegistrar.java b/org.springframework.beans/src/main/java/org/springframework/beans/factory/parsing/ComponentRegistrar.java index 94eb6541b62..45016231d71 100644 --- a/org.springframework.beans/src/main/java/org/springframework/beans/factory/parsing/ComponentRegistrar.java +++ b/org.springframework.beans/src/main/java/org/springframework/beans/factory/parsing/ComponentRegistrar.java @@ -16,9 +16,20 @@ 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 registerComponent(ComponentDefinition component); + } diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/factory/parsing/ComponentRegistrarAdapter.java b/org.springframework.beans/src/main/java/org/springframework/beans/factory/parsing/ComponentRegistrarAdapter.java new file mode 100644 index 00000000000..36a84706f6a --- /dev/null +++ b/org.springframework.beans/src/main/java/org/springframework/beans/factory/parsing/ComponentRegistrarAdapter.java @@ -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 + *

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); + } + +} diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/factory/parsing/ReaderContext.java b/org.springframework.beans/src/main/java/org/springframework/beans/factory/parsing/ReaderContext.java index 39c9741a971..64689f6486c 100644 --- a/org.springframework.beans/src/main/java/org/springframework/beans/factory/parsing/ReaderContext.java +++ b/org.springframework.beans/src/main/java/org/springframework/beans/factory/parsing/ReaderContext.java @@ -30,13 +30,12 @@ public class ReaderContext { private final Resource resource; + private final ProblemReporter problemReporter; + private final ReaderEventListener eventListener; private final SourceExtractor sourceExtractor; - // TODO SPR-7420: review exposing problem reporter - protected final ProblemReporter problemReporter; - public ReaderContext(Resource resource, ProblemReporter problemReporter, ReaderEventListener eventListener, SourceExtractor sourceExtractor) { diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/BeanDefinitionReaderUtils.java b/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/BeanDefinitionReaderUtils.java index 1d80a290cfc..4407c05902f 100644 --- a/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/BeanDefinitionReaderUtils.java +++ b/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/BeanDefinitionReaderUtils.java @@ -166,12 +166,24 @@ public class BeanDefinitionReaderUtils { * for the given bean definition or the definition cannot be registered */ public static String registerWithGeneratedName( - AbstractBeanDefinition definition, BeanDefinitionRegistry registry) + BeanDefinition definition, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException { - String generatedName = generateBeanName(definition, registry, false); registry.registerBeanDefinition(generatedName, definition); 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); + + } + } diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/factory/xml/ParserContext.java b/org.springframework.beans/src/main/java/org/springframework/beans/factory/xml/ParserContext.java index 78ad74e2f2c..c36314c0d14 100644 --- a/org.springframework.beans/src/main/java/org/springframework/beans/factory/xml/ParserContext.java +++ b/org.springframework.beans/src/main/java/org/springframework/beans/factory/xml/ParserContext.java @@ -21,7 +21,6 @@ import java.util.Stack; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.parsing.BeanComponentDefinition; 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.support.BeanDefinitionReaderUtils; import org.springframework.beans.factory.support.BeanDefinitionRegistry; @@ -37,7 +36,7 @@ import org.springframework.beans.factory.support.BeanDefinitionRegistry; * @see XmlReaderContext * @see BeanDefinitionParserDelegate */ -public final class ParserContext implements ComponentRegistrar { +public final class ParserContext { private final XmlReaderContext readerContext; @@ -122,8 +121,4 @@ public final class ParserContext implements ComponentRegistrar { registerComponent(component); } - public String registerWithGeneratedName(BeanDefinition beanDefinition) { - return this.readerContext.registerWithGeneratedName(beanDefinition); - } - } diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/factory/xml/XmlReaderContext.java b/org.springframework.beans/src/main/java/org/springframework/beans/factory/xml/XmlReaderContext.java index 8dd361ce399..cbb5a0d5040 100644 --- a/org.springframework.beans/src/main/java/org/springframework/beans/factory/xml/XmlReaderContext.java +++ b/org.springframework.beans/src/main/java/org/springframework/beans/factory/xml/XmlReaderContext.java @@ -83,9 +83,4 @@ public class XmlReaderContext extends ReaderContext { return generatedName; } - // TODO SPR-7420: review exposing problem reporter - public ProblemReporter getProblemReporter() { - return this.problemReporter; - } - } diff --git a/org.springframework.context/src/main/java/org/springframework/context/annotation/ComponentScanBeanDefinitionParser.java b/org.springframework.context/src/main/java/org/springframework/context/annotation/ComponentScanBeanDefinitionParser.java index 1da8a0ef10a..a10f608053f 100644 --- a/org.springframework.context/src/main/java/org/springframework/context/annotation/ComponentScanBeanDefinitionParser.java +++ b/org.springframework.context/src/main/java/org/springframework/context/annotation/ComponentScanBeanDefinitionParser.java @@ -16,11 +16,9 @@ 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.XmlReaderContext; -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.Node; import org.w3c.dom.NodeList; @@ -38,11 +36,10 @@ import org.w3c.dom.NodeList; * @see ComponentScanSpec * @see ComponentScanExecutor */ -public class ComponentScanBeanDefinitionParser implements BeanDefinitionParser { +public class ComponentScanBeanDefinitionParser extends AbstractSpecificationBeanDefinitionParser { - public BeanDefinition parse(Element element, ParserContext parserContext) { - XmlReaderContext readerContext = parserContext.getReaderContext(); - ClassLoader classLoader = readerContext.getResourceLoader().getClassLoader(); + public FeatureSpecification doParse(Element element, ParserContext parserContext) { + ClassLoader classLoader = parserContext.getReaderContext().getResourceLoader().getClassLoader(); ComponentScanSpec spec = ComponentScanSpec.forDelimitedPackages(element.getAttribute("base-package")) @@ -51,7 +48,9 @@ public class ComponentScanBeanDefinitionParser implements BeanDefinitionParser { .resourcePattern(element.getAttribute("resource-pattern")) .beanNameGenerator(element.getAttribute("name-generator"), 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. NodeList nodeList = element.getChildNodes(); @@ -70,26 +69,7 @@ public class ComponentScanBeanDefinitionParser implements BeanDefinitionParser { } } - spec.beanDefinitionDefaults(parserContext.getDelegate().getBeanDefinitionDefaults()) - .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; + return spec; } } diff --git a/org.springframework.context/src/main/java/org/springframework/context/annotation/ConfigurationClassBeanDefinitionReader.java b/org.springframework.context/src/main/java/org/springframework/context/annotation/ConfigurationClassBeanDefinitionReader.java index 879db9ce04d..e2802254b8c 100644 --- a/org.springframework.context/src/main/java/org/springframework/context/annotation/ConfigurationClassBeanDefinitionReader.java +++ b/org.springframework.context/src/main/java/org/springframework/context/annotation/ConfigurationClassBeanDefinitionReader.java @@ -107,6 +107,7 @@ class ConfigurationClassBeanDefinitionReader { this.sourceExtractor = sourceExtractor; this.problemReporter = problemReporter; this.metadataReaderFactory = metadataReaderFactory; + // TODO SPR-7420: see about passing in the SpecificationContext created in ConfigurationClassPostProcessor this.specificationContext = new SpecificationContext(); this.specificationContext.setRegistry(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). - GenericBeanDefinition configBeanDef = new GenericBeanDefinition(); + BeanDefinition configBeanDef = new GenericBeanDefinition(); String className = configClass.getMetadata().getClassName(); configBeanDef.setBeanClassName(className); if (checkConfigurationClassCandidate(configBeanDef, this.metadataReaderFactory)) { diff --git a/org.springframework.context/src/main/java/org/springframework/context/annotation/ConfigurationClassPostProcessor.java b/org.springframework.context/src/main/java/org/springframework/context/annotation/ConfigurationClassPostProcessor.java index 30a73a78b08..ec1fec1e65e 100644 --- a/org.springframework.context/src/main/java/org/springframework/context/annotation/ConfigurationClassPostProcessor.java +++ b/org.springframework.context/src/main/java/org/springframework/context/annotation/ConfigurationClassPostProcessor.java @@ -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) { final BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory; SpecificationContext specificationContext = new SpecificationContext(); @@ -363,8 +361,7 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo specificationContext.setResourceLoader(this.resourceLoader); specificationContext.setRegistry(registry); specificationContext.setRegistrar(new SimpleComponentRegistrar(registry)); - // TODO SPR-7420: how to get hold of the current problem reporter here? - specificationContext.setProblemReporter(new FailFastProblemReporter()); + specificationContext.setProblemReporter(this.problemReporter); return specificationContext; } diff --git a/org.springframework.context/src/main/java/org/springframework/context/annotation/SimpleComponentRegistrar.java b/org.springframework.context/src/main/java/org/springframework/context/annotation/SimpleComponentRegistrar.java index 8b9ceb1e898..d812f2983c0 100644 --- a/org.springframework.context/src/main/java/org/springframework/context/annotation/SimpleComponentRegistrar.java +++ b/org.springframework.context/src/main/java/org/springframework/context/annotation/SimpleComponentRegistrar.java @@ -20,7 +20,6 @@ import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.parsing.BeanComponentDefinition; import org.springframework.beans.factory.parsing.ComponentDefinition; 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.BeanDefinitionRegistry; @@ -30,7 +29,7 @@ import org.springframework.beans.factory.support.BeanDefinitionRegistry; * @author Chris Beams * @since 3.1 */ -public class SimpleComponentRegistrar implements ComponentRegistrar { +class SimpleComponentRegistrar implements ComponentRegistrar { private final BeanDefinitionRegistry registry; @@ -39,7 +38,7 @@ public class SimpleComponentRegistrar implements ComponentRegistrar { } public String registerWithGeneratedName(BeanDefinition beanDefinition) { - return BeanDefinitionReaderUtils.registerWithGeneratedName((AbstractBeanDefinition)beanDefinition, this.registry); + return BeanDefinitionReaderUtils.registerWithGeneratedName(beanDefinition, this.registry); } public void registerBeanComponent(BeanComponentDefinition component) { diff --git a/org.springframework.context/src/main/java/org/springframework/context/config/AbstractSpecificationBeanDefinitionParser.java b/org.springframework.context/src/main/java/org/springframework/context/config/AbstractSpecificationBeanDefinitionParser.java new file mode 100644 index 00000000000..61756a97e85 --- /dev/null +++ b/org.springframework.context/src/main/java/org/springframework/context/config/AbstractSpecificationBeanDefinitionParser.java @@ -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; + } + +} diff --git a/org.springframework.integration-tests/src/test/java/org/springframework/context/annotation/FeatureTestSuite.java b/org.springframework.integration-tests/src/test/java/org/springframework/context/annotation/FeatureTestSuite.java index feb52c6196a..5531b325d2c 100644 --- a/org.springframework.integration-tests/src/test/java/org/springframework/context/annotation/FeatureTestSuite.java +++ b/org.springframework.integration-tests/src/test/java/org/springframework/context/annotation/FeatureTestSuite.java @@ -73,6 +73,7 @@ import org.springframework.web.servlet.config.MvcViewControllersTests; MvcResourcesTests.class, MvcDefaultServletHandlerTests.class, MvcNamespaceTests.class +}) */ public class FeatureTestSuite { diff --git a/org.springframework.transaction/src/main/java/org/springframework/transaction/config/AnnotationDrivenBeanDefinitionParser.java b/org.springframework.transaction/src/main/java/org/springframework/transaction/config/AnnotationDrivenBeanDefinitionParser.java index e849cdb80c2..f4b1de641d7 100644 --- a/org.springframework.transaction/src/main/java/org/springframework/transaction/config/AnnotationDrivenBeanDefinitionParser.java +++ b/org.springframework.transaction/src/main/java/org/springframework/transaction/config/AnnotationDrivenBeanDefinitionParser.java @@ -17,10 +17,9 @@ package org.springframework.transaction.config; 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.context.config.SpecificationContext; +import org.springframework.context.config.AbstractSpecificationBeanDefinitionParser; +import org.springframework.context.config.FeatureSpecification; import org.w3c.dom.Element; /** @@ -41,7 +40,7 @@ import org.w3c.dom.Element; * @since 2.0 * @see TxAnnotationDriven */ -class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser { +class AnnotationDrivenBeanDefinitionParser extends AbstractSpecificationBeanDefinitionParser { /** * 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} * with the container as necessary. */ - public BeanDefinition parse(Element element, ParserContext parserContext) { - new TxAnnotationDriven(element.getAttribute("transaction-manager")) + @Override + protected FeatureSpecification doParse(Element element, ParserContext parserContext) { + return new TxAnnotationDriven(element.getAttribute("transaction-manager")) .order(element.getAttribute("order")) .mode(element.getAttribute("mode")) - .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; + .proxyTargetClass(Boolean.valueOf(element.getAttribute("proxy-target-class"))); } } diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParser.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParser.java index 88a03de5bc5..9df3b5e135c 100644 --- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParser.java +++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParser.java @@ -16,12 +16,12 @@ 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.support.ManagedList; import org.springframework.beans.factory.xml.BeanDefinitionParser; 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.w3c.dom.Element; @@ -30,22 +30,18 @@ import org.w3c.dom.Element; * to configure a Spring MVC web application. * * @author Rossen Stoyanchev + * @author Chris Beams * @since 3.0 * @see MvcAnnotationDriven * @see MvcAnnotationDrivenExecutor */ -class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser { +class AnnotationDrivenBeanDefinitionParser extends AbstractSpecificationBeanDefinitionParser { /** * Parses the {@code } tag. */ - public BeanDefinition parse(Element element, ParserContext parserContext) { - MvcAnnotationDriven spec = createSpecification(element, parserContext); - spec.execute(createSpecificationContext(parserContext)); - return null; - } - - private MvcAnnotationDriven createSpecification(Element element, ParserContext parserContext) { + @Override + protected FeatureSpecification doParse(Element element, ParserContext parserContext) { MvcAnnotationDriven spec = new MvcAnnotationDriven(); if (element.hasAttribute("conversion-service")) { String conversionService = element.getAttribute("conversion-service"); @@ -70,8 +66,6 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser { spec.argumentResolvers(extractBeanSubElements(resolversElement, parserContext)); } - spec.source(parserContext.extractSource(element)); - spec.sourceName(element.getTagName()); return spec; } @@ -86,18 +80,4 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser { 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; - } - } diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/DefaultServletHandlerBeanDefinitionParser.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/DefaultServletHandlerBeanDefinitionParser.java index 030fada54a9..7efa18b5bcb 100644 --- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/DefaultServletHandlerBeanDefinitionParser.java +++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/DefaultServletHandlerBeanDefinitionParser.java @@ -16,10 +16,10 @@ 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.context.config.SpecificationContext; +import org.springframework.context.config.AbstractSpecificationBeanDefinitionParser; +import org.springframework.context.config.FeatureSpecification; import org.springframework.util.StringUtils; import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping; import org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter; @@ -31,40 +31,21 @@ import org.w3c.dom.Element; * register a {@link DefaultServletHttpRequestHandler}. Will also register a * {@link SimpleUrlHandlerMapping} for mapping resource requests, and a * {@link HttpRequestHandlerAdapter} if necessary. - * + * * @author Rossen Stoyanchev + * @author Chris Beams * @since 3.0.4 */ -class DefaultServletHandlerBeanDefinitionParser implements BeanDefinitionParser { +class DefaultServletHandlerBeanDefinitionParser extends AbstractSpecificationBeanDefinitionParser { /** * Parses the {@code } tag. */ - public BeanDefinition parse(Element element, ParserContext parserContext) { - MvcDefaultServletHandler spec = createSpecification(element, parserContext); - spec.execute(createSpecificationContext(parserContext)); - return null; - } - - private MvcDefaultServletHandler createSpecification(Element element, ParserContext parserContext) { + public FeatureSpecification doParse(Element element, ParserContext parserContext) { String defaultServletHandler = element.getAttribute("default-servlet-handler"); - MvcDefaultServletHandler spec = StringUtils.hasText(defaultServletHandler) ? new MvcDefaultServletHandler( - defaultServletHandler) : new MvcDefaultServletHandler(); - 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; + return StringUtils.hasText(defaultServletHandler) ? + new MvcDefaultServletHandler(defaultServletHandler) : + new MvcDefaultServletHandler(); } } diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/MvcDefaultServletHandlerExecutor.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/MvcDefaultServletHandlerExecutor.java index 19f8074d6c6..aa57d5abb49 100644 --- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/MvcDefaultServletHandlerExecutor.java +++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/MvcDefaultServletHandlerExecutor.java @@ -57,7 +57,7 @@ final class MvcDefaultServletHandlerExecutor extends AbstractSpecificationExecut registry.registerBeanDefinition(HANDLER_ADAPTER_BEAN_NAME, handlerAdapterDef); registrar.registerComponent(new BeanComponentDefinition(handlerAdapterDef, HANDLER_ADAPTER_BEAN_NAME)); } - + RootBeanDefinition defaultServletHandlerDef = new RootBeanDefinition(DefaultServletHttpRequestHandler.class); defaultServletHandlerDef.setSource(source); defaultServletHandlerDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/ResourcesBeanDefinitionParser.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/ResourcesBeanDefinitionParser.java index 3ff959a9cf2..058652afcf2 100644 --- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/ResourcesBeanDefinitionParser.java +++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/ResourcesBeanDefinitionParser.java @@ -16,10 +16,9 @@ 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.context.config.SpecificationContext; +import org.springframework.context.config.AbstractSpecificationBeanDefinitionParser; +import org.springframework.context.config.FeatureSpecification; import org.springframework.util.StringUtils; import org.w3c.dom.Element; @@ -32,32 +31,16 @@ import org.w3c.dom.Element; * @see MvcResources * @see MvcResourcesExecutor */ -class ResourcesBeanDefinitionParser implements BeanDefinitionParser { +class ResourcesBeanDefinitionParser extends AbstractSpecificationBeanDefinitionParser { /** * Parses the {@code } tag */ - public BeanDefinition parse(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) { + public FeatureSpecification doParse(Element element, ParserContext parserContext) { String mapping = element.getAttribute("mapping"); - if (!StringUtils.hasText(mapping)) { - parserContext.getReaderContext().error("The 'mapping' attribute is required.", - 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; - } + String[] locations = + StringUtils.commaDelimitedListToStringArray(element.getAttribute("location")); + MvcResources spec = new MvcResources(mapping, locations); if (element.hasAttribute("cache-period")) { spec.cachePeriod(element.getAttribute("cache-period")); @@ -65,23 +48,8 @@ class ResourcesBeanDefinitionParser implements BeanDefinitionParser { if (element.hasAttribute("order")) { spec.order(element.getAttribute("order")); } - spec.source(parserContext.extractSource(element)); - spec.sourceName(element.getTagName()); + 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; - } - } diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/ViewControllerBeanDefinitionParser.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/ViewControllerBeanDefinitionParser.java index 01dc34416fe..5c6f3293be7 100644 --- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/ViewControllerBeanDefinitionParser.java +++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/ViewControllerBeanDefinitionParser.java @@ -16,10 +16,9 @@ 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.context.config.SpecificationContext; +import org.springframework.context.config.AbstractSpecificationBeanDefinitionParser; +import org.springframework.context.config.FeatureSpecification; import org.springframework.web.servlet.mvc.ParameterizableViewController; import org.w3c.dom.Element; @@ -32,33 +31,15 @@ import org.w3c.dom.Element; * @see MvcViewControllers * @see MvcViewControllersExecutor */ -class ViewControllerBeanDefinitionParser implements BeanDefinitionParser { +class ViewControllerBeanDefinitionParser extends AbstractSpecificationBeanDefinitionParser { /** * Parses the {@code } tag. */ - public BeanDefinition parse(Element element, ParserContext parserContext) { + public FeatureSpecification doParse(Element element, ParserContext parserContext) { String path = element.getAttribute("path"); String viewName = element.getAttribute("view-name"); - 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; + return new MvcViewControllers(path, viewName.isEmpty() ? null : viewName); } }