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;
8   
9   import org.mule.config.spring.parsers.assembly.BeanAssembler;
10  import org.mule.config.spring.parsers.assembly.configuration.PropertyConfiguration;
11  import org.mule.config.spring.parsers.assembly.configuration.ReusablePropertyConfiguration;
12  import org.mule.config.spring.parsers.assembly.configuration.TempWrapperPropertyConfiguration;
13  import org.mule.config.spring.util.SpringXMLUtils;
14  import org.mule.util.StringUtils;
15  
16  import org.springframework.beans.factory.config.BeanDefinition;
17  import org.springframework.beans.factory.support.BeanDefinitionBuilder;
18  import org.springframework.beans.factory.xml.ParserContext;
19  import org.w3c.dom.Element;
20  
21  /**
22   * This definition parser introduces the notion of Hierarchical processing to nested XML elements. Definition
23   * parsers that extend this can refer to parent beans.  It does not assume that the parser is restricted
24   * to a single property.
25   *
26   * Calling classes must set the registry at the start of processing.
27   *
28   * @see org.mule.config.spring.parsers.generic.ChildDefinitionParser
29   * @see org.mule.config.spring.parsers.collection.ChildMapEntryDefinitionParser.KeyValuePair
30   * @see org.mule.config.spring.parsers.AbstractMuleBeanDefinitionParser
31   */
32  public abstract class AbstractHierarchicalDefinitionParser extends AbstractMuleBeanDefinitionParser
33  {
34  
35      private ReusablePropertyConfiguration targetPropertyConfiguration =
36              new ReusablePropertyConfiguration(
37                      new TempWrapperPropertyConfiguration(beanPropertyConfiguration, false));
38      private BeanDefinition forcedParent = null;
39  
40      public PropertyConfiguration getTargetPropertyConfiguration()
41      {
42          return targetPropertyConfiguration;
43      }
44  
45      protected String getParentBeanName(Element element)
46      {
47          return ((Element) element.getParentNode()).getAttribute(ATTRIBUTE_NAME);
48      }
49  
50      public BeanDefinition getParentBeanDefinition(Element element)
51      {
52          if (null != forcedParent)
53          {
54              return forcedParent;
55          }
56          else
57          {
58              String parentBean = getParentBeanName(element);
59              if (StringUtils.isBlank(parentBean))
60              {
61                  throw new IllegalStateException("No parent for " + SpringXMLUtils.elementToString(element));
62              }
63              return getRegistry().getBeanDefinition(parentBean);
64          }
65      }
66  
67      /**
68       * The bean assembler gives more reliable/automatic processing of collections, maps, etc.
69       *
70       * @param element The current element
71       * @param bean The bean being constructed
72       * @return An assembler that includes Mule-specific construction logic
73       */
74      protected BeanAssembler getBeanAssembler(Element element, BeanDefinitionBuilder bean)
75      {
76          BeanDefinition target = getParentBeanDefinition(element);
77          return getBeanAssemblerFactory().newBeanAssembler(
78                  beanPropertyConfiguration, bean, targetPropertyConfiguration, target);
79      }
80  
81      /**
82       * Provide access to bean assembler from non-hierarchical case.  Legacy support for
83       * "mixed" definition parsers.
84       *
85       * @deprecated
86       * @param element
87       * @param bean
88       */
89      protected BeanAssembler getOrphanBeanAssembler(Element element, BeanDefinitionBuilder bean)
90      {
91          return super.getBeanAssembler(element, bean);
92      }
93  
94      public void forceParent(BeanDefinition parent)
95      {
96          forcedParent = parent;
97      }
98  
99      protected void preProcess(Element element)
100     {
101         super.preProcess(element);
102         targetPropertyConfiguration.reset();
103     }
104 
105     // reset the forced parent
106     protected void postProcess(ParserContext context, BeanAssembler assembler, Element element)
107     {
108         super.postProcess(context, assembler, element);
109         forcedParent = null;
110     }
111     
112 }