KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > mx4j > remote > ConnectionResolver


1 /*
2  * Copyright (C) The MX4J Contributors.
3  * All rights reserved.
4  *
5  * This software is distributed under the terms of the MX4J License version 1.0.
6  * See the terms of the MX4J License in the documentation provided with this software.
7  */

8
9 package mx4j.remote;
10
11 import java.io.IOException JavaDoc;
12 import java.util.Map JavaDoc;
13 import java.util.StringTokenizer JavaDoc;
14
15 import javax.management.remote.JMXConnectorServerFactory JavaDoc;
16 import javax.management.remote.JMXServiceURL JavaDoc;
17
18 import mx4j.log.Logger;
19
20 /**
21  * ConnectionResolver handles the details of creating connections for different protocols.
22  * Subclasses for the specific protocol are instantiated using a mechanism very similar to the
23  * one specified by {@link javax.management.remote.JMXConnectorFactory}. Here a subclass
24  * has a fully qualified name specified like this:
25  * <package>.resolver.<protocol>.Resolver, for example
26  * {@link mx4j.remote.resolver.rmi.Resolver}
27  * This class is used from both the client and the server.
28  * The former uses it to lookup stubs or connections to the server side; the latter uses it
29  * to create server instances and make them availale to clients, for example via JNDI.
30  * The client and server methods have not been splitted into 2 different interfaces because
31  * most of the times they share common code, although it may have been a better design.
32  *
33  * @version $Revision: 1.6 $
34  */

35 public abstract class ConnectionResolver extends ProviderHelper
36 {
37    /**
38     * Returns a subclass of ConnectionResolver for the specified protocol.
39     */

40    public static ConnectionResolver newConnectionResolver(String JavaDoc proto, Map JavaDoc environment)
41    {
42       String JavaDoc protocol = normalizeProtocol(proto);
43       String JavaDoc resolverPackages = findResolverPackageList();
44       ClassLoader JavaDoc classLoader = findResolverClassLoader(environment, JMXConnectorServerFactory.PROTOCOL_PROVIDER_CLASS_LOADER);
45       return loadResolver(resolverPackages, protocol, classLoader);
46    }
47
48    private static String JavaDoc findResolverPackageList()
49    {
50       String JavaDoc packages = findSystemPackageList(MX4JRemoteConstants.PROTOCOL_RESOLVER_PACKAGES);
51       if (packages == null)
52          packages = MX4JRemoteConstants.RESOLVER_PACKAGES;
53       else
54          packages += MX4JRemoteConstants.RESOLVER_PACKAGES_SEPARATOR + MX4JRemoteConstants.RESOLVER_PACKAGES;
55       Logger logger = getLogger();
56       if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Resolver packages list is: " + packages);
57       return packages;
58    }
59
60    private static ClassLoader JavaDoc findResolverClassLoader(Map JavaDoc environment, String JavaDoc loaderKey)
61    {
62       if (environment == null) return Thread.currentThread().getContextClassLoader();
63       Object JavaDoc object = environment.get(loaderKey);
64       if (object == null) return Thread.currentThread().getContextClassLoader();
65       if (!(object instanceof ClassLoader JavaDoc)) throw new IllegalArgumentException JavaDoc("Environment property " + loaderKey + " must be a ClassLoader");
66       return (ClassLoader JavaDoc)object;
67    }
68
69    private static ConnectionResolver loadResolver(String JavaDoc packages, String JavaDoc protocol, ClassLoader JavaDoc loader)
70    {
71       Logger logger = getLogger();
72
73       StringTokenizer JavaDoc tokenizer = new StringTokenizer JavaDoc(packages, MX4JRemoteConstants.RESOLVER_PACKAGES_SEPARATOR);
74       while (tokenizer.hasMoreTokens())
75       {
76          String JavaDoc pkg = tokenizer.nextToken().trim();
77          if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Resolver package: " + pkg);
78          if (pkg.length() == 0) continue;
79
80          String JavaDoc resolverClassName = constructClassName(pkg, protocol, MX4JRemoteConstants.RESOLVER_CLASS);
81
82          Class JavaDoc resolverClass = null;
83          try
84          {
85             resolverClass = loadClass(resolverClassName, loader);
86          }
87          catch (ClassNotFoundException JavaDoc x)
88          {
89             if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Resolver class " + resolverClassName + " not found, continuing with next package");
90             continue;
91          }
92          catch (Exception JavaDoc x)
93          {
94             if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Cannot load resolver class " + resolverClassName, x);
95             return null;
96          }
97
98          try
99          {
100             return (ConnectionResolver)resolverClass.newInstance();
101          }
102          catch (Exception JavaDoc x)
103          {
104             if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Cannot instantiate resolver class " + resolverClassName, x);
105             return null;
106          }
107       }
108
109       // Nothing found
110
if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Could not find resolver for protocol " + protocol + " in package list '" + packages + "'");
111       return null;
112    }
113
114    /**
115     * Looks up a connection with the server side as specified in the given JMXServiceURL.
116     * This method is used in implementations of {@link javax.management.remote.JMXConnector#connect()}.
117     *
118     * @see #bindClient
119     */

120    public abstract Object JavaDoc lookupClient(JMXServiceURL JavaDoc url, Map JavaDoc environment) throws IOException JavaDoc;
121
122    /**
123     * Connects the client returned by {@link #lookupClient} to the server side.
124     *
125     * @return An object of the same type as the client passed in; normally the client object itself
126     */

127    public abstract Object JavaDoc bindClient(Object JavaDoc client, Map JavaDoc environment) throws IOException JavaDoc;
128
129    /**
130     * Creates an instance of the server as specified in the given JMXServiceURL.
131     * It is only a factory method, it should just return a fresh instance of the server;
132     * other methods are responsible to make it available to clients (for example exporting it).
133     * This method is used in implementations of {@link javax.management.remote.JMXConnectorServer#start}.
134     *
135     * @see #bindServer
136     * @see #destroyServer
137     */

138    public abstract Object JavaDoc createServer(JMXServiceURL JavaDoc url, Map JavaDoc environment) throws IOException JavaDoc;
139
140    /**
141     * Binds the server created by {@link #createServer} to a place specified by the JMXServiceURL.
142     *
143     * @return a new JMXServiceURL that specifies where the server has been bound to.
144     * @see #unbindServer
145     */

146    public abstract JMXServiceURL JavaDoc bindServer(Object JavaDoc server, JMXServiceURL JavaDoc url, Map JavaDoc environment) throws IOException JavaDoc;
147
148    /**
149     * Unbinds the server bound by {@link #bindServer} from the place specified by the JMXServiceURL.
150     *
151     * @see #destroyServer
152     */

153    public abstract void unbindServer(Object JavaDoc server, JMXServiceURL JavaDoc address, Map JavaDoc environment) throws IOException JavaDoc;
154
155    /**
156     * Destroys the server created by {@link #createServer}, by cleaning up resources it may have requested
157     * at creation time
158     *
159     * @see #createServer
160     */

161    public abstract void destroyServer(Object JavaDoc server, JMXServiceURL JavaDoc url, Map JavaDoc environment) throws IOException JavaDoc;
162 }
163
Popular Tags