KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > mx4j > remote > resolver > rmi > Resolver


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.resolver.rmi;
10
11 import java.io.ByteArrayInputStream JavaDoc;
12 import java.io.ByteArrayOutputStream JavaDoc;
13 import java.io.IOException JavaDoc;
14 import java.io.ObjectInputStream JavaDoc;
15 import java.io.ObjectOutputStream JavaDoc;
16 import java.net.MalformedURLException JavaDoc;
17 import java.rmi.Remote JavaDoc;
18 import java.rmi.server.RMIClientSocketFactory JavaDoc;
19 import java.rmi.server.RMIServerSocketFactory JavaDoc;
20 import java.util.Hashtable JavaDoc;
21 import java.util.Map JavaDoc;
22
23 import javax.management.remote.JMXServiceURL JavaDoc;
24 import javax.management.remote.rmi.RMIConnectorServer JavaDoc;
25 import javax.management.remote.rmi.RMIJRMPServerImpl JavaDoc;
26 import javax.management.remote.rmi.RMIServer JavaDoc;
27 import javax.management.remote.rmi.RMIServerImpl JavaDoc;
28 import javax.naming.InitialContext JavaDoc;
29 import javax.naming.NamingException JavaDoc;
30
31 import mx4j.log.Logger;
32 import mx4j.remote.ConnectionResolver;
33 import mx4j.util.Base64Codec;
34
35 /**
36  * Resolver for RMI/JRMP protocol.
37  *
38  * @version $Revision: 1.3 $
39  */

40 public class Resolver extends ConnectionResolver
41 {
42    private static final String JavaDoc JNDI_CONTEXT = "/jndi/";
43    private static final String JavaDoc STUB_CONTEXT = "/stub/";
44
45
46 //********************************************************************************************************************//
47
// CLIENT METHODS
48

49
50    public Object JavaDoc lookupClient(JMXServiceURL JavaDoc url, Map JavaDoc environment) throws IOException JavaDoc
51    {
52       return lookupRMIServerStub(url, environment);
53    }
54
55    public Object JavaDoc bindClient(Object JavaDoc client, Map JavaDoc environment) throws IOException JavaDoc
56    {
57       // JRMP does not need anything special
58
return client;
59    }
60
61    protected RMIServer JavaDoc lookupRMIServerStub(JMXServiceURL JavaDoc url, Map JavaDoc environment) throws IOException JavaDoc
62    {
63       Logger logger = getLogger();
64
65       String JavaDoc path = url.getURLPath();
66       if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("JMXServiceURL for lookup is: '" + url + "'");
67
68       if (path != null)
69       {
70          if (path.startsWith(JNDI_CONTEXT))
71          {
72             return lookupStubInJNDI(url, environment);
73          }
74
75          return decodeStub(url, environment);
76       }
77
78       throw new MalformedURLException JavaDoc("Unsupported lookup " + url);
79    }
80
81    protected RMIServer JavaDoc lookupStubInJNDI(JMXServiceURL JavaDoc url, Map JavaDoc environment) throws IOException JavaDoc
82    {
83       Logger logger = getLogger();
84
85       String JavaDoc path = url.getURLPath();
86       String JavaDoc name = path.substring(JNDI_CONTEXT.length());
87       if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Looking up RMI stub in JNDI under name " + name);
88
89       InitialContext JavaDoc ctx = null;
90       try
91       {
92          ctx = new InitialContext JavaDoc(new Hashtable JavaDoc(environment));
93          Object JavaDoc stub = ctx.lookup(name);
94          if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Found RMI stub in JNDI " + stub);
95          return narrowRMIServerStub(stub);
96       }
97       catch (NamingException JavaDoc x)
98       {
99          if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Cannot lookup RMI stub in JNDI", x);
100          throw new IOException JavaDoc(x.toString());
101       }
102       finally
103       {
104          try
105          {
106             if (ctx != null) ctx.close();
107          }
108          catch (NamingException JavaDoc x)
109          {
110             if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Cannot close InitialContext", x);
111          }
112       }
113    }
114
115    protected RMIServer JavaDoc narrowRMIServerStub(Object JavaDoc stub)
116    {
117       return (RMIServer JavaDoc)stub;
118    }
119
120    protected RMIServer JavaDoc decodeStub(JMXServiceURL JavaDoc url, Map JavaDoc environment) throws IOException JavaDoc
121    {
122       String JavaDoc path = url.getURLPath();
123       if (path.startsWith(STUB_CONTEXT))
124       {
125          byte[] encoded = path.substring(STUB_CONTEXT.length()).getBytes();
126          if (!Base64Codec.isArrayByteBase64(encoded)) throw new IOException JavaDoc("Encoded stub form is not a valid Base64 sequence: " + url);
127          byte[] decoded = Base64Codec.decodeBase64(encoded);
128          ByteArrayInputStream JavaDoc bais = new ByteArrayInputStream JavaDoc(decoded);
129          ObjectInputStream JavaDoc ois = null;
130          try
131          {
132             ois = new ObjectInputStream JavaDoc(bais);
133             return (RMIServer JavaDoc)ois.readObject();
134          }
135          catch (ClassNotFoundException JavaDoc x)
136          {
137             throw new IOException JavaDoc("Cannot decode stub from " + url + ": " + x);
138          }
139          finally
140          {
141             if (ois != null) ois.close();
142          }
143       }
144       throw new MalformedURLException JavaDoc("Unsupported binding: " + url);
145    }
146
147
148 //********************************************************************************************************************//
149
// SERVER METHODS
150

151
152    public Object JavaDoc createServer(JMXServiceURL JavaDoc url, Map JavaDoc environment) throws IOException JavaDoc
153    {
154       return createRMIServer(url, environment);
155    }
156
157    protected RMIServerImpl JavaDoc createRMIServer(JMXServiceURL JavaDoc url, Map JavaDoc environment) throws IOException JavaDoc
158    {
159       int port = url.getPort();
160       RMIClientSocketFactory JavaDoc clientFactory = (RMIClientSocketFactory JavaDoc)environment.get(RMIConnectorServer.RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE);
161       RMIServerSocketFactory JavaDoc serverFactory = (RMIServerSocketFactory JavaDoc)environment.get(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE);
162       return new RMIJRMPServerImpl JavaDoc(port, clientFactory, serverFactory, environment);
163    }
164
165    public JMXServiceURL JavaDoc bindServer(Object JavaDoc server, JMXServiceURL JavaDoc url, Map JavaDoc environment) throws IOException JavaDoc
166    {
167       // See javax/management/remote/rmi/package-summary.html
168

169       RMIServerImpl JavaDoc rmiServer = (RMIServerImpl JavaDoc)server;
170
171       Logger logger = getLogger();
172       if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("JMXServiceURL for binding is: '" + url + "'");
173
174       if (isEncodedForm(url))
175       {
176          String JavaDoc path = encodeStub(rmiServer, environment);
177          return new JMXServiceURL JavaDoc(url.getProtocol(), url.getHost(), url.getPort(), path);
178       }
179       else
180       {
181          String JavaDoc jndiURL = parseJNDIForm(url);
182          if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("JMXServiceURL path for binding is: '" + jndiURL + "'");
183
184          InitialContext JavaDoc ctx = null;
185          try
186          {
187             ctx = new InitialContext JavaDoc(new Hashtable JavaDoc(environment));
188             boolean rebind = Boolean.valueOf((String JavaDoc)environment.get(RMIConnectorServer.JNDI_REBIND_ATTRIBUTE)).booleanValue();
189             if (rebind)
190                ctx.rebind(jndiURL, rmiServer.toStub());
191             else
192                ctx.bind(jndiURL, rmiServer.toStub());
193             if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Bound " + rmiServer + " to " + jndiURL);
194             return url;
195          }
196          catch (NamingException JavaDoc x)
197          {
198             if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Cannot bind server " + rmiServer + " to " + jndiURL, x);
199             throw new IOException JavaDoc(x.toString());
200          }
201          finally
202          {
203             try
204             {
205                if (ctx != null) ctx.close();
206             }
207             catch (NamingException JavaDoc x)
208             {
209                if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Cannot close InitialContext", x);
210             }
211          }
212       }
213    }
214
215    protected String JavaDoc encodeStub(RMIServerImpl JavaDoc rmiServer, Map JavaDoc environment) throws IOException JavaDoc
216    {
217       Remote JavaDoc stub = rmiServer.toStub();
218       ByteArrayOutputStream JavaDoc baos = new ByteArrayOutputStream JavaDoc();
219       ObjectOutputStream JavaDoc oos = null;
220       try
221       {
222          oos = new ObjectOutputStream JavaDoc(baos);
223          oos.writeObject(stub);
224       }
225       finally
226       {
227          if (oos != null) oos.close();
228       }
229       byte[] bytes = baos.toByteArray();
230       byte[] encoded = Base64Codec.encodeBase64(bytes);
231       // Since the bytes are base 64 bytes, the encoding in creating the string is not important: any will work
232
return STUB_CONTEXT + new String JavaDoc(encoded);
233    }
234
235    protected boolean isEncodedForm(JMXServiceURL JavaDoc url)
236    {
237       String JavaDoc path = url.getURLPath();
238       if (path == null || path.length() == 0 || "/".equals(path) || path.startsWith(STUB_CONTEXT)) return true;
239       return false;
240    }
241
242    private String JavaDoc parseJNDIForm(JMXServiceURL JavaDoc url) throws MalformedURLException JavaDoc
243    {
244       String JavaDoc path = url.getURLPath();
245       if (path.startsWith(JNDI_CONTEXT))
246       {
247          String JavaDoc jndiURL = path.substring(JNDI_CONTEXT.length());
248          if (jndiURL == null || jndiURL.length() == 0) throw new MalformedURLException JavaDoc("No JNDI URL specified: " + url);
249          return jndiURL;
250       }
251       throw new MalformedURLException JavaDoc("Unsupported binding: " + url);
252    }
253
254    public void unbindServer(Object JavaDoc server, JMXServiceURL JavaDoc url, Map JavaDoc environment) throws IOException JavaDoc
255    {
256       Logger logger = getLogger();
257       if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("JMXServiceURL for unbinding is: '" + url + "'");
258
259       // The server was not bound to JNDI (the stub was encoded), just return
260
if (isEncodedForm(url))
261       {
262          return;
263       }
264       else
265       {
266          String JavaDoc jndiURL = parseJNDIForm(url);
267          if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("JMXServiceURL path for unbinding is: '" + jndiURL + "'");
268
269          InitialContext JavaDoc ctx = null;
270          try
271          {
272             ctx = new InitialContext JavaDoc(new Hashtable JavaDoc(environment));
273             ctx.unbind(jndiURL);
274             if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Unbound " + server + " from " + jndiURL);
275          }
276          catch (NamingException JavaDoc x)
277          {
278             if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Cannot unbind server " + server + " to " + jndiURL, x);
279             throw new IOException JavaDoc(x.toString());
280          }
281          finally
282          {
283             try
284             {
285                if (ctx != null) ctx.close();
286             }
287             catch (NamingException JavaDoc x)
288             {
289                if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Cannot close InitialContext", x);
290             }
291          }
292       }
293    }
294
295    public void destroyServer(Object JavaDoc server, JMXServiceURL JavaDoc url, Map JavaDoc environment) throws IOException JavaDoc
296    {
297    }
298 }
299
Popular Tags