View Javadoc

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