View Javadoc

1   /***
2    * Redistribution and use of this software and associated documentation
3    * ("Software"), with or without modification, are permitted provided
4    * that the following conditions are met:
5    *
6    * 1. Redistributions of source code must retain copyright
7    *    statements and notices.  Redistributions must also contain a
8    *    copy of this document.
9    *
10   * 2. Redistributions in binary form must reproduce the
11   *    above copyright notice, this list of conditions and the
12   *    following disclaimer in the documentation and/or other
13   *    materials provided with the distribution.
14   *
15   * 3. The name "Exolab" must not be used to endorse or promote
16   *    products derived from this Software without prior written
17   *    permission of Exoffice Technologies.  For written permission,
18   *    please contact info@exolab.org.
19   *
20   * 4. Products derived from this Software may not be called "Exolab"
21   *    nor may "Exolab" appear in their names without prior written
22   *    permission of Exoffice Technologies. Exolab is a registered
23   *    trademark of Exoffice Technologies.
24   *
25   * 5. Due credit should be given to the Exolab Project
26   *    (http://www.exolab.org/).
27   *
28   * THIS SOFTWARE IS PROVIDED BY EXOFFICE TECHNOLOGIES AND CONTRIBUTORS
29   * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
30   * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
31   * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
32   * EXOFFICE TECHNOLOGIES OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
33   * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
35   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
37   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
39   * OF THE POSSIBILITY OF SUCH DAMAGE.
40   *
41   * Copyright 2005 (C) Exoffice Technologies Inc. All Rights Reserved.
42   *
43   * $Id: ConnectorService.java,v 1.4 2006/02/23 11:17:40 tanderson Exp $
44   */
45  
46  package org.exolab.jms.server;
47  
48  import java.lang.reflect.Constructor;
49  import javax.naming.Context;
50  import javax.naming.NamingException;
51  
52  import org.apache.commons.logging.Log;
53  import org.apache.commons.logging.LogFactory;
54  
55  import org.exolab.jms.config.Configuration;
56  import org.exolab.jms.config.Connector;
57  import org.exolab.jms.config.ConnectorHelper;
58  import org.exolab.jms.config.ConnectorResource;
59  import org.exolab.jms.config.types.SchemeType;
60  import org.exolab.jms.net.connector.Authenticator;
61  import org.exolab.jms.service.Service;
62  import org.exolab.jms.service.ServiceException;
63  import org.exolab.jms.common.threads.ThreadPoolFactory;
64  
65  
66  /***
67   * Service that manages the connectors configured for the server.
68   *
69   * @author <a href="mailto:tma@netspace.net.au">Tim Anderson</a>
70   * @version $Revision: 1.4 $ $Date: 2006/02/23 11:17:40 $
71   */
72  public class ConnectorService extends Service {
73  
74      /***
75       * The configuration.
76       */
77      private final Configuration _config;
78  
79      /***
80       * The authenticator, for authenticating clients.
81       */
82      private final Authenticator _authenticator;
83  
84      /***
85       * The factory for <code>ServerConnection</code> instances.
86       */
87      private final ServerConnectionFactory _factory;
88  
89      /***
90       * The admin connection manager.
91       */
92      private final AdminConnectionManager _manager;
93  
94      /***
95       * The name service.
96       */
97      private final NameService _names;
98  
99      /***
100      * The thread pool factory.
101      */
102     private final ThreadPoolFactory _threads;
103 
104     /***
105      * The interfaces to this server. One interface is constructed for each
106      * configured connector.
107      */
108     private ServerConnector[] _interfaces = null;
109 
110     /***
111      * The logger.
112      */
113     private static final Log _log = LogFactory.getLog(ConnectorService.class);
114 
115 
116     /***
117      * Construct a new <code>ConnectorService</code>.
118      *
119      * @param config the configuration to use
120      * @param names  the name service
121      */
122     public ConnectorService(Configuration config,
123                             Authenticator authenticator,
124                             ServerConnectionFactory factory,
125                             AdminConnectionManager manager,
126                             NameService names,
127                             ThreadPoolFactory threads) {
128         super("ConnectorService");
129         if (config == null) {
130             throw new IllegalArgumentException("Argument 'config' is null");
131         }
132         if (authenticator == null) {
133             throw new IllegalArgumentException(
134                     "Argument 'authenticator' is null");
135         }
136         if (factory == null) {
137             throw new IllegalArgumentException("Argument 'factory' is null");
138         }
139         if (manager == null) {
140             throw new IllegalArgumentException("Argument 'manager' is null");
141         }
142         if (names == null) {
143             throw new IllegalArgumentException("Arguement 'names' is null");
144         }
145         if (threads == null) {
146             throw new IllegalArgumentException("Argument 'threads' is null");
147         }
148         _config = config;
149         _authenticator = authenticator;
150         _factory = factory;
151         _manager = manager;
152         _names = names;
153         _threads = threads;
154     }
155 
156     /***
157      * Start the service.
158      *
159      * @throws ServiceException if the service fails to start
160      */
161     protected void doStart() throws ServiceException {
162         try {
163             Context context = _names.getInitialContext();
164             initConnectors(context);
165         } catch (NamingException exception) {
166             throw new ServiceException(exception.getMessage(), exception);
167         }
168     }
169 
170     /***
171      * Stop the service.
172      *
173      * @throws ServiceException if the service fails to stop
174      */
175     protected void doStop() throws ServiceException {
176         for (int i = 0; i < _interfaces.length; ++i) {
177             _interfaces[i].close();
178         }
179     }
180 
181     /***
182      * Creates an interface to the server for each configured connector.
183      *
184      * @param context the initial context
185      * @throws NamingException  if administered objects cannot be bound in JNDI
186      * @throws ServiceException if an interface can't be created
187      */
188     protected void initConnectors(Context context)
189             throws NamingException, ServiceException {
190 
191         Connector[] connectors = _config.getConnectors().getConnector();
192         _interfaces = new ServerConnector[connectors.length];
193 
194         for (int i = 0; i < connectors.length; ++i) {
195             Connector connector = connectors[i];
196             _interfaces[i] = initConnector(connector, context);
197         }
198     }
199 
200     /***
201      * Create an interface to the server for the specified connector.
202      *
203      * @param connector the connector
204      * @param context   the initial context
205      * @return the interface corresponding to <code>connector</code>
206      * @throws NamingException  if administered objects cannot be bound in JNDI
207      * @throws ServiceException if the interface can't be created
208      */
209     protected ServerConnector initConnector(Connector connector,
210                                             Context context)
211             throws NamingException, ServiceException {
212 
213         _log.info("Creating server interface for the " + connector.getScheme()
214                   + " connector");
215 
216         ServerConnector server;
217         ConnectorResource resource = ConnectorHelper.getConnectorResource(
218                 connector.getScheme(), _config);
219 
220         String className = resource.getServer().getImplementationClass();
221         Class clazz;
222         try {
223             clazz = Class.forName(className);
224         } catch (ClassNotFoundException exception) {
225             throw new ServiceException("Failed to load class " + className);
226         }
227 
228         if (!ServerConnector.class.isAssignableFrom(clazz)) {
229             throw new ServiceException(
230                     "Class " + className
231                     + " does not implement ServerConnector");
232         }
233         try {
234             SchemeType scheme = connector.getScheme();
235             Constructor ctor = clazz.getConstructor(new Class[]{
236                 SchemeType.class, Configuration.class,
237                 Authenticator.class, ServerConnectionFactory.class,
238                 AdminConnectionManager.class, NameService.class,
239                 ThreadPoolFactory.class});
240             server = (ServerConnector) ctor.newInstance(new Object[]{
241                 scheme, _config, _authenticator, _factory, _manager, _names,
242                 _threads});
243         } catch (NoSuchMethodException ignore) {
244             // fall back to the default constructor
245             try {
246                 server = (ServerConnector) clazz.newInstance();
247             } catch (Exception exception) {
248                 throw new ServiceException(exception.getMessage(), exception);
249             }
250         } catch (Exception exception) {
251             throw new ServiceException(exception.getMessage(), exception);
252         }
253 
254         _log.debug("Created an instance of " + className
255                    + " as a server interface");
256 
257         // initialise the interface
258         server.init();
259 
260         // bind any configured connection factories
261         server.bindConnectionFactories(context);
262 
263         return server;
264     }
265 
266 
267 }