View Javadoc

1   /*
2    * $Id: MapDefinitionParserMutator.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.delegate;
12  
13  import org.mule.config.spring.parsers.MuleChildDefinitionParser;
14  import org.mule.config.spring.parsers.MuleDefinitionParser;
15  import org.mule.config.spring.parsers.assembly.BeanAssembler;
16  import org.mule.config.spring.parsers.assembly.TwoStageMapBeanAssemblerFactory;
17  import org.mule.config.spring.parsers.assembly.configuration.PropertyConfiguration;
18  import org.mule.config.spring.parsers.generic.ChildDefinitionParser;
19  
20  import java.util.HashMap;
21  import java.util.Map;
22  
23  import org.springframework.beans.factory.config.BeanDefinition;
24  import org.springframework.beans.factory.support.AbstractBeanDefinition;
25  import org.springframework.beans.factory.xml.ParserContext;
26  import org.w3c.dom.Element;
27  
28  /**
29   * This changes a {@link org.mule.config.spring.parsers.generic.ChildDefinitionParser}
30   * so that it generates a map instead of a bean definition.  This is useful for converting
31   * parsers to work with the object factory (which requires a map).
32   */
33  public class MapDefinitionParserMutator
34          extends AbstractDelegatingDefinitionParser
35          implements TwoStageMapBeanAssemblerFactory.BeanAssemblerStore, MuleChildDefinitionParser
36  {
37  
38      private String setter;
39      private Element currentElement;
40      private Map pendingAssemblers = new HashMap();
41  
42      public MapDefinitionParserMutator(String setter, ChildDefinitionParser delegate)
43      {
44          super(new MuleDefinitionParser[]{delegate});
45          this.setter = setter;
46          // this is where we set the callback
47          delegate.setBeanAssemblerFactory(new TwoStageMapBeanAssemblerFactory(this));
48      }
49  
50      public AbstractBeanDefinition muleParse(Element element, ParserContext parserContext)
51      {
52          if (pendingAssemblers.containsKey(element))
53          {
54              // this is the second call, after the children have been processed
55              BeanAssembler beanAssembler = (BeanAssembler) pendingAssemblers.get(element);
56              pendingAssemblers.remove(element);
57              beanAssembler.insertBeanInTarget(setter);
58              return null;
59          }
60          else
61          {
62              // first call, so process in normal manner, but set current element so that
63              // when the store callback is called, we can associate the assembler with this
64              // element
65              currentElement = element;
66              return getChildDelegate().muleParse(element, parserContext);
67          }
68      }
69  
70      public void saveBeanAssembler(BeanAssembler beanAssembler)
71      {
72          // this is called by the bean assembler from inside parseDelegate above.
73          pendingAssemblers.put(currentElement, beanAssembler);
74      }
75  
76      protected ChildDefinitionParser getChildDelegate()
77      {
78          return (ChildDefinitionParser) getDelegate(0);
79      }
80  
81      public void forceParent(BeanDefinition parent)
82      {
83          getChildDelegate().forceParent(parent);
84      }
85  
86      public PropertyConfiguration getTargetPropertyConfiguration()
87      {
88          return getChildDelegate().getTargetPropertyConfiguration();
89      }
90  
91  }