KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > mx4j > remote > ProviderFactory


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.BufferedReader JavaDoc;
12 import java.io.IOException JavaDoc;
13 import java.io.InputStream JavaDoc;
14 import java.io.InputStreamReader JavaDoc;
15 import java.net.MalformedURLException JavaDoc;
16 import java.net.URL JavaDoc;
17 import java.security.AccessController JavaDoc;
18 import java.security.PrivilegedActionException JavaDoc;
19 import java.security.PrivilegedExceptionAction JavaDoc;
20 import java.util.ArrayList JavaDoc;
21 import java.util.Collections JavaDoc;
22 import java.util.Enumeration JavaDoc;
23 import java.util.List JavaDoc;
24 import java.util.Map JavaDoc;
25 import java.util.StringTokenizer JavaDoc;
26
27 import javax.management.MBeanServer JavaDoc;
28 import javax.management.remote.JMXConnector JavaDoc;
29 import javax.management.remote.JMXConnectorFactory JavaDoc;
30 import javax.management.remote.JMXConnectorProvider JavaDoc;
31 import javax.management.remote.JMXConnectorServer JavaDoc;
32 import javax.management.remote.JMXConnectorServerFactory JavaDoc;
33 import javax.management.remote.JMXConnectorServerProvider JavaDoc;
34 import javax.management.remote.JMXProviderException JavaDoc;
35 import javax.management.remote.JMXServiceURL JavaDoc;
36
37 import mx4j.log.Logger;
38
39 /**
40  * @version $Revision: 1.8 $
41  */

42 public class ProviderFactory extends ProviderHelper
43 {
44    public static JMXConnector JavaDoc newJMXConnector(JMXServiceURL JavaDoc url, Map JavaDoc env) throws IOException JavaDoc
45    {
46       // Yes, throw NPE if url is null (spec compliant)
47
String JavaDoc protocol = normalizeProtocol(url.getProtocol());
48       String JavaDoc providerPackages = findProviderPackageList(env, JMXConnectorFactory.PROTOCOL_PROVIDER_PACKAGES);
49       ClassLoader JavaDoc classLoader = findProviderClassLoader(env, JMXConnectorFactory.PROTOCOL_PROVIDER_CLASS_LOADER);
50       List JavaDoc providers = loadProviders(JMXConnectorProvider JavaDoc.class, providerPackages, protocol, MX4JRemoteConstants.CLIENT_PROVIDER_CLASS, classLoader);
51       for (int i = 0; i < providers.size(); i++)
52       {
53          JMXConnectorProvider JavaDoc provider = (JMXConnectorProvider JavaDoc)providers.get(i);
54          try
55          {
56             return provider.newJMXConnector(url, Collections.unmodifiableMap(env));
57          }
58          catch (JMXProviderException JavaDoc x)
59          {
60             throw x;
61          }
62          catch (IOException JavaDoc x)
63          {
64             continue;
65          }
66       }
67       throw new MalformedURLException JavaDoc("Could not find provider for protocol " + protocol);
68    }
69
70    public static JMXConnectorServer JavaDoc newJMXConnectorServer(JMXServiceURL JavaDoc url, Map JavaDoc env, MBeanServer JavaDoc server) throws IOException JavaDoc
71    {
72       // Yes, throw NPE if url is null (spec compliant)
73
String JavaDoc protocol = normalizeProtocol(url.getProtocol());
74       String JavaDoc providerPackages = findProviderPackageList(env, JMXConnectorServerFactory.PROTOCOL_PROVIDER_PACKAGES);
75       ClassLoader JavaDoc classLoader = findProviderClassLoader(env, JMXConnectorServerFactory.PROTOCOL_PROVIDER_CLASS_LOADER);
76       List JavaDoc providers = loadProviders(JMXConnectorServerProvider JavaDoc.class, providerPackages, protocol, MX4JRemoteConstants.SERVER_PROVIDER_CLASS, classLoader);
77       for (int i = 0; i < providers.size(); i++)
78       {
79          JMXConnectorServerProvider JavaDoc provider = (JMXConnectorServerProvider JavaDoc)providers.get(i);
80          try
81          {
82             return provider.newJMXConnectorServer(url, Collections.unmodifiableMap(env), server);
83          }
84          catch (JMXProviderException JavaDoc x)
85          {
86             throw x;
87          }
88          catch (IOException JavaDoc x)
89          {
90             continue;
91          }
92       }
93       throw new MalformedURLException JavaDoc("Could not find provider for protocol " + protocol);
94    }
95
96    /**
97     * public static JMXConnectorProvider newJMXConnectorProvider(JMXServiceURL url, Map env) throws IOException
98     * {
99     * // Yes, throw NPE if url is null (spec compliant)
100     * String protocol = normalizeProtocol(url.getProtocol());
101     * String providerPackages = findProviderPackageList(env, JMXConnectorFactory.PROTOCOL_PROVIDER_PACKAGES);
102     * ClassLoader classLoader = findProviderClassLoader(env, JMXConnectorFactory.PROTOCOL_PROVIDER_CLASS_LOADER);
103     * JMXConnectorProvider provider = (JMXConnectorProvider)loadProvider(JMXConnectorProvider.class, providerPackages, protocol, MX4JRemoteConstants.CLIENT_PROVIDER_CLASS, classLoader);
104     * return provider;
105     * }
106     * <p/>
107     * public static JMXConnectorServerProvider newJMXConnectorServerProvider(JMXServiceURL url, Map env) throws IOException
108     * {
109     * // Yes, throw NPE if url is null (spec compliant)
110     * String protocol = normalizeProtocol(url.getProtocol());
111     * String providerPackages = findProviderPackageList(env, JMXConnectorServerFactory.PROTOCOL_PROVIDER_PACKAGES);
112     * ClassLoader classLoader = findProviderClassLoader(env, JMXConnectorServerFactory.PROTOCOL_PROVIDER_CLASS_LOADER);
113     * JMXConnectorServerProvider provider = (JMXConnectorServerProvider)loadProvider(JMXConnectorServerProvider.class, providerPackages, protocol, MX4JRemoteConstants.SERVER_PROVIDER_CLASS, classLoader);
114     * return provider;
115     * }
116     */

117    private static String JavaDoc findEnvironmentProviderPackageList(Map JavaDoc environment, String JavaDoc key) throws JMXProviderException JavaDoc
118    {
119       String JavaDoc providerPackages = null;
120       if (environment != null)
121       {
122          Logger logger = getLogger();
123          Object JavaDoc pkgs = environment.get(key);
124          if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Provider packages in the environment: " + pkgs);
125          if (pkgs != null && !(pkgs instanceof String JavaDoc)) throw new JMXProviderException JavaDoc("Provider package list must be a string");
126          providerPackages = (String JavaDoc)pkgs;
127       }
128       return providerPackages;
129    }
130
131    private static String JavaDoc findProviderPackageList(Map JavaDoc environment, final String JavaDoc providerPkgsKey) throws JMXProviderException JavaDoc
132    {
133       // 1. Look in the environment
134
// 2. Look for system property
135
// 3. Use implementation's provider
136

137       String JavaDoc providerPackages = findEnvironmentProviderPackageList(environment, providerPkgsKey);
138
139       if (providerPackages == null)
140       {
141          providerPackages = findSystemPackageList(providerPkgsKey);
142       }
143
144       if (providerPackages != null && providerPackages.trim().length() == 0) throw new JMXProviderException JavaDoc("Provider package list cannot be an empty string");
145
146       if (providerPackages == null)
147          providerPackages = MX4JRemoteConstants.PROVIDER_PACKAGES;
148       else
149          providerPackages += MX4JRemoteConstants.PROVIDER_PACKAGES_SEPARATOR + MX4JRemoteConstants.PROVIDER_PACKAGES;
150
151       Logger logger = getLogger();
152       if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Provider packages list is: " + providerPackages);
153
154       return providerPackages;
155    }
156
157    private static ClassLoader JavaDoc findProviderClassLoader(Map JavaDoc environment, String JavaDoc providerLoaderKey)
158    {
159       Logger logger = getLogger();
160
161       ClassLoader JavaDoc classLoader = null;
162       if (environment != null)
163       {
164          Object JavaDoc loader = environment.get(providerLoaderKey);
165          if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Provider classloader in the environment: " + loader);
166          if (loader != null && !(loader instanceof ClassLoader JavaDoc)) throw new IllegalArgumentException JavaDoc("Provider classloader is not a ClassLoader");
167          classLoader = (ClassLoader JavaDoc)loader;
168       }
169
170       if (classLoader == null)
171       {
172          classLoader = Thread.currentThread().getContextClassLoader();
173          if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Provider classloader in the environment: " + classLoader);
174       }
175
176       // Add the classloader as required by the spec
177
environment.put(JMXConnectorFactory.PROTOCOL_PROVIDER_CLASS_LOADER, classLoader);
178       if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Provider classloader added to the environment");
179
180       return classLoader;
181    }
182
183    private static List JavaDoc loadProviders(Class JavaDoc providerType, String JavaDoc packages, String JavaDoc protocol, String JavaDoc className, ClassLoader JavaDoc loader) throws JMXProviderException JavaDoc
184    {
185       Logger logger = getLogger();
186       List JavaDoc result = new ArrayList JavaDoc();
187
188       StringTokenizer JavaDoc tokenizer = new StringTokenizer JavaDoc(packages, MX4JRemoteConstants.PROVIDER_PACKAGES_SEPARATOR);
189       while (tokenizer.hasMoreTokens())
190       {
191          String JavaDoc pkg = tokenizer.nextToken().trim();
192          if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Provider package: " + pkg);
193
194          // The spec states the package cannot be empty
195
if (pkg.length() == 0) throw new JMXProviderException JavaDoc("Empty package list not allowed: " + packages);
196
197          String JavaDoc providerClassName = constructClassName(pkg, protocol, className);
198
199          Class JavaDoc providerClass = null;
200          try
201          {
202             providerClass = loadClass(providerClassName, loader);
203          }
204          catch (ClassNotFoundException JavaDoc x)
205          {
206             if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Provider class " + providerClassName + " not found, " + (tokenizer.hasMoreTokens() ? "continuing with next package" : "no more packages to try"));
207             continue;
208          }
209          catch (Exception JavaDoc x)
210          {
211             if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Cannot load provider class " + providerClassName, x);
212             throw new JMXProviderException JavaDoc("Cannot load provider class " + providerClassName, x);
213          }
214
215          try
216          {
217             Object JavaDoc provider = providerClass.newInstance();
218             result.add(provider);
219          }
220          catch (Exception JavaDoc x)
221          {
222             if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Cannot instantiate provider class " + providerClassName, x);
223             throw new JMXProviderException JavaDoc("Cannot instantiate provider class " + providerClassName, x);
224          }
225       }
226
227       try
228       {
229          List JavaDoc serviceProviders = fromServiceProviders(providerType, protocol, className, loader);
230          result.addAll(serviceProviders);
231       }
232       catch (IOException JavaDoc x)
233       {
234          if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Error retrieving service providers", x);
235       }
236
237       if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Providers found are: " + result);
238       return result;
239    }
240
241    private static List JavaDoc fromServiceProviders(Class JavaDoc providerType, String JavaDoc protocol, String JavaDoc className, ClassLoader JavaDoc loader) throws IOException JavaDoc
242    {
243       String JavaDoc services = "META-INF/services/";
244
245       Logger logger = getLogger();
246       if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Loading providers from " + services);
247
248       if (loader == null) loader = Thread.currentThread().getContextClassLoader();
249       if (loader == null) loader = ClassLoader.getSystemClassLoader();
250       Enumeration JavaDoc providerURLs = loader.getResources(services + providerType.getName());
251       List JavaDoc providers = new ArrayList JavaDoc();
252       while (providerURLs.hasMoreElements())
253       {
254          final URL JavaDoc providerURL = (URL JavaDoc)providerURLs.nextElement();
255
256          InputStream JavaDoc stream = null;
257          try
258          {
259             stream = (InputStream JavaDoc)AccessController.doPrivileged(new PrivilegedExceptionAction JavaDoc()
260             {
261                public Object JavaDoc run() throws Exception JavaDoc
262                {
263                   return providerURL.openStream();
264                }
265             });
266          }
267          catch (PrivilegedActionException JavaDoc x)
268          {
269             Exception JavaDoc xx = x.getException();
270             if (xx instanceof IOException JavaDoc) throw (IOException JavaDoc)xx;
271             throw new IOException JavaDoc(xx.toString());
272          }
273
274          BufferedReader JavaDoc reader = null;
275          try
276          {
277             if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Reading provider from " + providerURL);
278             reader = new BufferedReader JavaDoc(new InputStreamReader JavaDoc(stream, "UTF-8"));
279             String JavaDoc line = null;
280             while ((line = reader.readLine()) != null)
281             {
282                int comment = line.indexOf('#');
283                if (comment >= 0) line = line.substring(0, comment);
284                line = line.trim();
285                if (line.length() == 0) continue;
286                if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Found provider '" + line + "' in " + providerURL);
287                try
288                {
289                   Class JavaDoc providerClass = loader.loadClass(line);
290                   if (providerType.isAssignableFrom(providerClass))
291                   {
292                      Object JavaDoc providerInstance = providerClass.newInstance();
293                      providers.add(providerInstance);
294                   }
295                }
296                catch (Exception JavaDoc ignored)
297                {
298                   // Skip this line and continue
299
}
300             }
301          }
302          finally
303          {
304             if (reader != null) reader.close();
305          }
306       }
307
308       return providers;
309    }
310 }
311
Popular Tags