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
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
258 server.init();
259
260
261 server.bindConnectionFactories(context);
262
263 return server;
264 }
265
266
267 }