View Javadoc

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