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.handlers;
8   
9   import org.mule.config.spring.factories.InboundEndpointFactoryBean;
10  import org.mule.config.spring.factories.OutboundEndpointFactoryBean;
11  import org.mule.config.spring.parsers.MuleDefinitionParser;
12  import org.mule.config.spring.parsers.MuleDefinitionParserConfiguration;
13  import org.mule.config.spring.parsers.PostProcessor;
14  import org.mule.config.spring.parsers.PreProcessor;
15  import org.mule.config.spring.parsers.assembly.configuration.ValueMap;
16  import org.mule.config.spring.parsers.generic.MuleOrphanDefinitionParser;
17  import org.mule.config.spring.parsers.specific.endpoint.TransportEndpointDefinitionParser;
18  import org.mule.config.spring.parsers.specific.endpoint.TransportGlobalEndpointDefinitionParser;
19  import org.mule.config.spring.parsers.specific.endpoint.support.AddressedEndpointDefinitionParser;
20  import org.mule.endpoint.EndpointURIEndpointBuilder;
21  
22  import java.io.InputStream;
23  import java.util.HashSet;
24  import java.util.Iterator;
25  import java.util.Map;
26  import java.util.Properties;
27  import java.util.Set;
28  
29  import org.apache.commons.logging.Log;
30  import org.apache.commons.logging.LogFactory;
31  import org.mule.util.IOUtils;
32  import org.springframework.beans.factory.config.BeanDefinition;
33  import org.springframework.beans.factory.xml.BeanDefinitionParser;
34  import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
35  import org.springframework.beans.factory.xml.ParserContext;
36  import org.w3c.dom.Element;
37  
38  /**
39   * This Namespace handler extends the default Spring {@link org.springframework.beans.factory.xml.NamespaceHandlerSupport}
40   * to allow certain elements in document to be ignored by the handler.
41   */
42  public abstract class AbstractMuleNamespaceHandler extends NamespaceHandlerSupport
43  {
44      public static final String GLOBAL_ENDPOINT = "endpoint";
45      public static final String INBOUND_ENDPOINT = "inbound-endpoint";
46      public static final String OUTBOUND_ENDPOINT = "outbound-endpoint"; 
47  
48      protected transient final Log logger = LogFactory.getLog(getClass());
49  
50      /**
51       * @param name The name of the element to be ignored.
52       */
53      protected final void registerIgnoredElement(String name)
54      {
55          registerBeanDefinitionParser(name, new IgnoredDefinitionParser());
56      }
57  
58      protected MuleDefinitionParserConfiguration registerConnectorDefinitionParser(Class connectorClass, String transportName)
59      {
60          return registerConnectorDefinitionParser(findConnectorClass(connectorClass, transportName));
61      }
62  
63      protected MuleDefinitionParserConfiguration registerConnectorDefinitionParser(Class connectorClass)
64      {
65          return registerConnectorDefinitionParser( new MuleOrphanDefinitionParser(connectorClass, true));
66      }
67  
68      protected MuleDefinitionParserConfiguration registerConnectorDefinitionParser(MuleDefinitionParser parser)
69      {
70          registerBeanDefinitionParser("connector", parser);
71          return parser;
72      }
73  
74      protected MuleDefinitionParserConfiguration registerMuleBeanDefinitionParser(String name, MuleDefinitionParser parser)
75      {
76          registerBeanDefinitionParser(name, parser);
77          return parser;
78      }
79  
80      protected MuleDefinitionParserConfiguration registerStandardTransportEndpoints(String protocol, String[] requiredAttributes)
81      {
82          return new RegisteredMdps(protocol, AddressedEndpointDefinitionParser.PROTOCOL, requiredAttributes);
83      }
84  
85      protected MuleDefinitionParserConfiguration registerMetaTransportEndpoints(String protocol)
86      {
87          return new RegisteredMdps(protocol, AddressedEndpointDefinitionParser.META, new String[]{});
88      }
89  
90      private static class IgnoredDefinitionParser implements BeanDefinitionParser
91      {
92          public IgnoredDefinitionParser()
93          {
94              super();
95          }
96          
97          public BeanDefinition parse(Element element, ParserContext parserContext)
98          {
99              return null;
100         }
101     }
102 
103     protected Class getInboundEndpointFactoryBeanClass()
104     {
105         return InboundEndpointFactoryBean.class;
106     }
107 
108     protected Class getOutboundEndpointFactoryBeanClass()
109     {
110         return OutboundEndpointFactoryBean.class;
111     }
112 
113     protected Class getGlobalEndpointBuilderBeanClass()
114     {
115         return EndpointURIEndpointBuilder.class;
116     }
117 
118     private class RegisteredMdps implements MuleDefinitionParserConfiguration
119     {
120         private Set bdps = new HashSet();
121 
122         public RegisteredMdps(String protocol, boolean isMeta, String[] requiredAttributes)
123         {
124             registerBeanDefinitionParser("endpoint", add(new TransportGlobalEndpointDefinitionParser(protocol, isMeta, AbstractMuleNamespaceHandler.this.getGlobalEndpointBuilderBeanClass(), requiredAttributes, new String[]{})));
125             registerBeanDefinitionParser("inbound-endpoint", add(new TransportEndpointDefinitionParser(protocol, isMeta, AbstractMuleNamespaceHandler.this.getInboundEndpointFactoryBeanClass(), requiredAttributes, new String[]{})));
126             registerBeanDefinitionParser("outbound-endpoint", add(new TransportEndpointDefinitionParser(protocol, isMeta, AbstractMuleNamespaceHandler.this.getOutboundEndpointFactoryBeanClass(), requiredAttributes, new String[]{})));
127         }
128 
129         private MuleDefinitionParser add(MuleDefinitionParser bdp)
130         {
131             bdps.add(bdp);
132             return bdp;
133         }
134 
135         public MuleDefinitionParserConfiguration registerPreProcessor(PreProcessor preProcessor)
136         {
137             for (Iterator bdp = bdps.iterator(); bdp.hasNext();)
138             {
139                 ((MuleDefinitionParserConfiguration) bdp.next()).registerPreProcessor(preProcessor);
140             }
141             return this;
142         }
143 
144         public MuleDefinitionParserConfiguration registerPostProcessor(PostProcessor postProcessor)
145         {
146             for (Iterator bdp = bdps.iterator(); bdp.hasNext();)
147             {
148                 ((MuleDefinitionParserConfiguration) bdp.next()).registerPostProcessor(postProcessor);
149             }
150             return this;
151         }
152 
153         public MuleDefinitionParserConfiguration addReference(String propertyName)
154         {
155             for (Iterator bdp = bdps.iterator(); bdp.hasNext();)
156             {
157                 ((MuleDefinitionParserConfiguration) bdp.next()).addReference(propertyName);
158             }
159             return this;
160         }
161 
162         public MuleDefinitionParserConfiguration addMapping(String propertyName, Map mappings)
163         {
164             for (Iterator bdp = bdps.iterator(); bdp.hasNext();)
165             {
166                 ((MuleDefinitionParserConfiguration) bdp.next()).addMapping(propertyName, mappings);
167             }
168             return this;
169         }
170 
171         public MuleDefinitionParserConfiguration addMapping(String propertyName, String mappings)
172         {
173             for (Iterator bdp = bdps.iterator(); bdp.hasNext();)
174             {
175                 ((MuleDefinitionParserConfiguration) bdp.next()).addMapping(propertyName, mappings);
176             }
177             return this;
178         }
179 
180         public MuleDefinitionParserConfiguration addMapping(String propertyName, ValueMap mappings)
181         {
182             for (Iterator bdp = bdps.iterator(); bdp.hasNext();)
183             {
184                 ((MuleDefinitionParserConfiguration) bdp.next()).addMapping(propertyName, mappings);
185             }
186             return this;
187         }
188 
189         public MuleDefinitionParserConfiguration addAlias(String alias, String propertyName)
190         {
191             for (Iterator bdp = bdps.iterator(); bdp.hasNext();)
192             {
193                 ((MuleDefinitionParserConfiguration) bdp.next()).addAlias(alias, propertyName);
194             }
195             return this;
196         }
197 
198         public MuleDefinitionParserConfiguration addCollection(String propertyName)
199         {
200             for (Iterator bdp = bdps.iterator(); bdp.hasNext();)
201             {
202                 ((MuleDefinitionParserConfiguration) bdp.next()).addCollection(propertyName);
203             }
204             return this;
205         }
206 
207         public MuleDefinitionParserConfiguration addIgnored(String propertyName)
208         {
209             for (Iterator bdp = bdps.iterator(); bdp.hasNext();)
210             {
211                 ((MuleDefinitionParserConfiguration) bdp.next()).addIgnored(propertyName);
212             }
213             return this;
214         }
215 
216         public MuleDefinitionParserConfiguration removeIgnored(String propertyName)
217         {
218             for (Iterator bdp = bdps.iterator(); bdp.hasNext();)
219             {
220                 ((MuleDefinitionParserConfiguration) bdp.next()).removeIgnored(propertyName);
221             }
222             return this;
223         }
224 
225         public MuleDefinitionParserConfiguration setIgnoredDefault(boolean ignoreAll)
226         {
227             for (Iterator bdp = bdps.iterator(); bdp.hasNext();)
228             {
229                 ((MuleDefinitionParserConfiguration) bdp.next()).setIgnoredDefault(ignoreAll);
230             }
231             return this;
232         }
233 
234         public MuleDefinitionParserConfiguration addBeanFlag(String flag)
235         {
236             for (Iterator bdp = bdps.iterator(); bdp.hasNext();)
237             {
238                 ((MuleDefinitionParserConfiguration) bdp.next()).addBeanFlag(flag);
239             }
240             return this;
241         }
242     }
243     
244     /**
245      * Subclasses can call this to register the supplied {@link BeanDefinitionParser} to
246      * handle the specified element. The element name is the local (non-namespace qualified)
247      * name.
248      */
249     protected void registerDeprecatedBeanDefinitionParser(String elementName, BeanDefinitionParser parser, String deprecationWarning) 
250     {
251         if (parser instanceof MuleDefinitionParserConfiguration)
252         {
253             ((MuleDefinitionParser) parser).setDeprecationWarning(deprecationWarning);
254         }
255         registerBeanDefinitionParser(elementName, parser);
256     }
257 
258     /**
259      * See if there's a preferred connector class
260      */
261     protected Class findConnectorClass(Class basicConnector, String transportName)
262     {
263         String preferredPropertiesURL = "META-INF/services/org/mule/transport/preferred-" +transportName + ".properties";
264         InputStream stream = AbstractMuleNamespaceHandler.class.getClassLoader().getResourceAsStream(preferredPropertiesURL);
265         if (stream != null)
266         {
267             try
268             {
269                 Properties preferredProperties = new Properties();
270                 preferredProperties.load(stream);
271                 String preferredConnectorName = preferredProperties.getProperty("connector");
272                 if (preferredConnectorName != null)
273                 {
274                     logger.debug("Found preferred connector class " + preferredConnectorName);
275                     return Class.forName(preferredConnectorName);
276                 }
277             }
278             catch (Exception e)
279             {
280                 logger.debug("Error processing preferred properties", e);
281             }
282             finally
283             {
284                 IOUtils.closeQuietly(stream);
285             }
286         }
287         return basicConnector;
288     }
289 }