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.transport.service;
8   
9   import org.mule.api.MuleContext;
10  import org.mule.api.endpoint.EndpointException;
11  import org.mule.api.endpoint.EndpointURI;
12  import org.mule.api.endpoint.ImmutableEndpoint;
13  import org.mule.api.registry.ServiceException;
14  import org.mule.api.registry.ServiceType;
15  import org.mule.api.transport.Connector;
16  import org.mule.config.i18n.CoreMessages;
17  import org.mule.endpoint.MuleEndpointURI;
18  import org.mule.transport.AbstractConnector;
19  import org.mule.util.BeanUtils;
20  import org.mule.util.ObjectNameHelper;
21  
22  import java.util.ArrayList;
23  import java.util.Collection;
24  import java.util.Iterator;
25  import java.util.List;
26  
27  import org.apache.commons.logging.Log;
28  import org.apache.commons.logging.LogFactory;
29  
30  /**
31   * <code>TransportFactory</code> can be used for generically creating endpoints
32   * from an url. Note that for some endpoints, the url alone is not enough to create
33   * the endpoint if a connector for the endpoint has not already been configured with
34   * the Mule Manager.
35   */
36  public class TransportFactory
37  {
38      /**
39       * logger used by this class
40       */
41      protected static final Log logger = LogFactory.getLog(TransportFactory.class);
42  
43      protected MuleContext muleContext;
44  
45      public TransportFactory(MuleContext muleContext)
46      {
47          this.muleContext = muleContext;
48      }
49  
50      /**
51       * Creates an uninitialied connector from the provided MuleEndpointURI. The
52       * scheme is used to determine what kind of connector to create. Any params set
53       * on the uri can be used to initialise bean properties on the created connector.
54       * <p/> Note that the initalise method will need to be called on the connector
55       * returned. This is so that developers can control when the connector
56       * initialisation takes place as this is likely to initialse all connecotr
57       * resources.
58       *
59       * @param url the MuleEndpointURI url to create the connector with
60       * @return a new Connector
61       * @throws TransportFactoryException
62       */
63      public Connector createConnector(EndpointURI url) throws TransportFactoryException
64      {
65  
66          try
67          {
68              Connector connector;
69              String scheme = url.getFullScheme();
70  
71              TransportServiceDescriptor sd = (TransportServiceDescriptor)
72                      muleContext.getRegistry().lookupServiceDescriptor(ServiceType.TRANSPORT, scheme, null);
73              if (sd == null)
74              {
75                  throw new ServiceException(CoreMessages.noServiceTransportDescriptor(scheme));
76              }
77  
78              connector = sd.createConnector();
79              if (connector != null)
80              {
81                  if (connector instanceof AbstractConnector)
82                  {
83                      ((AbstractConnector) connector).initialiseFromUrl(url);
84                  }
85              }
86              else
87              {
88                  throw new TransportFactoryException(
89                          CoreMessages.objectNotSetInService("Connector", scheme));
90              }
91  
92              connector.setName(new ObjectNameHelper(muleContext).getConnectorName(connector));
93  
94              return connector;
95          }
96          catch (Exception e)
97          {
98              throw new TransportFactoryException(
99                      CoreMessages.failedToCreateObjectWith("Endpoint", url), e);
100         }
101     }
102 
103     public Connector createConnector(String uri) throws TransportFactoryException
104     {
105         try
106         {
107             return createConnector(new MuleEndpointURI(uri, muleContext));
108         }
109         catch (EndpointException e)
110         {
111             throw new TransportFactoryException(e);
112         }
113     }
114 
115     public Connector getOrCreateConnectorByProtocol(ImmutableEndpoint endpoint)
116             throws TransportFactoryException
117     {
118         return getOrCreateConnectorByProtocol(endpoint.getEndpointURI());
119     }
120 
121     /**
122      * Returns an initialized connector.
123      */
124     public Connector getOrCreateConnectorByProtocol(EndpointURI uri)
125             throws TransportFactoryException
126     {
127         String connectorName = uri.getConnectorName();
128         if (null != connectorName)
129         {
130             // TODO this lookup fails currently on Mule 2.x! MuleAdminAgentTestCase
131             Connector connector = muleContext.getRegistry().lookupConnector(connectorName);
132             if (connector != null)
133             {
134                 return connector;
135             }
136         }
137 
138         Connector connector = getConnectorByProtocol(uri.getFullScheme());
139         if (connector == null)
140         {
141             connector = createConnector(uri);
142             try
143             {
144                 BeanUtils.populate(connector, uri.getParams());
145                 muleContext.getRegistry().registerConnector(connector);
146             }
147             catch (Exception e)
148             {
149                 throw new TransportFactoryException(e);
150             }
151         }
152         return connector;
153     }
154 
155     public Connector getConnectorByProtocol(String protocol)
156     {
157         Connector connector;
158         List<Connector> results = new ArrayList<Connector>();
159         Collection connectors = muleContext.getRegistry().lookupObjects(Connector.class);
160         for (Iterator iterator = connectors.iterator(); iterator.hasNext();)
161         {
162             connector = (Connector) iterator.next();
163             if (connector.supportsProtocol(protocol))
164             {
165                 results.add(connector);
166             }
167         }
168         if (results.size() > 1)
169         {
170             StringBuffer buf = new StringBuffer();
171             for (Connector result : results)
172             {
173                 buf.append(result.getName()).append(", ");
174             }
175             throw new IllegalStateException(
176                     CoreMessages.moreThanOneConnectorWithProtocol(protocol, buf.toString()).getMessage());
177         }
178         else if (results.size() == 1)
179         {
180             return results.get(0);
181         }
182         else
183         {
184             return null;
185         }
186     }
187 }