1:
38:
39:
40: package ;
41:
42: import ;
43: import ;
44: import ;
45: import ;
46: import ;
47: import ;
48: import ;
49: import ;
50: import ;
51: import ;
52: import ;
53: import ;
54: import ;
55: import ;
56: import ;
57:
58: public class UnicastServerRef
59: extends UnicastRef
60: implements ServerRef{
61:
62: final static private Class[] stubprototype = new Class[] { RemoteRef.class };
63:
64: Remote myself;
65: private Skeleton skel;
66: private RemoteStub stub;
67: private Hashtable methods = new Hashtable();
68:
69:
72: UnicastServerRef()
73: {
74: }
75:
76: public UnicastServerRef(ObjID id, int port, RMIServerSocketFactory ssf) throws RemoteException {
77: super(id);
78: manager = UnicastConnectionManager.getInstance(port, ssf);
79: }
80:
81: public RemoteStub exportObject(Remote obj) throws RemoteException {
82: if (myself == null) {
83: myself = obj;
84:
85:
86: manager.serverobj = obj;
87:
88:
89: Class cls = obj.getClass();
90: Class expCls;
91: try {
92:
93: expCls = findStubSkelClass(cls);
94: } catch (Exception ex) {
95: throw new RemoteException("can not find stubs for class: " + cls, ex);
96: }
97:
98: stub = (RemoteStub)getHelperClass(expCls, "_Stub");
99: if (stub == null) {
100: throw new RemoteException("failed to export: " + cls);
101: }
102:
103:
104: skel = (Skeleton)getHelperClass(expCls, "_Skel");
105:
106:
107: buildMethodHash(obj.getClass(), true);
108:
109:
110: UnicastServer.exportObject(this);
111: }
112:
113: return (stub);
114: }
115:
116: public RemoteStub exportObject(Remote remote, Object obj)
117: throws RemoteException
118: {
119:
120: return exportObject(remote);
121: }
122:
123: public RemoteStub getStub(){
124: return stub;
125: }
126:
127:
128: public boolean unexportObject(Remote obj, boolean force) {
129:
130: buildMethodHash(obj.getClass(), false);
131: return UnicastServer.unexportObject(this, force);
132: }
133:
134:
140: private Class findStubSkelClass(Class startCls) throws Exception {
141: Class cls = startCls;
142:
143: while (true) {
144: try {
145: String stubClassname = cls.getName() + "_Stub";
146: ClassLoader cl = cls.getClassLoader();
147: Class scls = cl == null ? Class.forName(stubClassname)
148: : cl.loadClass(stubClassname);
149: return cls;
150: } catch (ClassNotFoundException e) {
151: Class superCls = cls.getSuperclass();
152: if (superCls == null
153: || superCls == java.rmi.server.UnicastRemoteObject.class)
154: {
155: throw new Exception("Neither " + startCls
156: + " nor one of their superclasses (like" + cls + ")"
157: + " has a _Stub");
158: }
159: cls = superCls;
160: }
161: }
162: }
163:
164:
165:
166: private Object getHelperClass(Class cls, String type) {
167: try {
168: String classname = cls.getName();
169: ClassLoader cl = cls.getClassLoader();
170: Class scls = cl == null ? Class.forName(classname + type)
171: : cl.loadClass(classname + type);
172: if (type.equals("_Stub")) {
173: try {
174:
175: Constructor con = scls.getConstructor(stubprototype);
176: return (con.newInstance(new Object[]{this}));
177: }
178: catch (NoSuchMethodException e) {
179: }
180: catch (InstantiationException e) {
181: }
182: catch (IllegalAccessException e) {
183: }
184: catch (IllegalArgumentException e) {
185: }
186: catch (InvocationTargetException e) {
187: }
188:
189: RemoteStub stub = (RemoteStub)scls.newInstance();
190: UnicastRemoteStub.setStubRef(stub, this);
191: return (stub);
192: }
193: else {
194:
195: return (scls.newInstance());
196: }
197: }
198: catch (ClassNotFoundException e) {
199: }
200: catch (InstantiationException e) {
201: }
202: catch (IllegalAccessException e) {
203: }
204: return (null);
205: }
206:
207:
208:
209: public String getClientHost() throws ServerNotActiveException {
210: return RemoteServer.getClientHost();
211: }
212:
213: private void buildMethodHash(Class cls, boolean build) {
214: Method[] meths = cls.getMethods();
215: for (int i = 0; i < meths.length; i++) {
216:
217: if (meths[i].getDeclaringClass().getName().startsWith("java.")) {
218: continue;
219: }
220: long hash = RMIHashes.getMethodHash(meths[i]);
221: if(build)
222: methods.put(new Long (hash), meths[i]);
223: else
224: methods.remove(new Long (hash));
225:
226: }
227: }
228:
229: Class getMethodReturnType(int method, long hash) throws Exception
230: {
231: if (method == -1) {
232: Method meth = (Method)methods.get(new Long (hash));
233: return meth.getReturnType();
234: }else
235: return null;
236: }
237:
238: public Object incomingMessageCall(UnicastConnection conn, int method, long hash) throws Exception {
239:
240:
241:
242: if (method == -1) {
243: Method meth = (Method)methods.get(new Long (hash));
244:
245: if (meth == null) {
246: throw new NoSuchMethodException();
247: }
248:
249: ObjectInputStream in = conn.getObjectInputStream();
250: int nrargs = meth.getParameterTypes().length;
251: Object[] args = new Object[nrargs];
252: for (int i = 0; i < nrargs; i++) {
253:
258: try {
259:
260: args[i] = ((RMIObjectInputStream)in).readValue(meth.getParameterTypes()[i]);
261:
262: }
263: catch (Exception t) {
264: t.printStackTrace();
265: throw t;
266: }
267: }
268:
269:
270: Object ret = null;
271: try{
272: ret = meth.invoke(myself, args);
273: }catch(InvocationTargetException e){
274: Throwable cause = e.getTargetException();
275: if (cause instanceof Exception) {
276: throw (Exception)cause;
277: }
278: else if (cause instanceof Error) {
279: throw (Error)cause;
280: }
281: else {
282: throw new Error("The remote method threw a java.lang.Throwable that is neither java.lang.Exception nor java.lang.Error.", e);
283: }
284: }
285: return ret;
286: }
287:
288:
289:
290:
291: else {
292: if (skel == null) {
293: throw new NoSuchMethodException();
294: }
295: UnicastRemoteCall call = new UnicastRemoteCall(conn);
296: skel.dispatch(myself, call, method, hash);
297: if (!call.isReturnValue())
298: return RMIVoidValue.INSTANCE;
299: else
300: return (call.returnValue());
301: }
302: }
303:
304: }
305: