Don't like ads? PRO users don't see any ads ;-)
Guest

Untitled

By: a guest on Apr 13th, 2012  |  syntax: None  |  size: 9.37 KB  |  hits: 18  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. /*
  2.  * Copyright 2002-2010 the original author or authors.
  3.  *
  4.  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
  5.  * the License. You may obtain a copy of the License at
  6.  *
  7.  * http://www.apache.org/licenses/LICENSE-2.0
  8.  *
  9.  * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
  10.  * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
  11.  * specific language governing permissions and limitations under the License.
  12.  */
  13. package org.springframework.bootstrap.config;
  14.  
  15. import java.lang.reflect.Field;
  16.  
  17. import org.springframework.beans.BeansException;
  18. import org.springframework.beans.factory.BeanFactory;
  19. import org.springframework.beans.factory.DisposableBean;
  20. import org.springframework.beans.factory.NoSuchBeanDefinitionException;
  21. import org.springframework.beans.factory.config.BeanDefinition;
  22. import org.springframework.beans.factory.parsing.ComponentRegistrarAdapter;
  23. import org.springframework.beans.factory.parsing.ProblemReporter;
  24. import org.springframework.beans.factory.parsing.ReaderContext;
  25. import org.springframework.beans.factory.support.BeanDefinitionBuilder;
  26. import org.springframework.beans.factory.support.BeanDefinitionRegistry;
  27. import org.springframework.beans.factory.xml.BeanDefinitionParser;
  28. import org.springframework.beans.factory.xml.BeanDefinitionParserDelegate;
  29. import org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader;
  30. import org.springframework.beans.factory.xml.ParserContext;
  31. import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
  32. import org.springframework.beans.factory.xml.XmlReaderContext;
  33. import org.springframework.context.ConfigurableApplicationContext;
  34. import org.springframework.context.Lifecycle;
  35. import org.springframework.context.config.FeatureSpecification;
  36. import org.springframework.context.config.SpecificationContext;
  37. import org.springframework.context.support.GenericApplicationContext;
  38. import org.springframework.core.env.ConfigurableEnvironment;
  39. import org.springframework.core.env.DefaultEnvironment;
  40. import org.springframework.core.env.Environment;
  41. import org.springframework.core.io.Resource;
  42. import org.springframework.util.StringUtils;
  43. import org.springframework.util.xml.DomUtils;
  44. import org.w3c.dom.Document;
  45. import org.w3c.dom.Element;
  46.  
  47. /**
  48.  * @author Dave Syer
  49.  *
  50.  */
  51. public class GenericFeatureSpecificationParser implements BeanDefinitionParser {
  52.  
  53.         /** Constant for the id attribute */
  54.         public static final String ID_ATTRIBUTE = "id";
  55.  
  56.         /** Constant for the expose-features attribute */
  57.         private static final String EXPOSE_FEATURES_ATTRIBUTE = "expose-features";
  58.  
  59.         public BeanDefinition parse(Element element, ParserContext parserContext) {
  60.  
  61.                 final GenericApplicationContext bootstrapApplicationContext = new GenericApplicationContext();
  62.  
  63.                 Environment environment = parserContext.getDelegate().getEnvironment();
  64.                 if (environment instanceof ConfigurableEnvironment) {
  65.                         bootstrapApplicationContext.setEnvironment((ConfigurableEnvironment) environment);
  66.                 }
  67.  
  68.                 registerBootstrapApplicationContext(bootstrapApplicationContext, element, parserContext);
  69.  
  70.                 registerBeanDefinitionsInBootstrapApplicationContext(bootstrapApplicationContext, element, parserContext);
  71.  
  72.                 bootstrapApplicationContext.refresh();
  73.  
  74.                 if ("true".equals(element.getAttribute(EXPOSE_FEATURES_ATTRIBUTE))) {
  75.                         exposeFeatures(bootstrapApplicationContext, parserContext);
  76.                 }
  77.  
  78.                 return null;
  79.  
  80.         }
  81.  
  82.         /**
  83.          * Copied from AbstractSpecificationBeanDefinitionParser. Adapt the given ParserContext into a SpecificationContext.
  84.          */
  85.         private static SpecificationContext specificationContextFrom(ParserContext parserContext) {
  86.                 SpecificationContext specContext = new SpecificationContext();
  87.                 specContext.setRegistry(parserContext.getRegistry());
  88.                 specContext.setRegistrar(new ComponentRegistrarAdapter(parserContext));
  89.                 specContext.setResourceLoader(parserContext.getReaderContext().getResourceLoader());
  90.                 try {
  91.                         // again, STS constraints around the addition of the new getEnvironment()
  92.                         // method in 3.1.0 (it's not present in STS current spring version, 3.0.5)
  93.                         // TODO 3.1 GA: remove this block prior to 3.1 GA
  94.                         specContext.setEnvironment(parserContext.getDelegate().getEnvironment());
  95.                 } catch (NoSuchMethodError ex) {
  96.                         specContext.setEnvironment(new DefaultEnvironment());
  97.                 }
  98.                 try {
  99.                         // access the reader context's problem reporter reflectively in order to
  100.                         // compensate for tooling (STS) constraints around introduction of changes
  101.                         // to parser context / reader context classes.
  102.                         // TODO 3.1 GA: remove this block prior to 3.1 GA
  103.                         Field field = ReaderContext.class.getDeclaredField("problemReporter");
  104.                         field.setAccessible(true);
  105.                         ProblemReporter problemReporter = (ProblemReporter) field.get(parserContext.getReaderContext());
  106.                         specContext.setProblemReporter(problemReporter);
  107.                 } catch (Exception ex) {
  108.                         throw new IllegalStateException("Could not access field 'ReaderContext#problemReporter' on object "
  109.                                         + parserContext.getReaderContext(), ex);
  110.                 }
  111.                 return specContext;
  112.         }
  113.  
  114.         public void registerBootstrapApplicationContext(final GenericApplicationContext context, Element element,
  115.                         ParserContext parserContext) {
  116.  
  117.                 BeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(ContextHolder.class)
  118.                                 .addConstructorArgValue(context).getBeanDefinition();
  119.  
  120.                 String id = element.getAttribute(ID_ATTRIBUTE);
  121.                 String beanName = parserContext.getReaderContext().generateBeanName(beanDefinition);
  122.                 if (StringUtils.hasText(id)) {
  123.                         context.setId(id);
  124.                         beanName = id;
  125.                 }
  126.  
  127.                 parserContext.getRegistry().registerBeanDefinition(beanName, beanDefinition);
  128.  
  129.         }
  130.  
  131.         public void exposeFeatures(final GenericApplicationContext context, ParserContext parserContext) {
  132.  
  133.                 SpecificationContext specificationContext = specificationContextFrom(parserContext);
  134.  
  135.                 for (FeatureSpecification specification : context.getBeansOfType(FeatureSpecification.class).values()) {
  136.                         specification.execute(specificationContext);
  137.                 }
  138.  
  139.         }
  140.  
  141.         private void registerBeanDefinitionsInBootstrapApplicationContext(BeanDefinitionRegistry registry, Element element,
  142.                         ParserContext parserContext) {
  143.                 LocalXmlBeanDefinitionReader beanDefinitionReader = new LocalXmlBeanDefinitionReader( //
  144.                                 registry, //
  145.                                 parserContext.getDelegate().getEnvironment(), //
  146.                                 parserContext.getReaderContext().getResource()//
  147.                 );
  148.                 beanDefinitionReader.register(element);
  149.         }
  150.  
  151.         private static class LocalXmlBeanDefinitionReader extends XmlBeanDefinitionReader {
  152.  
  153.                 private Resource resource;
  154.  
  155.                 public LocalXmlBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment, Resource resource) {
  156.                         super(registry);
  157.                         this.resource = resource;
  158.                         setEnvironment(environment);
  159.                 }
  160.  
  161.                 public void register(Element element) {
  162.                         XmlReaderContext readerContext = createReaderContext(resource);
  163.                         LocalBeanDefinitionDocumentReader documentReader = new LocalBeanDefinitionDocumentReader(
  164.                                         this.getEnvironment());
  165.                         documentReader.registerBeanDefinitions(element, readerContext);
  166.                 }
  167.  
  168.         }
  169.  
  170.         private static class LocalBeanDefinitionDocumentReader extends DefaultBeanDefinitionDocumentReader {
  171.  
  172.                 public LocalBeanDefinitionDocumentReader(Environment environment) {
  173.                         super.setEnvironment(environment);
  174.                 }
  175.  
  176.                 public void registerBeanDefinitions(Element element, XmlReaderContext readerContext) {
  177.                         try {
  178.                                 registerBeanDefinitions((Document) null, readerContext);
  179.                         } catch (NullPointerException e) {
  180.                                 // Hack: ignore
  181.                         }
  182.                         BeanDefinitionParserDelegate delegate = createHelper(readerContext, element, null);
  183.                         for (Element child : DomUtils.getChildElements(element)) {
  184.                                 if ("bean".equals(child.getNodeName())) {
  185.                                         processBeanDefinition(child, delegate);
  186.                                 } else {
  187.                                         doRegisterBeanDefinitions(child);
  188.                                 }
  189.                         }
  190.                 }
  191.  
  192.         }
  193.  
  194.         private static class ContextHolder implements BeanFactory, Lifecycle, DisposableBean {
  195.  
  196.                 final ConfigurableApplicationContext context;
  197.  
  198.                 @SuppressWarnings("unused")
  199.                 public ContextHolder(ConfigurableApplicationContext context) {
  200.                         super();
  201.                         this.context = context;
  202.                 }
  203.  
  204.                 public void destroy() throws Exception {
  205.                         context.close();
  206.                 }
  207.  
  208.                 public void start() {
  209.                         context.start();
  210.                 }
  211.  
  212.                 public void stop() {
  213.                         context.stop();
  214.                 }
  215.  
  216.                 public boolean isRunning() {
  217.                         return context.isRunning();
  218.                 }
  219.  
  220.                 public Object getBean(String name) throws BeansException {
  221.                         return context.getBean(name);
  222.                 }
  223.  
  224.                 public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
  225.                         return context.getBean(name, requiredType);
  226.                 }
  227.  
  228.                 public <T> T getBean(Class<T> requiredType) throws BeansException {
  229.                         return context.getBean(requiredType);
  230.                 }
  231.  
  232.                 public Object getBean(String name, Object... args) throws BeansException {
  233.                         return context.getBean(name, args);
  234.                 }
  235.  
  236.                 public boolean containsBean(String name) {
  237.                         return context.containsBean(name);
  238.                 }
  239.  
  240.                 public boolean isSingleton(String name) throws NoSuchBeanDefinitionException {
  241.                         return context.isSingleton(name);
  242.                 }
  243.  
  244.                 public boolean isTypeMatch(String name, Class<?> targetType) throws NoSuchBeanDefinitionException {
  245.                         return context.isTypeMatch(name, targetType);
  246.                 }
  247.  
  248.                 public String[] getAliases(String name) {
  249.                         return context.getAliases(name);
  250.                 }
  251.  
  252.                 public boolean isPrototype(String name) throws NoSuchBeanDefinitionException {
  253.                         return context.isPrototype(name);
  254.                 }
  255.  
  256.                 public Class<?> getType(String name) throws NoSuchBeanDefinitionException {
  257.                         return context.getType(name);
  258.                 }
  259.  
  260.         }
  261.  
  262. }