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