View Javadoc

1   /*
2    * $Id: AbstractSerialDelegatingDefinitionParser.java 21939 2011-05-18 13:32:09Z aperepel $
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.MuleHierarchicalBeanDefinitionParserDelegate;
14  import org.mule.config.spring.parsers.AbstractMuleBeanDefinitionParser;
15  import org.mule.config.spring.parsers.MuleDefinitionParser;
16  import org.mule.config.spring.parsers.MuleDefinitionParserConfiguration;
17  import org.mule.config.spring.parsers.PreProcessor;
18  import org.mule.config.spring.parsers.assembly.configuration.PropertyConfiguration;
19  import org.mule.util.StringUtils;
20  
21  import java.util.Arrays;
22  import java.util.HashSet;
23  import java.util.Iterator;
24  import java.util.Set;
25  
26  import org.springframework.beans.factory.support.AbstractBeanDefinition;
27  import org.springframework.beans.factory.xml.ParserContext;
28  import org.w3c.dom.Element;
29  
30  /**
31   * This allows a set of definition parsers to be used, one after another, to process
32   * the same element.  This lets multiple beans be generated from a single element.
33   *
34   * <p>Since each bean typically needs a spearate name, this class guarantees that the
35   * name and id attributes are reset before each call.  Delegates can then modify these
36   * on the element without worrying about interfering with other parsers.</p>
37   *
38   * <p>Typically, subclasses will add additional processing with
39   * {@link org.mule.config.spring.parsers.PreProcessor} and
40   * {@link org.mule.config.spring.parsers.PostProcessor} anonymous classes.</p>
41   */
42  public abstract class AbstractSerialDelegatingDefinitionParser extends AbstractDelegatingDefinitionParser
43  {
44  
45      private int index = 0;
46      private boolean first;
47      private boolean doReset;
48      private String originalId;
49      private String originalName;
50      private Set handledExceptions = new HashSet();
51  
52      public AbstractSerialDelegatingDefinitionParser()
53      {
54          this(true); // by default, reset name
55      }
56  
57      /**
58       * @param doReset Should the name be reset after called.  This is typically true (it protects the
59       * parent from changes made by children) unless this is itself nested.
60       */
61      public AbstractSerialDelegatingDefinitionParser(boolean doReset)
62      {
63          this.doReset = doReset;
64      }
65  
66      public AbstractBeanDefinition muleParse(Element element, ParserContext parserContext)
67      {
68          if (index == 0 || index >= size())
69          {
70              first = true;
71              index = 0;
72          }
73          else
74          {
75              first = false;
76          }
77          AbstractBeanDefinition bean = null;
78          while (null == bean && index < size())
79          {
80              try
81              {
82                  MuleDefinitionParser parser = getDelegate(index);
83                  bean = doSingleBean(index++, parser, element, parserContext);
84              }
85              catch (RuntimeException e)
86              {
87                  if (isExceptionHandled(e))
88                  {
89                      bean = null;
90                  }
91                  else
92                  {
93                      throw e;
94                  }
95              }
96          }
97          if (null != bean)
98          {
99              if (index == size())
100             {
101                 bean.removeAttribute(MuleHierarchicalBeanDefinitionParserDelegate.MULE_REPEAT_PARSE);
102             }
103             else
104             {
105                 bean.setAttribute(MuleHierarchicalBeanDefinitionParserDelegate.MULE_REPEAT_PARSE, Boolean.TRUE);
106             }
107         }
108         return bean;
109     }
110 
111     protected boolean isExceptionHandled(Exception e)
112     {
113         return handledExceptions.contains(e.getClass());
114     }
115 
116     protected AbstractBeanDefinition doSingleBean(int index, MuleDefinitionParser parser,
117                                                   Element element, ParserContext parserContext)
118     {
119         return parser.muleParse(element, parserContext);
120     }
121 
122     protected MuleDefinitionParserConfiguration addDelegate(MuleDefinitionParser delegate)
123     {
124         delegate.registerPreProcessor(new PreProcessor()
125         {
126             public void preProcess(PropertyConfiguration config, Element element)
127             {
128                 if (first)
129                 {
130                     originalId = element.getAttribute(AbstractMuleBeanDefinitionParser.ATTRIBUTE_ID);
131                     originalName = element.getAttribute(AbstractMuleBeanDefinitionParser.ATTRIBUTE_NAME);
132                 }
133                 else if (doReset)
134                 {
135                     resetNameAndId(element);
136                 }
137             }
138         });
139         return super.addDelegate(delegate);
140     }
141 
142     protected void resetNameAndId(Element element)
143     {
144         resetAttribute(element, AbstractMuleBeanDefinitionParser.ATTRIBUTE_ID, originalId);
145         resetAttribute(element, AbstractMuleBeanDefinitionParser.ATTRIBUTE_NAME, originalName);
146     }
147 
148     protected void resetAttribute(Element element, String name, String value)
149     {
150         if (StringUtils.isEmpty(value))
151         {
152             if (element.hasAttribute(name))
153             {
154                 element.removeAttribute(name);
155             }
156         }
157         else
158         {
159             element.setAttribute(name, value);
160         }
161     }
162 
163     protected void addHandledException(Class exception)
164     {
165         handledExceptions.add(exception);
166     }
167 
168     /**
169      * A utility class for selecting certain attributes.  If the attributes are enabled,
170      * the default is set to block others; if specific attributes are disabled the default
171      * is set to allow others.
172      *
173      * @param delegate
174      * @param attributes
175      * @param enable
176      */
177     public static void enableAttributes(MuleDefinitionParser delegate, String[] attributes, boolean enable)
178     {
179         // if enabling specific attributes, block globally
180         delegate.setIgnoredDefault(enable);
181 
182         Iterator names = Arrays.asList(attributes).iterator();
183         while (names.hasNext())
184         {
185             String name = (String) names.next();
186             if (enable)
187             {
188                 delegate.removeIgnored(name);
189             }
190             else
191             {
192                 delegate.addIgnored(name);
193             }
194         }
195     }
196 
197     public static void enableAttributes(MuleDefinitionParser delegate, String[][] attributes)
198     {
199         for (int i = 0; i < attributes.length; ++i)
200         {
201             enableAttributes(delegate, attributes[i], true);
202         }
203     }
204 
205     public static void enableAttributes(MuleDefinitionParser delegate, String[] attributes)
206     {
207         enableAttributes(delegate, attributes, true);
208     }
209 
210     public static void enableAttribute(MuleDefinitionParser delegate, String attribute)
211     {
212         enableAttributes(delegate, new String[]{attribute}, true);
213     }
214 
215     public static void disableAttributes(MuleDefinitionParser delegate, String[][] attributes)
216     {
217         for (int i = 0; i < attributes.length; ++i)
218         {
219             enableAttributes(delegate, attributes[i], false);
220         }
221     }
222 
223     public static void disableAttributes(MuleDefinitionParser delegate, String[] attributes)
224     {
225         enableAttributes(delegate, attributes, false);
226     }
227 
228     public static void disableAttribute(MuleDefinitionParser delegate, String attribute)
229     {
230         enableAttributes(delegate, new String[]{attribute}, false);
231     }
232 
233 }