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 2000-2001,2003 (C) Exoffice Technologies Inc. All Rights Reserved.
42   *
43   * $Id: RmiJndiInitialContextFactory.java,v 1.20 2004/01/29 12:14:14 tanderson Exp $
44   *
45   * Date         Author  Changes
46   * 3/16/2000    jima    Created
47   */
48  package org.exolab.jms.jndi.rmi;
49  
50  import java.net.MalformedURLException;
51  import java.rmi.Naming;
52  import java.rmi.NotBoundException;
53  import java.rmi.RemoteException;
54  import java.util.Hashtable;
55  
56  import javax.naming.CommunicationException;
57  import javax.naming.ConfigurationException;
58  import javax.naming.Context;
59  import javax.naming.NameParser;
60  import javax.naming.NamingException;
61  import javax.naming.ServiceUnavailableException;
62  import javax.naming.spi.InitialContextFactory;
63  
64  import org.apache.avalon.excalibur.naming.DefaultNamespace;
65  import org.apache.avalon.excalibur.naming.NamingProvider;
66  import org.apache.avalon.excalibur.naming.RemoteContext;
67  import org.apache.commons.logging.Log;
68  import org.apache.commons.logging.LogFactory;
69  
70  import org.exolab.core.util.URI;
71  import org.exolab.jms.jndi.JndiConstants;
72  
73  
74  /***
75   * This is the client side helper class that retrieves the root context
76   * of the JNDI server. This class implements the InitialContextFactory
77   * interface
78   *
79   * @version     $Revision: 1.20 $ $Date: 2004/01/29 12:14:14 $
80   * @author      <a href="mailto:jima@intalio.com">Jim Alateras</a>
81   */
82  public class RmiJndiInitialContextFactory implements InitialContextFactory {
83  
84      /***
85       * The logger
86       */
87      private static final Log _log =
88          LogFactory.getLog(RmiJndiInitialContextFactory.class);
89  
90  
91      /***
92       * This class is required to have a default constructor
93       */
94      public RmiJndiInitialContextFactory() {
95      }
96  
97      /***
98       * This routine will extract the port number of the RMI registry from
99       * the environment and uses it to establish a connection with the JNDI
100      * server. It then makes a call to retrieve the initial context which
101      * it then returns to the client
102      *
103      * @param environment the environment specifying information to be used in
104      * the creation of the initial context.
105      * @return the initial context
106      */
107     public Context getInitialContext(Hashtable environment)
108         throws NamingException {
109         Context result = null;
110         if (environment == null) {
111             throw new ConfigurationException(
112                 "Cannot connect to JNDI provider - environment not set");
113         }
114         String url = (String) environment.get(Context.PROVIDER_URL);
115         if (url != null) {
116             URI uri;
117             try {
118                 uri = new URI(url);
119             } catch (URI.MalformedURIException exception) {
120                 throw new ConfigurationException(
121                     "Malformed JNDI provider URL: " + url);
122             }
123             String path = uri.getPath();
124             if (path == null || path.length() == 0) {
125                 url += "/JndiServer";
126             } else if (path.equals("/")) {
127                 url += "JndiServer";
128             }
129         } else {
130             url = getDeprecatedEnvironment(environment);
131         }
132 
133         NamingProvider provider;
134         try {
135             provider = (NamingProvider) Naming.lookup(url);
136         } catch (MalformedURLException exception) {
137             throw new ConfigurationException(
138                 "Malformed JNDI provider URL: " + url);
139         } catch (NotBoundException exception) {
140             throw new ServiceUnavailableException(
141                 "JNDI service is not bound in the registry for URL: " + url);
142         } catch (RemoteException exception) {
143             NamingException error = new CommunicationException(
144                 "Failed to lookup JNDI provider for URL: " + url);
145             error.setRootCause(exception);
146             throw error;
147         }
148 
149         NameParser parser;
150         try {
151             parser = provider.getNameParser();
152         } catch (NamingException exception) {
153             throw exception;
154         } catch (Exception exception) {
155             NamingException error = new ServiceUnavailableException(
156                 exception.getMessage());
157             error.setRootCause(exception);
158             throw error;
159         }
160         DefaultNamespace namespace = new DefaultNamespace(parser);
161         Hashtable env = new Hashtable(environment);
162         env.put(RemoteContext.NAMING_PROVIDER, provider);
163         env.put(RemoteContext.NAMESPACE, namespace);
164         return new RemoteContext(env, parser.parse(""));
165     }
166 
167     /***
168      * Returns the RMI url using the old environment properties, logging a
169      * warning. This method will be removed in future releases
170      */
171     private String getDeprecatedEnvironment(Hashtable environment) {
172         _log.warn(
173             getClass().getName()
174             + ": using deprecated environment. Use Context.PROVIDER_URL");
175 
176         StringBuffer url = new StringBuffer("rmi://");
177         String host = (String) environment.get(JndiConstants.HOST_PROPERTY);
178         Integer port = (Integer) environment.get(
179             JndiConstants.PORT_NUMBER_PROPERTY);
180         String name = (String) environment.get(JndiConstants.NAME_PROPERTY);
181 
182         // if the host is specified then use it, otherwise use localhost
183         if (host != null) {
184             url.append(host);
185             url.append(":");
186         } else {
187             url.append("localhost:");
188         }
189 
190         // if the port has been specified then use it otherwise use
191         // the default port
192         if (port != null) {
193             url.append(port.toString());
194             url.append("/");
195         } else {
196             url.append("1099/");
197         }
198 
199         // now append the server name
200         if (name != null) {
201             url.append(name);
202         } else {
203             url.append("JndiServer");
204         }
205         return url.toString();
206     }
207 
208 } //-- RmiJndiInitialContextFactory