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.assembly;
8   
9   import org.mule.config.spring.MuleHierarchicalBeanDefinitionParserDelegate;
10  import org.mule.config.spring.parsers.assembly.configuration.PropertyConfiguration;
11  
12  import org.springframework.beans.factory.config.BeanDefinition;
13  import org.springframework.beans.factory.support.BeanDefinitionBuilder;
14  
15  /**
16   * This is used by {@link org.mule.config.spring.parsers.delegate.MapDefinitionParserMutator} - it takes
17   * a normal bean definition and re-packages it as a map (rather than individual values).  The difference
18   * between this and {@link org.mule.config.spring.parsers.assembly.AttributeMapBeanAssemblerFactory} is
19   * that this allows child elements to generate the properties (it's an ugly consequence of the fact that
20   * BDPs are called before nested children - this is a hack that gets "re-called" after the children to
21   * complete the work).
22   */
23  public class TwoStageMapBeanAssembler extends AbstractMapBeanAssembler
24  {
25  
26      private TwoStageMapBeanAssemblerFactory.BeanAssemblerStore store;
27  
28      public TwoStageMapBeanAssembler(TwoStageMapBeanAssemblerFactory.BeanAssemblerStore store,
29              PropertyConfiguration beanConfig, BeanDefinitionBuilder bean,
30              PropertyConfiguration targetConfig, BeanDefinition target)
31      {
32          super(beanConfig, bean, targetConfig, target);
33          this.store = store;
34      }
35  
36      /**
37       * We overwrite this method to populate a map instead of inserting the definition.
38       * However, the bean definition is not complete until all child elements have been
39       * parsed - and that parsing happens after this routine is called.  So on first
40       * pass we set a flag in the definition.  This is picked up by the main
41       * driver loop ({@link org.mule.config.spring.MuleHierarchicalBeanDefinitionParserDelegate})
42       * and our enclosing bean definition parser is called again.  At the same time, to
43       * avoid complicating otherwise "normal" BDPs, we pass this assembler to a callback,
44       * so that it can be called the second time in a more direct way.
45       */
46      public void insertBeanInTarget(String oldName)
47      {
48          assertTargetPresent();
49  
50          if (MuleHierarchicalBeanDefinitionParserDelegate.testFlag(getBean().getBeanDefinition(),
51                  MuleHierarchicalBeanDefinitionParserDelegate.MULE_POST_CHILDREN))
52          {
53              insertDefinitionAsMap(oldName);
54          }
55          else
56          {
57              // called for the first time, so set the flag and store this assembler for
58              // later processing
59              MuleHierarchicalBeanDefinitionParserDelegate.setFlag(getBean().getBeanDefinition(),
60                      MuleHierarchicalBeanDefinitionParserDelegate.MULE_POST_CHILDREN);
61              store.saveBeanAssembler(this);
62          }
63      }
64  
65  }