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 2003-2005 (C) Exoffice Technologies Inc. All Rights Reserved. 42 * 43 * $Id: VMManagedConnectionAcceptor.java,v 1.4 2005/11/12 12:42:54 tanderson Exp $ 44 */ 45 package org.exolab.jms.net.vm; 46 47 import java.security.Principal; 48 import java.util.HashMap; 49 import java.util.Map; 50 51 import org.apache.commons.logging.Log; 52 import org.apache.commons.logging.LogFactory; 53 54 import org.exolab.jms.net.connector.Authenticator; 55 import org.exolab.jms.net.connector.ConnectException; 56 import org.exolab.jms.net.connector.ManagedConnectionAcceptor; 57 import org.exolab.jms.net.connector.ManagedConnectionAcceptorListener; 58 import org.exolab.jms.net.connector.ResourceException; 59 import org.exolab.jms.net.connector.SecurityException; 60 import org.exolab.jms.net.connector.URIRequestInfo; 61 import org.exolab.jms.net.uri.URI; 62 63 64 /*** 65 * A <code>VMManagedConnectionAcceptor</code> is responsible for accepting 66 * connections, and constructing new {@link VMManagedConnection} instances to 67 * serve them. 68 * 69 * @author <a href="mailto:tma@netspace.net.au">Tim Anderson</a> 70 * @version $Revision: 1.4 $ $Date: 2005/11/12 12:42:54 $ 71 */ 72 class VMManagedConnectionAcceptor implements ManagedConnectionAcceptor { 73 74 /*** 75 * The connection authenticator. 76 */ 77 private final Authenticator _authenticator; 78 79 /*** 80 * The URI denoting this acceptor. 81 */ 82 private final URI _uri; 83 84 /*** 85 * The listener to delegate accepted connections to. 86 */ 87 private ManagedConnectionAcceptorListener _listener; 88 89 /*** 90 * The set of acceptors, keyed on URI. 91 */ 92 private static Map _acceptors = new HashMap(); 93 94 /*** 95 * The logger. 96 */ 97 private static final Log _log = 98 LogFactory.getLog(VMManagedConnectionAcceptor.class); 99 100 101 /*** 102 * Construct a new <code>VMConnectionAcceptor</code>. 103 * 104 * @param authenticator the connection authenticator 105 * @param info the connection request info 106 */ 107 public VMManagedConnectionAcceptor(Authenticator authenticator, 108 URIRequestInfo info) { 109 _authenticator = authenticator; 110 _uri = info.getURI(); 111 } 112 113 /*** 114 * Start accepting connections. 115 * 116 * @param listener the listener to delegate accepted connections to 117 * @throws ResourceException if connections cannot be accepted 118 */ 119 public synchronized void accept(ManagedConnectionAcceptorListener listener) 120 throws ResourceException { 121 if (listener == null) { 122 throw new IllegalArgumentException("Argument 'listener' is null"); 123 } 124 if (_listener != null) { 125 throw new ResourceException( 126 "Acceptor already accepting connections at URI=" + _uri); 127 } 128 synchronized (_acceptors) { 129 if (_acceptors.containsKey(_uri)) { 130 throw new ResourceException("Cannot accept connections on URI=" 131 + _uri 132 + ". Address in use."); 133 } 134 _acceptors.put(_uri, this); 135 } 136 _listener = listener; 137 138 if (_log.isDebugEnabled()) { 139 _log.debug("VM connector accepting requests at URI=" + _uri); 140 } 141 } 142 143 /*** 144 * Stop accepting connection requests, and clean up any allocated 145 * resources. 146 */ 147 public synchronized void close() { 148 if (_listener != null) { 149 synchronized (_acceptors) { 150 _acceptors.remove(_uri); 151 } 152 } 153 _listener = null; 154 } 155 156 /*** 157 * Returns the URI that this acceptor is accepting connections on. 158 * 159 * @return the URI that this acceptor is accepting connections on 160 */ 161 public URI getURI() { 162 return _uri; 163 } 164 165 /*** 166 * Create a new <code>ManagedConnection>/code>. 167 * 168 * @param principal the security principal 169 * @param info the connection request info 170 * @param client the invoker for performing invocations back to the 171 * client 172 * @param uri the URI representing the client 173 * @return an invoker for delegating invocations from the client to the 174 * server ManagedConnection 175 * @throws ConnectException if the connection can't be accepted 176 * @throws ResourceException for any error 177 */ 178 protected static VMInvoker connect(Principal principal, URIRequestInfo info, 179 VMInvoker client, URI uri) 180 throws ResourceException { 181 VMManagedConnectionAcceptor acceptor; 182 URI acceptURI = info.getURI(); 183 synchronized (_acceptors) { 184 acceptor = (VMManagedConnectionAcceptor) _acceptors.get(acceptURI); 185 } 186 if (acceptor == null) { 187 throw new ConnectException("Connection refused, URI=" + acceptURI); 188 } 189 return acceptor.accept(principal, info, client, uri); 190 } 191 192 /*** 193 * Create a new <code>ManagedConnection</code>. 194 * 195 * @param principal the security principal 196 * @param info the connection request info 197 * @param client the invoker for performing invocations back to the 198 * client 199 * @param uri the URI representing the client 200 * @return an invoker for delegating invocations from the client to the 201 * server ManagedConnection 202 * @throws ConnectException if the connection can't be accepted 203 * @throws ResourceException for any error 204 */ 205 protected VMInvoker accept(Principal principal, URIRequestInfo info, 206 VMInvoker client, URI uri) 207 throws ResourceException { 208 if (!_authenticator.authenticate(principal)) { 209 throw new SecurityException("Failed to authenticate: " + principal); 210 } 211 VMManagedConnection connection = 212 new VMManagedConnection(principal, info, client, uri); 213 VMInvoker invoker = new VMInvoker(connection); 214 ManagedConnectionAcceptorListener listener; 215 synchronized (this) { 216 listener = _listener; 217 } 218 if (listener == null) { 219 throw new ConnectException("Connection refused, URI=" + _uri); 220 } 221 listener.accepted(this, connection); 222 return invoker; 223 } 224 }