View Javadoc

1   /*
2    * $Id: WrappingChildDefinitionParser.java 20320 2010-11-24 15:03:31Z 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.generic;
12  
13  import org.mule.config.spring.parsers.assembly.BeanAssembler;
14  import org.mule.config.spring.parsers.assembly.BeanAssemblerFactory;
15  import org.mule.config.spring.parsers.assembly.DefaultBeanAssembler;
16  import org.mule.config.spring.parsers.assembly.DefaultBeanAssemblerFactory;
17  import org.mule.config.spring.parsers.assembly.configuration.PropertyConfiguration;
18  import org.springframework.beans.MutablePropertyValues;
19  import org.springframework.beans.PropertyValue;
20  import org.springframework.beans.factory.config.BeanDefinition;
21  import org.springframework.beans.factory.support.BeanDefinitionBuilder;
22  import org.springframework.beans.factory.support.ManagedList;
23  import org.w3c.dom.Element;
24  
25  import java.util.List;
26  
27  /**
28   * A child definition parser that wraps the child object
29   */
30  public class WrappingChildDefinitionParser extends ChildDefinitionParser
31  {
32      private final Class wrapperClass;
33      private final String propertyNameInWrapper;
34      private final String unwrappedPropertyName;
35      private final WrappingController wrappingController;
36  
37      public WrappingChildDefinitionParser(String setterMethod,
38                                           Class clazz,
39                                           Class constraint,
40                                           boolean allowClassAttribute,
41                                           Class wrapperClass,
42                                           String propertyNameInWrapper,
43                                           String unwrappedPropertyName,
44                                           WrappingController wrappingController)
45      {
46          super(setterMethod, clazz, constraint, allowClassAttribute);
47          this.wrapperClass = wrapperClass;
48          this.propertyNameInWrapper = propertyNameInWrapper;
49          this.unwrappedPropertyName = unwrappedPropertyName;
50          this.wrappingController = wrappingController;
51      }
52  
53      @Override
54      public String getPropertyName(Element
55          e)
56      {
57          if (!wrappingController.shouldWrap(e))
58          {
59              return unwrappedPropertyName;
60          }
61          else
62          {
63              return super.getPropertyName(e);
64          }
65      }
66  
67      @Override
68      protected void preProcess(Element
69          element)
70      {
71          super.preProcess(element);
72          if (wrappingController.shouldWrap(element))
73          {
74              setBeanAssemblerFactory(new MessageProcessorWrappingBeanAssemblerFactory(wrapperClass, propertyNameInWrapper));
75          }
76          else
77          {
78              setBeanAssemblerFactory(new DefaultBeanAssemblerFactory());
79          }
80      }
81  
82      /**
83       * Determines whether to wrap the child based on the where it appears in the DOM.
84       */
85      public interface WrappingController
86      {
87          boolean shouldWrap(Element elm);
88      }
89  
90      private static class MessageProcessorWrappingBeanAssemblerFactory implements BeanAssemblerFactory
91      {
92          private final Class wrapperClass;
93          private final String propertyNameInWrapper;
94  
95          public MessageProcessorWrappingBeanAssemblerFactory(Class wrapperClass, String propertyNameInWrapper)
96          {
97              this.wrapperClass = wrapperClass;
98              this.propertyNameInWrapper = propertyNameInWrapper;
99          }
100 
101         public BeanAssembler newBeanAssembler(PropertyConfiguration beanConfig,
102                                               BeanDefinitionBuilder bean,
103                                               PropertyConfiguration targetConfig,
104                                               BeanDefinition target)
105         {
106             return new MessageProcessorWrappingBeanAssembler(beanConfig, bean, targetConfig, target, wrapperClass, propertyNameInWrapper);
107         }
108     }
109 
110     private static class MessageProcessorWrappingBeanAssembler extends DefaultBeanAssembler
111     {
112         private final Class wrapperClass;
113         private final String propertyNameInWrapper;
114 
115         public MessageProcessorWrappingBeanAssembler(PropertyConfiguration beanConfig,
116                                                      BeanDefinitionBuilder bean,
117                                                      PropertyConfiguration targetConfig,
118                                                      BeanDefinition target,
119                                                      Class wrapperClass,
120                                                      String propertyNameInWrapper)
121         {
122             super(beanConfig, bean, targetConfig, target);
123             this.wrapperClass = wrapperClass;
124             this.propertyNameInWrapper = propertyNameInWrapper;
125         }
126 
127         public void insertBeanInTarget(String oldName)
128         {
129             assertTargetPresent();
130             String newName = bestGuessName(targetConfig, oldName, target.getBeanClassName());
131             MutablePropertyValues targetProperties = target.getPropertyValues();
132             PropertyValue pv = targetProperties.getPropertyValue(newName);
133             Object oldValue = null == pv ? null : pv.getValue();
134 
135             BeanDefinitionBuilder wrapper = BeanDefinitionBuilder.genericBeanDefinition(wrapperClass);
136             wrapper.addPropertyValue(propertyNameInWrapper, bean.getBeanDefinition());
137 
138             if (oldValue == null)
139             {
140                 oldValue = new ManagedList();
141                 pv = new PropertyValue(newName, oldValue);
142                 targetProperties.addPropertyValue(pv);
143             }
144             if (targetConfig.isCollection(oldName))
145             {
146                 List list = retrieveList(oldValue);
147                 list.add(wrapper.getBeanDefinition());
148             }
149             else
150             {
151                 targetProperties.addPropertyValue(newName, wrapper.getBeanDefinition());
152             }
153         }
154     }
155 }