1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.gwe.utils;
18
19 import java.net.URI;
20 import java.net.URISyntaxException;
21 import java.net.UnknownHostException;
22 import java.rmi.NotBoundException;
23 import java.rmi.Remote;
24 import java.rmi.RemoteException;
25 import java.rmi.registry.LocateRegistry;
26 import java.rmi.registry.Registry;
27 import java.rmi.server.RMIClientSocketFactory;
28
29 import org.apache.commons.logging.Log;
30 import org.apache.commons.logging.LogFactory;
31
32
33
34
35
36 public class RemoteResolver<RT extends Remote> implements Runnable {
37
38 private static Log log = LogFactory.getLog(RemoteResolver.class);
39
40 private RT remoteObj = null;
41 private String[] servicesList = null;
42 private RemoteException rex = null;
43 private NotBoundException nbex = null;
44 private URI uriObj;
45 private Thread resolverThread = null;
46 private boolean list = false;
47 private RMIClientSocketFactory socketFactory;
48
49 public RemoteResolver(String uriStr, RMIClientSocketFactory socketFactory) throws URISyntaxException, UnknownHostException {
50 this.uriObj = new URI(uriStr);
51 this.socketFactory = socketFactory;
52 }
53
54 public RT getRemote(long waitMillis) throws RemoteException, NotBoundException, ConnectionTimeoutException {
55 return (RT)getRegistryInformation(waitMillis, false);
56 }
57
58 public String[] getList(long waitMillis) throws RemoteException, NotBoundException, ConnectionTimeoutException {
59 return (String[])getRegistryInformation(waitMillis, true);
60 }
61
62 public synchronized <INFO_TYPE extends Object> INFO_TYPE getRegistryInformation(long waitMillis, boolean list) throws RemoteException, NotBoundException, ConnectionTimeoutException {
63 if (resolverThread != null) return null;
64 this.list = list;
65 resolverThread = new Thread(this);
66 resolverThread.start();
67 long timeout;
68 long end = System.currentTimeMillis() + waitMillis;
69 while ((timeout = end - System.currentTimeMillis()) > 0) {
70 try {
71 this.wait(timeout);
72 } catch (InterruptedException e) {}
73 INFO_TYPE info = (INFO_TYPE) ((list) ? servicesList : remoteObj);
74 if (info != null) return info;
75 if (rex != null) throw rex;
76 if (nbex != null) throw nbex;
77 }
78
79
80 throw new ConnectionTimeoutException(uriObj.toString(), timeout);
81 }
82
83 public void run() {
84 try {
85 log.info("Retrieving remote registry '" + uriObj.getHost() + ":" + uriObj.getPort() + "'...");
86 Registry registry = LocateRegistry.getRegistry(uriObj.getHost(), uriObj.getPort(), socketFactory);
87 log.info("Registry obtained! " + registry);
88 log.info("Retrieving remote object '" + uriObj.toString() + "'...");
89 RT rObj = null;
90 String[] sList = null;
91 if (list)
92 sList = registry.list();
93 else
94 rObj = (RT) registry.lookup(uriObj.getPath().substring(1));
95 log.info("Remote proxy object created: '" + rObj + "'. Actual object at '" + uriObj.toString() + "'");
96 synchronized (this) {
97 remoteObj = rObj;
98 servicesList = sList;
99 close();
100 }
101 } catch (RemoteException e) {
102 synchronized (this) {
103 this.rex = e;
104 close();
105 }
106 } catch (NotBoundException e) {
107 synchronized (this) {
108 this.nbex = e;
109 close();
110 }
111 }
112 }
113
114 private synchronized void close() {
115 resolverThread = null;
116 this.notifyAll();
117 }
118
119 }
120
121 class ConnectionTimeoutException extends Exception {
122
123 public ConnectionTimeoutException(String uriStr, long timeout) {
124 super("Timeout reached! No exception or sucessful response received from '" + uriStr + "' within " + timeout / 1000 + " seconds");
125 }
126 }