1:
38:
39: package ;
40:
41: import ;
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: import ;
58: import ;
59:
60: public class UnicastRef
61: implements RemoteRef, ProtocolConstants {
62:
63: public ObjID objid;
64: UnicastConnectionManager manager;
65:
66:
69:
70:
71: public UnicastRef() {
72: }
73:
74: public UnicastRef(ObjID objid, String host, int port, RMIClientSocketFactory csf) {
75: this(objid);
76: manager = UnicastConnectionManager.getInstance(host, port, csf);
77: }
78:
79: public UnicastRef(ObjID objid) {
80: this.objid = objid;
81: }
82:
83: public Object invoke(Remote obj, Method method, Object[] params, long opnum) throws Exception {
84:
85:
86: Object svrobj = manager.serverobj;
87:
88:
89:
90: if(svrobj != null && method.getDeclaringClass().isInstance(svrobj)){
91:
92: Object ret = null;
93: try{
94: ret = method.invoke(svrobj, params);
95: }catch(InvocationTargetException e){
96: throw (Exception)e.getTargetException();
97: }
98:
99: return ret;
100: }
101:
102: return (invokeCommon(obj, method, params, -1, opnum));
103: }
104:
105: private Object invokeCommon(Remote obj, Method method, Object[] params, int opnum, long hash) throws Exception {
106: UnicastConnection conn;
107: try {
108: conn = manager.getConnection();
109: }
110: catch (IOException e1) {
111: throw new RemoteException("connection failed to host: " + manager.serverName, e1);
112: }
113:
114: ObjectOutputStream out;
115: DataOutputStream dout;
116: try {
117: dout = conn.getDataOutputStream();
118: dout.writeByte(MESSAGE_CALL);
119:
120: out = conn.startObjectOutputStream();
121:
122: objid.write(out);
123: out.writeInt(opnum);
124: out.writeLong(hash);
125:
126:
127: Class clss[] = method.getParameterTypes();
128: for(int i = 0; i < clss.length; i++)
129: ((RMIObjectOutputStream)out).writeValue(params[i], clss[i]);
130:
131: out.flush();
132: }
133: catch (IOException e2) {
134: throw new RemoteException("call failed: ", e2);
135: }
136:
137: int returncode;
138: Object returnval;
139: DataInputStream din;
140: ObjectInputStream in;
141: UID ack;
142: try {
143: din = conn.getDataInputStream();
144:
145: if ((returncode = din.readUnsignedByte()) != MESSAGE_CALL_ACK) {
146: conn.disconnect();
147: throw new RemoteException("Call not acked:" + returncode);
148: }
149:
150: in = conn.startObjectInputStream();
151: returncode = in.readUnsignedByte();
152: ack = UID.read(in);
153:
154: Class cls = method.getReturnType();
155:
156: if (returncode == RETURN_NACK) {
157: returnval = in.readObject();
158:
159: } else if(cls == Void.TYPE) {
160: returnval = null;
161:
162: } else {
163: returnval = ((RMIObjectInputStream)in).readValue(cls);
164: }
165: } catch (IOException e3) {
166:
167: throw new RemoteException("call return failed: ", e3);
168: }
169:
170:
177:
178: manager.discardConnection(conn);
179:
180: if (returncode != RETURN_ACK && returnval != null) {
181: if (returncode == RETURN_NACK) throw (Exception)returnval;
182: else throw new RemoteException("unexpected returncode: " + returncode);
183: }
184:
185: return (returnval);
186: }
187:
188:
191: public RemoteCall newCall(RemoteObject obj, Operation[] op, int opnum, long hash) throws RemoteException {
192: UnicastConnection conn;
193:
194: try {
195: conn = manager.getConnection();
196: }
197: catch (IOException e1) {
198: throw new RemoteException("connection failed to host: " + manager.serverName, e1);
199: }
200:
201:
202:
203: return (new UnicastRemoteCall(conn, objid, opnum, hash));
204: }
205:
206:
209: public void invoke(RemoteCall call) throws Exception {
210: UnicastRemoteCall c = (UnicastRemoteCall)call;
211: call.executeCall();
212: }
213:
214:
217: public void done(RemoteCall call) throws RemoteException {
218: UnicastRemoteCall c = (UnicastRemoteCall)call;
219: try{
220: c.done();
221: } catch(IOException e){}
222: UnicastConnection conn = c.getConnection();
223: manager.discardConnection(conn);
224: }
225:
226: public void writeExternal(ObjectOutput out) throws IOException {
227: if (manager == null) {
228: throw new IOException("no connection");
229: }
230: manager.write(out);
231: objid.write(out);
232:
233: out.writeByte(0);
234: }
235:
236: public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
237: manager = UnicastConnectionManager.read(in);
238: objid = ObjID.read(in);
239: byte ack = in.readByte();
240:
241: if (ack != RETURN_ACK && ack != 0) {
242: throw new IOException("no ack found");
243: }
244: }
245:
246: public boolean remoteEquals(RemoteRef ref) {
247: throw new Error("Not implemented");
248: }
249:
250: public int remoteHashCode() {
251: throw new Error("Not implemented");
252: }
253:
254: public String getRefClass(ObjectOutput out) {
255: return ("UnicastRef");
256: }
257:
258: public String remoteToString() {
259: throw new Error("Not implemented");
260: }
261:
262: public void dump(UnicastConnection conn) {
263: try {
264: DataInputStream din = conn.getDataInputStream();
265: for (;;) {
266: int b = din.readUnsignedByte();
267: System.out.print(Integer.toHexString(b));
268: if (b >= 32 && b < 128) {
269: System.out.print(": " + (char)b);
270: }
271: System.out.println();
272: }
273: }
274: catch (IOException _) {
275: }
276: }
277:
278: }