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.endpoint;
8   
9   import org.mule.api.MuleContext;
10  import org.mule.api.MuleException;
11  import org.mule.api.annotations.meta.ChannelType;
12  import org.mule.api.endpoint.EndpointBuilder;
13  import org.mule.api.endpoint.ImmutableEndpoint;
14  import org.mule.api.expression.PropertyConverter;
15  import org.mule.api.routing.filter.Filter;
16  import org.mule.api.transformer.Transformer;
17  import org.mule.config.i18n.AnnotationsMessages;
18  import org.mule.endpoint.MuleEndpointURI;
19  import org.mule.registry.RegistryMap;
20  import org.mule.routing.MessageFilter;
21  import org.mule.transport.AbstractConnector;
22  import org.mule.transport.service.TransportFactory;
23  import org.mule.util.TemplateParser;
24  
25  import java.util.Collection;
26  import java.util.Iterator;
27  import java.util.List;
28  
29  /**
30   * This is a wrapper helper that can process {@link AnnotatedEndpointData} objects (Annotaiton config data)
31   * and turn them into {@link org.mule.api.endpoint.EndpointBuilder} or {@link org.mule.api.endpoint.ImmutableEndpoint} objects.
32   * <p/>
33   * THis is an internal class that should only be used by the Annotation parser code.
34   */
35  public class AnnotatedEndpointHelper
36  {
37      protected TemplateParser parser = TemplateParser.createAntStyleParser();
38  
39      protected RegistryMap regMap;
40      protected MuleContext muleContext;
41      protected TransportFactory transportFactory;
42  
43      public AnnotatedEndpointHelper(MuleContext muleContext) throws MuleException
44      {
45          this.muleContext = muleContext;
46          this.transportFactory = new ConfigurableTransportFactory(muleContext);
47          regMap = new RegistryMap(muleContext.getRegistry());
48      }
49  
50      protected String parsePlaceholderValues(String key)
51      {
52          return parser.parse(regMap, key);
53      }
54  
55      protected EndpointBuilder getEndpointBuilder(AnnotatedEndpointData epData) throws MuleException
56      {
57          String uri = parsePlaceholderValues(epData.getAddress());
58  
59          EndpointBuilder endpointBuilder = muleContext.getEndpointFactory().getEndpointBuilder(uri);
60          endpointBuilder.setMuleContext(muleContext);
61  
62          return endpointBuilder;
63      }
64  
65      public ImmutableEndpoint processEndpoint(AnnotatedEndpointData epData) throws MuleException
66      {
67          preprocessEndpointData(epData);
68  
69          ImmutableEndpoint endpoint;
70          EndpointBuilder endpointBuilder = getEndpointBuilder(epData);
71  
72          if (epData.getProperties() != null && epData.getProperties().size() > 0)
73          {
74              endpointBuilder.setProperties(epData.getProperties());
75          }
76  
77          if (epData.getTransformers() != null)
78          {
79              List<Transformer> transformers = (List) convertProperty(List.class, epData.getTransformers());
80              endpointBuilder.setTransformers(transformers);
81          }
82  
83          if (epData.getFilter() != null)
84          {
85              Filter filter = (Filter) convertProperty(Filter.class, epData.getFilter());
86              endpointBuilder.addMessageProcessor(new MessageFilter(filter));
87  
88          }
89  
90          if (epData.getEncoding() != null)
91          {
92              endpointBuilder.setEncoding(parsePlaceholderValues(epData.getEncoding()));
93          }
94  
95          AbstractConnector connector;
96          if (epData.getConnectorName() != null)
97          {
98              connector = (AbstractConnector) muleContext.getRegistry().lookupConnector(parsePlaceholderValues(epData.getConnectorName()));
99          }
100         else if (epData.getConnector() != null)
101         {
102             connector = (AbstractConnector) epData.getConnector();
103         }
104         else
105         {
106             //We always create a new connecotr for annotations when one has not been configured
107             MuleEndpointURI uri = new MuleEndpointURI(parsePlaceholderValues(epData.getAddress()), muleContext);
108 
109             connector = (AbstractConnector) transportFactory.createConnector(uri);
110             //The ibeans transport factory will not always create a new connector, check before registering
111             if (muleContext.getRegistry().lookupConnector(connector.getName()) == null)
112             {
113                 muleContext.getRegistry().registerConnector(connector);
114             }
115         }
116         endpointBuilder.setConnector(connector);
117 
118         //Set threading for this connector. Note we simplify by setting all profiles with a single value 'threads'
119         //that can be set by the user
120         String threadsString = (String) epData.getProperties().get("threads");
121         if (threadsString != null)
122         {
123             int threads = Integer.valueOf(threadsString);
124             connector.setMaxDispatchersActive(threads);
125             connector.setMaxRequestersActive(threads);
126             connector.getReceiverThreadingProfile().setMaxThreadsActive(threads);
127             connector.getReceiverThreadingProfile().setMaxThreadsIdle(threads);
128         }
129 
130         if (epData.getName() != null)
131         {
132             endpointBuilder.setName(parsePlaceholderValues(epData.getName()));
133         }
134 
135         endpointBuilder.setExchangePattern(epData.getMep());
136 
137         if (epData.getType() == ChannelType.Inbound)
138         {
139             endpoint = endpointBuilder.buildInboundEndpoint();
140         }
141         else if (epData.getType() == ChannelType.Outbound)
142         {
143             endpoint = endpointBuilder.buildOutboundEndpoint();
144         }
145         else
146         {
147             throw new IllegalArgumentException("Channel type not recognised: " + epData.getType());
148         }
149         //TODO: not sure where to put this yet
150         if (epData.getName() != null)
151         {
152             muleContext.getRegistry().registerEndpointBuilder(epData.getName(), endpointBuilder);
153         }
154         return endpoint;
155     }
156 
157     /**
158      * This method can be overridden to process endpoints before they get built. This may be useful in environments
159      * where the characteristics of the endpoint change depending on the deployed environment
160      *
161      * @param data the endpoint data to process
162      */
163     protected void preprocessEndpointData(AnnotatedEndpointData data)
164     {
165         //no=op
166     }
167 
168     public Object convertProperty(Class type, String property)
169     {
170         String prop = parsePlaceholderValues(property);
171         Collection c = muleContext.getRegistry().lookupObjects(PropertyConverter.class);
172         for (Iterator iterator = c.iterator(); iterator.hasNext();)
173         {
174             PropertyConverter converter = (PropertyConverter) iterator.next();
175             if (converter.getType().equals(type))
176             {
177                 return converter.convert(prop, muleContext);
178             }
179         }
180         throw new IllegalArgumentException(AnnotationsMessages.noPropertyConverterForType(type).getMessage());
181     }
182 
183 }