View Javadoc
1   /*
2    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
3    * The software in this package is published under the terms of the CPAL v1.0
4    * license, a copy of which has been included with this distribution in the
5    * LICENSE.txt file.
6    */
7   package org.mule.config.spring.parsers.generic;
8   
9   import org.mule.config.spring.MuleHierarchicalBeanDefinitionParserDelegate;
10  import org.mule.config.spring.parsers.AbstractHierarchicalDefinitionParser;
11  import org.mule.config.spring.parsers.assembly.BeanAssembler;
12  
13  import org.springframework.beans.factory.config.BeanDefinition;
14  import org.springframework.beans.factory.support.AbstractBeanDefinition;
15  import org.springframework.beans.factory.support.BeanDefinitionBuilder;
16  import org.springframework.beans.factory.xml.ParserContext;
17  import org.springframework.util.Assert;
18  import org.w3c.dom.Element;
19  
20  /**
21   * Processes child property elements in Xml but sets the properties on the parent object.  This is
22   * useful when an object has lots of properties and it's more readable to break those properties into
23   * groups that can be represented as a sub-element in Xml.
24   */
25  public class ParentDefinitionParser extends AbstractHierarchicalDefinitionParser
26  {
27  
28      public ParentDefinitionParser()
29      {
30          addBeanFlag(MuleHierarchicalBeanDefinitionParserDelegate.MULE_NO_REGISTRATION);
31      }
32  
33      protected Class getBeanClass(Element element)
34      {
35          try
36          {
37              return Class.forName(getParentBeanDefinition(element).getBeanClassName());
38          }
39          catch (Exception e)
40          {
41              // Should continue to work, but automatic collection detection etc will fail
42              logger.debug("No class for " + element);
43              return Object.class;
44          }
45      }
46  
47      protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext)
48      {
49          preProcess(element);
50          setParserContext(parserContext);
51          setRegistry(parserContext.getRegistry());
52          Class beanClass = getBeanClass(element);
53          Assert.state(beanClass != null, "Class returned from getBeanClass(Element) must not be null, element is: " + element.getNodeName());
54          BeanDefinitionBuilder builder = createBeanDefinitionBuilder(element, beanClass);
55          builder.getRawBeanDefinition().setSource(parserContext.extractSource(element));
56          if (parserContext.isNested())
57          {
58              // Inner bean definition must receive same singleton status as containing bean.
59              builder.setScope(parserContext.getContainingBeanDefinition().isSingleton()
60                  ? BeanDefinition.SCOPE_SINGLETON : BeanDefinition.SCOPE_PROTOTYPE);
61          }
62          doParse(element, parserContext, builder);
63          BeanAssembler beanAssembler = getBeanAssembler(element, builder);
64          beanAssembler.copyBeanToTarget();
65          return (AbstractBeanDefinition) beanAssembler.getTarget();
66      }
67  
68      protected void postProcess(ParserContext context, BeanAssembler assembler, Element element)
69      {
70          // by default the name matches the "real" bean
71          if (null == element.getAttributeNode(ATTRIBUTE_NAME))
72          {
73              element.setAttribute(ATTRIBUTE_NAME, getParentBeanName(element));
74          }
75          super.postProcess(context, assembler, element);
76      }
77  
78  }