View Javadoc

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