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 2000-2005 (C) Exoffice Technologies Inc. All Rights Reserved. 42 * 43 * $Id: JmsServerStubImpl.java,v 1.5 2005/11/18 03:29:41 tanderson Exp $ 44 */ 45 package org.exolab.jms.client.net; 46 47 import java.rmi.AccessException; 48 import java.rmi.NotBoundException; 49 import java.rmi.RemoteException; 50 import java.util.HashMap; 51 import java.util.Map; 52 import javax.jms.ExceptionListener; 53 import javax.jms.InvalidClientIDException; 54 import javax.jms.JMSException; 55 import javax.jms.JMSSecurityException; 56 57 import org.exolab.jms.client.JmsServerStubIfc; 58 import org.exolab.jms.net.connector.Caller; 59 import org.exolab.jms.net.connector.CallerListener; 60 import org.exolab.jms.net.orb.ORB; 61 import org.exolab.jms.net.registry.Registry; 62 import org.exolab.jms.net.proxy.Proxy; 63 import org.exolab.jms.server.ServerConnection; 64 import org.exolab.jms.server.ServerConnectionFactory; 65 66 67 /*** 68 * This class is responsible for returning a reference to the remote JMS 69 * server. 70 * 71 * @author <a href="mailto:jima@comware.com.au">Jim Alateras</a> 72 * @author <a href="mailto:tma@netspace.net.au">Tim Anderson</a> 73 * @version $Revision: 1.5 $ $Date: 2005/11/18 03:29:41 $ 74 */ 75 public class JmsServerStubImpl implements JmsServerStubIfc, CallerListener { 76 77 /*** 78 * The ORB. 79 */ 80 private ORB _orb; 81 82 /*** 83 * Properties used to establish a connection to the remote server. 84 */ 85 private final Map _properties; 86 87 /*** 88 * The server URI; 89 */ 90 private final String _serverURI; 91 92 /*** 93 * Default user to connect to server. May be <code>null</code>. 94 */ 95 private final String _defaultUser; 96 97 /*** 98 * Default user's password. May be <code>null</code>. 99 */ 100 private final String _defaultPassword; 101 102 /*** 103 * The exception listener, which is shared by all the connections to the 104 * server. 105 */ 106 private ExceptionListener _listener = null; 107 108 109 /*** 110 * Construct a new <code>JmsServerStubImpl</code>. 111 * 112 * @param properties properties to initialise this with 113 * @param environment the environment used. May be <code>null</code> 114 */ 115 public JmsServerStubImpl(Map properties, Map environment) { 116 if (properties == null) { 117 throw new IllegalArgumentException("Argument 'properties' is null"); 118 } 119 _properties = properties; 120 121 _serverURI = (String) properties.get(ORB.PROVIDER_URI); 122 if (_serverURI == null) { 123 throw new IllegalArgumentException( 124 "Argument 'properties' does not contain property " 125 + ORB.PROVIDER_URI); 126 } 127 if (environment != null) { 128 _defaultUser = (String) environment.get(ORB.SECURITY_PRINCIPAL); 129 _defaultPassword = (String) environment.get( 130 ORB.SECURITY_CREDENTIALS); 131 } else { 132 _defaultUser = null; 133 _defaultPassword = null; 134 } 135 } 136 137 /*** 138 * Creates a connection with the specified user identity. 139 * <p/> 140 * The connection is created in stopped mode. No messages will be delivered 141 * until the <code>Connection.start</code> method is explicitly called. 142 * <p/> 143 * If <code>clientID</code> is specified, it indicates the pre-configured 144 * client identifier associated with the client 145 * <code>ConnectionFactory</code> object. 146 * 147 * @param clientID the pre-configured client identifier. May be 148 * <code>null</code>. 149 * @param user the caller's user name. May be <code>null</code> 150 * @param password the caller's password. May be <code>null</code> 151 * @return a newly created connection 152 * @throws InvalidClientIDException if the JMS client specifies an invalid 153 * or duplicate client ID. 154 * @throws JMSException if the JMS provider fails to create the 155 * connection due to some internal error. 156 * @throws JMSSecurityException if client authentication fails due to an 157 * invalid user name or password. 158 */ 159 public ServerConnection createConnection(String clientID, String user, 160 String password) 161 throws JMSException { 162 ServerConnection stub; 163 164 if (user == null) { 165 user = _defaultUser; 166 password = _defaultPassword; 167 } 168 169 ServerConnectionFactory factory 170 = getServerConnectionFactory(user, password); 171 try { 172 ServerConnection connection 173 = factory.createConnection(clientID, user, password); 174 stub = new JmsConnectionStubImpl(connection, _orb, _serverURI, 175 user, password); 176 } finally { 177 if (factory instanceof Proxy) { 178 ((Proxy) factory).disposeProxy(); 179 } 180 } 181 return stub; 182 } 183 184 /*** 185 * Set the exception listener so that the client can be notified of client 186 * disconnection events. 187 * 188 * @param listener the exception listener 189 */ 190 public void setExceptionListener(ExceptionListener listener) { 191 _listener = listener; 192 } 193 194 /*** 195 * Notifies that a caller has been disconnected. 196 * 197 * @param caller the caller that was disconnected 198 */ 199 public void disconnected(Caller caller) { 200 if (_listener != null) { 201 _listener.onException(new JMSException("Lost connection")); 202 } 203 } 204 205 /*** 206 * Looks up and returns the {@link ServerConnectionFactory} instance bound 207 * in the registry. 208 * 209 * @param user the caller's user name. May be <code>null</code> 210 * @param password the caller's password. May be <code>null</code> 211 * @return the bound {@link ServerConnectionFactory} 212 * @throws JMSException if lookup fails 213 */ 214 private synchronized ServerConnectionFactory getServerConnectionFactory( 215 String user, String password) 216 throws JMSException { 217 ServerConnectionFactory factory = null; 218 Map properties = _properties; 219 220 if (user != null) { 221 properties = new HashMap(_properties); 222 properties.put(ORB.SECURITY_PRINCIPAL, user); 223 properties.put(ORB.SECURITY_CREDENTIALS, password); 224 } 225 Registry registry = null; 226 try { 227 if (_orb == null) { 228 _orb = SharedORB.getInstance(); 229 } 230 registry = _orb.getRegistry(properties); 231 } catch (AccessException exception) { 232 JMSSecurityException error = new JMSSecurityException( 233 exception.getMessage()); 234 error.setLinkedException(exception); 235 throw error; 236 } catch (RemoteException exception) { 237 JMSException error = new JMSException( 238 "Failed to get registry service for URL: " + _serverURI); 239 error.setLinkedException(exception); 240 throw error; 241 } 242 243 try { 244 factory = (ServerConnectionFactory) registry.lookup("server"); 245 } catch (NotBoundException exception) { 246 throw new JMSException( 247 "Server is not bound in the registry for URL: " 248 + _serverURI); 249 } catch (RemoteException exception) { 250 JMSException error = new JMSException( 251 "Failed to lookup OpenJMS server for URL: " + _serverURI); 252 error.setLinkedException(exception); 253 throw error; 254 } 255 try { 256 _orb.addCallerListener(_serverURI, this); 257 } catch (RemoteException exception) { 258 JMSException error = new JMSException( 259 "Failed to register for disconnection notification for " 260 + "URL: " + _serverURI); 261 error.setLinkedException(exception); 262 throw error; 263 } 264 265 if (registry instanceof Proxy) { 266 ((Proxy) registry).disposeProxy(); 267 } 268 return factory; 269 } 270 271 }