1:
38:
39:
40: package ;
41:
42: import ;
43:
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: import ;
58: import ;
59: import ;
60: import ;
61: import ;
62: import ;
63: import ;
64:
65: public class UnicastRef
66: implements RemoteRef, ProtocolConstants
67: {
68:
69:
72: private static final long serialVersionUID = 1;
73:
74: public ObjID objid;
75:
76: UnicastConnectionManager manager;
77:
78:
82:
83:
84:
85: public UnicastRef()
86: {
87: }
88:
89: public UnicastRef(ObjID objid, String host, int port,
90: RMIClientSocketFactory csf)
91: {
92: this(objid);
93: manager = UnicastConnectionManager.getInstance(host, port, csf);
94: }
95:
96: public UnicastRef(ObjID objid)
97: {
98: this.objid = objid;
99: }
100:
101: public Object invoke(Remote obj, Method method, Object[] params, long opnum)
102: throws Exception
103: {
104:
105:
106:
107: Object svrobj = manager.serverobj;
108:
109:
110:
111:
112: if (svrobj != null && method.getDeclaringClass().isInstance(svrobj))
113: {
114:
115: Object ret = null;
116: try
117: {
118: ret = method.invoke(svrobj, params);
119: }
120: catch (InvocationTargetException e)
121: {
122: throw (Exception) e.getTargetException();
123: }
124:
125:
126: return ret;
127: }
128:
129:
130: return (invokeCommon(obj, method, params, - 1, opnum));
131: }
132:
133:
136: static long dgcSequence;
137:
138:
142: static final ObjID dgcId = new ObjID(ObjID.DGC_ID);
143:
144: ObjID[] this_id;
145:
146:
149: static int DIRTY = 1;
150:
151:
154: static final long dgcInterfaceHash = - 669196253586618813L;
155:
156:
159: public Lease notifyDGC(Lease lease) throws Exception
160: {
161: long seq;
162: synchronized (dgcId)
163: {
164: seq = dgcSequence++;
165: }
166:
167: if (this_id == null)
168: this_id = new ObjID[] { objid };
169:
170: UnicastConnection conn;
171: try
172: {
173: conn = manager.getConnection();
174: }
175: catch (IOException e1)
176: {
177: throw new RemoteException("connection failed to host: "
178: + manager.serverName, e1);
179: }
180:
181: ObjectOutputStream out;
182: DataOutputStream dout;
183: try
184: {
185: dout = conn.getDataOutputStream();
186: dout.writeByte(MESSAGE_CALL);
187:
188: out = conn.startObjectOutputStream();
189:
190: dgcId.write(out);
191:
192: out.writeInt(DIRTY);
193: out.writeLong(dgcInterfaceHash);
194:
195: RMIObjectOutputStream rout = (RMIObjectOutputStream) out;
196:
197: rout.writeValue(this_id, this_id.getClass());
198: rout.writeLong(seq);
199: rout.writeValue(lease, lease.getClass());
200:
201: out.flush();
202: }
203: catch (IOException e2)
204: {
205: throw new RemoteException("DGC call failed: ", e2);
206: }
207:
208: int returncode;
209: Object returnval;
210: DataInputStream din;
211: ObjectInputStream in;
212: UID ack;
213: try
214: {
215: din = conn.getDataInputStream();
216:
217: if ((returncode = din.readUnsignedByte()) != MESSAGE_CALL_ACK)
218: {
219: conn.disconnect();
220: throw new RemoteException("DGC Call not acked:" + returncode);
221: }
222:
223: in = conn.startObjectInputStream();
224: returncode = in.readUnsignedByte();
225: ack = UID.read(in);
226:
227: if (returncode == RETURN_NACK)
228: {
229: returnval = in.readObject();
230:
231: }
232: else
233: {
234: returnval = ((RMIObjectInputStream) in).readValue(Lease.class);
235: }
236: }
237: catch (IOException e3)
238: {
239: throw new RemoteException("DGC call return failed: ", e3);
240: }
241:
242: manager.discardConnection(conn);
243:
244: if (returncode != RETURN_ACK && returnval != null)
245: {
246: if (returncode == RETURN_NACK)
247: throw (Exception) returnval;
248: else
249: throw new RemoteException("DGC unexpected returncode: " + returncode);
250: }
251:
252: return (Lease) returnval;
253: }
254:
258: protected Object invokeCommon(Remote obj, Method method, Object[] params,
259: int opnum, long hash) throws Exception
260: {
261: UnicastConnection conn;
262: try
263: {
264: conn = manager.getConnection();
265: return invokeCommon(conn, obj, method, params, opnum, hash);
266: }
267: catch (IOException e1)
268: {
269: throw new RemoteException("connection failed to host: "
270: + manager.serverName, e1);
271: }
272: }
273:
274:
278: protected Object invokeCommon(UnicastConnection conn, Remote obj,
279: Method method, Object[] params, int opnum,
280: long hash) throws Exception
281: {
282: ObjectOutputStream out;
283: DataOutputStream dout;
284: try
285: {
286: dout = conn.getDataOutputStream();
287: dout.writeByte(MESSAGE_CALL);
288:
289: out = conn.startObjectOutputStream();
290:
291: objid.write(out);
292: out.writeInt(opnum);
293: out.writeLong(hash);
294:
295:
296: Class clss[] = method.getParameterTypes();
297: for (int i = 0; i < clss.length; i++)
298: ((RMIObjectOutputStream) out).writeValue(params[i], clss[i]);
299:
300: out.flush();
301: }
302: catch (IOException e2)
303: {
304: throw new RemoteException("call failed: ", e2);
305: }
306:
307: int returncode;
308: Object returnval;
309: DataInputStream din;
310: ObjectInputStream in;
311: UID ack;
312: try
313: {
314: din = conn.getDataInputStream();
315:
316: if ((returncode = din.readUnsignedByte()) != MESSAGE_CALL_ACK)
317: {
318: conn.disconnect();
319: throw new RemoteException("Call not acked:" + returncode);
320: }
321:
322: in = conn.startObjectInputStream();
323: returncode = in.readUnsignedByte();
324: ack = UID.read(in);
325:
326: Class cls = method.getReturnType();
327:
328: if (returncode == RETURN_NACK)
329: {
330: returnval = in.readObject();
331:
332: }
333: else if (cls == Void.TYPE)
334: {
335: returnval = null;
336:
337:
338: }
339: else
340: {
341: returnval = ((RMIObjectInputStream) in).readValue(cls);
342:
343: }
344: }
345: catch (IOException e3)
346: {
347:
348: throw new RemoteException("call return failed: ", e3);
349: }
350:
351:
356:
357: manager.discardConnection(conn);
358:
359: if (returncode != RETURN_ACK && returnval != null)
360: {
361: if (returncode == RETURN_NACK)
362: throw (Exception) returnval;
363: else
364: throw new RemoteException("unexpected returncode: " + returncode);
365: }
366:
367: return (returnval);
368: }
369:
370:
373: public RemoteCall newCall(RemoteObject obj, Operation[] op, int opnum,
374: long hash) throws RemoteException
375: {
376: UnicastConnection conn;
377:
378: try
379: {
380: conn = manager.getConnection();
381: }
382: catch (IOException e1)
383: {
384: throw new ConnectException("connection failed to host: "
385: + manager.serverName, e1);
386: }
387:
388:
389:
390: return (new UnicastRemoteCall(conn, objid, opnum, hash));
391: }
392:
393:
396: public void invoke(RemoteCall call) throws Exception
397: {
398: UnicastRemoteCall c = (UnicastRemoteCall) call;
399: call.executeCall();
400: }
401:
402:
405: public void done(RemoteCall call) throws RemoteException
406: {
407: UnicastRemoteCall c = (UnicastRemoteCall) call;
408: try
409: {
410: c.done();
411: }
412: catch (IOException e)
413: {
414: }
415: UnicastConnection conn = c.getConnection();
416: manager.discardConnection(conn);
417: }
418:
419: public void writeExternal(ObjectOutput out) throws IOException
420: {
421: if (manager == null)
422: {
423: throw new IOException("no connection");
424: }
425: manager.write(out);
426: objid.write(out);
427:
428: out.writeByte(0);
429: }
430:
431: public void readExternal(ObjectInput in) throws IOException,
432: ClassNotFoundException
433: {
434: manager = UnicastConnectionManager.read(in);
435: objid = ObjID.read(in);
436: byte ack = in.readByte();
437:
438: if (ack != RETURN_ACK && ack != 0)
439: {
440: throw new IOException("no ack found");
441: }
442:
443:
444:
445:
446: if (manager.serverobj == null)
447: LeaseRenewingTask.scheduleLeases(this);
448: }
449:
450: public boolean remoteEquals(RemoteRef ref)
451: {
452: throw new Error("Not implemented");
453: }
454:
455: public int remoteHashCode()
456: {
457: throw new Error("Not implemented");
458: }
459:
460: public String getRefClass(ObjectOutput out)
461: {
462: return ("UnicastRef");
463: }
464:
465:
468: public String remoteToString()
469: {
470: if (manager!=null)
471: return manager.toString();
472: else
473: return "null manager";
474: }
475:
476: public void dump(UnicastConnection conn)
477: {
478: try
479: {
480: DataInputStream din = conn.getDataInputStream();
481: for (;;)
482: {
483: int b = din.readUnsignedByte();
484: System.out.print(Integer.toHexString(b));
485: if (b >= 32 && b < 128)
486: {
487: System.out.print(": " + (char) b);
488: }
489: System.out.println();
490: }
491: }
492: catch (IOException _)
493: {
494: }
495: }
496:
497:
504: public boolean equals(Object other)
505: {
506: if (other instanceof UnicastRef)
507: {
508: UnicastRef r = (UnicastRef) other;
509: return r.manager.equals(manager) && r.objid.equals(objid);
510: }
511: else
512: return false;
513: }
514:
515:
519: public int hashCode()
520: {
521: return manager.hashCode() ^ objid.hashCode();
522: }
523:
524: }