001: /*
002: * JBoss, Home of Professional Open Source.
003: * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004: * as indicated by the @author tags. See the copyright.txt file in the
005: * distribution for a full listing of individual contributors.
006: *
007: * This is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as
009: * published by the Free Software Foundation; either version 2.1 of
010: * the License, or (at your option) any later version.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this software; if not, write to the Free
019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021: */
022: package org.jboss.naming;
023:
024: import java.io.InputStream;
025: import java.io.IOException;
026: import java.io.ObjectInputStream;
027: import java.net.HttpURLConnection;
028: import java.net.URL;
029: import java.util.Hashtable;
030: import java.lang.reflect.InvocationTargetException;
031: import javax.naming.Context;
032: import javax.naming.Name;
033: import javax.naming.NamingException;
034: import javax.naming.Reference;
035: import javax.naming.RefAddr;
036: import javax.naming.spi.InitialContextFactory;
037: import javax.naming.spi.ObjectFactory;
038:
039: import org.jboss.invocation.InvocationException;
040: import org.jboss.invocation.MarshalledValue;
041: import org.jboss.invocation.http.interfaces.Util;
042: import org.jboss.logging.Logger;
043: import org.jnp.interfaces.Naming;
044: import org.jnp.interfaces.NamingContext;
045:
046: /** A naming provider InitialContextFactory implementation that obtains a
047: Naming proxy from an HTTP URL.
048:
049: @see javax.naming.spi.InitialContextFactory
050:
051: @author Scott.Stark@jboss.org
052: @version $Revision: 57209 $
053: */
054: public class HttpNamingContextFactory implements InitialContextFactory,
055: ObjectFactory {
056: private static Logger log = Logger
057: .getLogger(HttpNamingContextFactory.class);
058:
059: // InitialContextFactory implementation --------------------------
060: public Context getInitialContext(Hashtable env)
061: throws NamingException {
062: // Parse the Context.PROVIDER_URL
063: String provider = (String) env.get(Context.PROVIDER_URL);
064: if (provider.startsWith("jnp:") == true)
065: provider = "http:" + provider.substring(4);
066: else if (provider.startsWith("jnps:") == true)
067: provider = "https:" + provider.substring(5);
068: else if (provider.startsWith("jnp-http:") == true)
069: provider = "http:" + provider.substring(9);
070: else if (provider.startsWith("jnp-https:") == true)
071: provider = "https:" + provider.substring(10);
072:
073: URL providerURL = null;
074: Naming namingServer = null;
075: try {
076: providerURL = new URL(provider);
077: // Retrieve the Naming interface
078: namingServer = getNamingServer(providerURL);
079: } catch (Exception e) {
080: NamingException ex = new NamingException(
081: "Failed to retrieve Naming interface");
082: ex.setRootCause(e);
083: throw ex;
084: }
085:
086: // Copy the context env
087: env = (Hashtable) env.clone();
088: return new NamingContext(env, null, namingServer);
089: }
090:
091: // ObjectFactory implementation ----------------------------------
092: public Object getObjectInstance(Object obj, Name name,
093: Context nameCtx, Hashtable env) throws Exception {
094: Context ctx = getInitialContext(env);
095: Reference ref = (Reference) obj;
096: RefAddr addr = ref.get("URL");
097: String path = (String) addr.getContent();
098: return ctx.lookup(path);
099: }
100:
101: /** Obtain the JNDI Naming stub by reading its marshalled object from the
102: * servlet specified by the providerURL
103: *
104: * @param providerURL the naming factory servlet URL
105: * @return
106: * @throws ClassNotFoundException throw during unmarshalling
107: * @throws IOException thrown on any trasport failure
108: * @throws InvocationTargetException throw on failure to install a JSSE host verifier
109: * @throws IllegalAccessException throw on failure to install a JSSE host verifier
110: */
111: private Naming getNamingServer(URL providerURL)
112: throws ClassNotFoundException, IOException,
113: InvocationTargetException, IllegalAccessException {
114: // Initialize the proxy Util class to integrate JAAS authentication
115: Util.init();
116: if (log.isTraceEnabled())
117: log.trace("Retrieving content from : " + providerURL);
118:
119: HttpURLConnection conn = (HttpURLConnection) providerURL
120: .openConnection();
121: Util.configureHttpsHostVerifier(conn);
122: Util.configureSSLSocketFactory(conn);
123: int length = conn.getContentLength();
124: String type = conn.getContentType();
125: if (log.isTraceEnabled())
126: log.trace("ContentLength: " + length + "\nContentType: "
127: + type);
128:
129: InputStream is = conn.getInputStream();
130: ObjectInputStream ois = new ObjectInputStream(is);
131: MarshalledValue mv = (MarshalledValue) ois.readObject();
132: ois.close();
133:
134: Object obj = mv.get();
135: if ((obj instanceof Naming) == false) {
136: String msg = "Invalid reply content seen: "
137: + obj.getClass();
138: Throwable t = null;
139: if (obj instanceof Throwable) {
140: t = (Throwable) obj;
141: if (t instanceof InvocationException)
142: t = ((InvocationException) t).getTargetException();
143: }
144: if (t != null)
145: log.warn(msg, t);
146: else
147: log.warn(msg);
148: IOException e = new IOException(msg);
149: throw e;
150: }
151: Naming namingServer = (Naming) obj;
152: return namingServer;
153: }
154: }
|