View Javadoc

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