View Javadoc

1   /*
2    * $Id: AbstractChildDefinitionParser.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.generic.AutoIdUtils;
14  import org.mule.config.spring.util.SpringXMLUtils;
15  import org.mule.util.StringUtils;
16  
17  import org.springframework.beans.factory.config.BeanDefinition;
18  import org.springframework.beans.factory.config.RuntimeBeanReference;
19  import org.springframework.beans.factory.support.BeanDefinitionBuilder;
20  import org.springframework.beans.factory.xml.ParserContext;
21  import org.w3c.dom.Element;
22  
23  /**
24   * This definition parser supports the definition of beans that are then set on the parent bean -
25   * it extends {@link org.mule.config.spring.parsers.AbstractHierarchicalDefinitionParser} with
26   * methods that assume the data are associated with a single property.
27   *
28   * This supports collections and Maps. For collections if a child element is repeated it will be assumed
29   * that it is a collection.
30   *
31   * If the Bean Class for this element is set to
32   * {@link org.mule.config.spring.parsers.collection.ChildMapEntryDefinitionParser.KeyValuePair} it is assumed that a Map
33   * is being processed and any child elements will be added to the parent Map.  Similarly for
34   * {@link org.mule.config.spring.parsers.collection.ChildListEntryDefinitionParser}.
35   *
36   * A single method needs to be overriden called {@link #getPropertyName} that determines the name of the property to
37   * set on the parent bean with this bean. Note that the property name can be dynamically resolved depending on the parent
38   * element.
39   *
40   * @see org.mule.config.spring.parsers.generic.ChildDefinitionParser
41   * @see org.mule.config.spring.parsers.collection.ChildMapEntryDefinitionParser.KeyValuePair
42   * @see AbstractMuleBeanDefinitionParser
43   */
44  public abstract class AbstractChildDefinitionParser
45          extends AbstractHierarchicalDefinitionParser
46          implements MuleChildDefinitionParser
47  {
48  
49      protected final void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder)
50      {
51          setRegistry(parserContext.getRegistry());
52          parseChild(element, parserContext, builder);
53      }
54  
55      protected void parseChild(Element element, ParserContext parserContext, BeanDefinitionBuilder builder)
56      {
57          builder.setScope(isSingleton() ? BeanDefinition.SCOPE_SINGLETON : BeanDefinition.SCOPE_PROTOTYPE);
58          super.doParse(element, parserContext, builder);
59      }
60  
61      protected void postProcess(ParserContext context, BeanAssembler assembler, Element element)
62      {
63          super.postProcess(context, assembler, element);
64  
65          // legacy handling of orphan beans - avoid setting parent
66          String propertyName = getPropertyName(element);
67          if (null != propertyName)
68          {
69              // If this is a singleton we need to inject it into parent using a
70              // RuntimeBeanReference so that the bean does not get created twice, once
71              // with a name and once as an (inner bean).
72              if (!assembler.getBean().getBeanDefinition().isSingleton())
73              {
74                  assembler.insertBeanInTarget(propertyName);
75              }
76              else
77              {
78                  assembler.insertSingletonBeanInTarget(propertyName,
79                      element.getAttribute(AbstractMuleBeanDefinitionParser.ATTRIBUTE_NAME));
80              }
81          }
82      }
83  
84      public String getBeanName(Element e)
85      {
86          String name = SpringXMLUtils.getNameOrId(e);
87          if (StringUtils.isBlank(name))
88          {
89              String parentId = getParentBeanName(e);
90              if (!parentId.startsWith("."))
91              {
92                  parentId = "." + parentId;
93              }
94              return AutoIdUtils.uniqueValue(parentId + ":" + e.getLocalName());
95          }
96          else
97          {
98              return name;
99          }
100     }
101 
102     public abstract String getPropertyName(Element element);
103 
104 }