2003-12-26 Guilhem Lavaux <guilhem@kaffe.org>
[official-gcc.git] / libjava / gnu / java / rmi / server / UnicastRef.java
blobaaec7a3b470d07fa6f308ba42bae151ca94ec224
1 /*
2 Copyright (c) 1996, 1997, 1998, 1999, 2002 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA.
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
38 package gnu.java.rmi.server;
40 import java.io.DataInputStream;
41 import java.io.DataOutputStream;
42 import java.io.IOException;
43 import java.io.ObjectInput;
44 import java.io.ObjectInputStream;
45 import java.io.ObjectOutput;
46 import java.io.ObjectOutputStream;
47 import java.lang.reflect.InvocationTargetException;
48 import java.lang.reflect.Method;
49 import java.rmi.Remote;
50 import java.rmi.RemoteException;
51 import java.rmi.server.ObjID;
52 import java.rmi.server.Operation;
53 import java.rmi.server.RMIClientSocketFactory;
54 import java.rmi.server.RemoteCall;
55 import java.rmi.server.RemoteObject;
56 import java.rmi.server.RemoteRef;
57 import java.rmi.server.UID;
59 public class UnicastRef
60 implements RemoteRef, ProtocolConstants {
62 public ObjID objid;
63 UnicastConnectionManager manager;
65 /**
66 * Used by serialization, and let subclass capable of having default constructor
68 // must be public otherwise java.rmi.RemoteObject cannot instantiate this class
69 // -- iP
70 public UnicastRef() {
73 public UnicastRef(ObjID objid, String host, int port, RMIClientSocketFactory csf) {
74 this(objid);
75 manager = UnicastConnectionManager.getInstance(host, port, csf);
78 public UnicastRef(ObjID objid) {
79 this.objid = objid;
82 public Object invoke(Remote obj, Method method, Object[] params, long opnum) throws Exception {
83 // Check if client and server are in the same VM, then local call can be used to
84 // replace remote call, but it's somewhat violating remote semantic.
85 Object svrobj = manager.serverobj;
87 // Make sure that the server object is compatible. It could be loaded from a different
88 // classloader --iP
89 if(svrobj != null && method.getDeclaringClass().isInstance(svrobj)){
90 //local call
91 Object ret = null;
92 try{
93 ret = method.invoke(svrobj, params);
94 }catch(InvocationTargetException e){
95 throw (Exception)e.getTargetException();
97 //System.out.println("\n\n ***** local call: " + method + "\nreturn: " + ret + "\n\n");
98 return ret;
100 //System.out.println("***************** remote call:" + manager.serverPort);
101 return (invokeCommon(obj, method, params, -1, opnum));
104 private Object invokeCommon(Remote obj, Method method, Object[] params, int opnum, long hash) throws Exception {
105 UnicastConnection conn;
106 try {
107 conn = manager.getConnection();
109 catch (IOException e1) {
110 throw new RemoteException("connection failed to host: " + manager.serverName, e1);
113 ObjectOutputStream out;
114 DataOutputStream dout;
115 try {
116 dout = conn.getDataOutputStream();
117 dout.writeByte(MESSAGE_CALL);
119 out = conn.getObjectOutputStream();
121 objid.write(out);
122 out.writeInt(opnum);
123 out.writeLong(hash);
125 // must handle primitive class and their wrapper classes
126 Class clss[] = method.getParameterTypes();
127 for(int i = 0; i < clss.length; i++)
128 ((RMIObjectOutputStream)out).writeValue(params[i], clss[i]);
130 out.flush();
132 catch (IOException e2) {
133 throw new RemoteException("call failed: ", e2);
136 int returncode;
137 Object returnval;
138 DataInputStream din;
139 ObjectInputStream in;
140 UID ack;
141 try {
142 din = conn.getDataInputStream();
144 if ((returncode = din.readUnsignedByte()) != MESSAGE_CALL_ACK) {
145 conn.disconnect();
146 throw new RemoteException("Call not acked:" + returncode);
149 in = conn.getObjectInputStream();
150 returncode = in.readUnsignedByte();
151 ack = UID.read(in);
153 Class cls = method.getReturnType();
154 if(cls == Void.TYPE){
155 returnval = null;
156 in.readObject();
157 }else
158 returnval = ((RMIObjectInputStream)in).readValue(cls);
161 catch (IOException e3) {
162 //for debug: e3.printStackTrace();
163 throw new RemoteException("call return failed: ", e3);
166 /* if DGCAck is necessary??
167 //According to RMI wire protocol, send a DGCAck
168 // to indicate receiving return value
169 dout.writeByte(MESSAGE_DGCACK);
170 ack.write(dout);
171 out.flush();
174 manager.discardConnection(conn);
176 if (returncode != RETURN_ACK && returnval != null) {
177 throw (Exception)returnval;
180 return (returnval);
184 * @deprecated
186 public RemoteCall newCall(RemoteObject obj, Operation[] op, int opnum, long hash) throws RemoteException {
187 UnicastConnection conn;
189 try {
190 conn = manager.getConnection();
192 catch (IOException e1) {
193 throw new RemoteException("connection failed to host: " + manager.serverName, e1);
196 //obj: useless?
198 return (new UnicastRemoteCall(conn, objid, opnum, hash));
202 * @deprecated
204 public void invoke(RemoteCall call) throws Exception {
205 UnicastRemoteCall c = (UnicastRemoteCall)call;
206 call.executeCall();
210 * @deprecated
212 public void done(RemoteCall call) throws RemoteException {
213 UnicastRemoteCall c = (UnicastRemoteCall)call;
214 try{
215 c.done();
216 } catch(IOException e){}
217 UnicastConnection conn = c.getConnection();
218 manager.discardConnection(conn);
221 public void writeExternal(ObjectOutput out) throws IOException {
222 if (manager == null) {
223 throw new IOException("no connection");
225 manager.write(out);
226 objid.write(out);
227 // This byte is somewhat confusing when interoperating with JDK
228 out.writeByte(0); //RETURN_ACK);
231 public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
232 manager = UnicastConnectionManager.read(in);
233 objid = ObjID.read(in);
234 byte ack = in.readByte();
235 // This byte is somewhat confusing when interoperating with JDK
236 if (ack != RETURN_ACK && ack != 0/*jdk ack value*/) {
237 throw new IOException("no ack found");
241 public boolean remoteEquals(RemoteRef ref) {
242 throw new Error("Not implemented");
245 public int remoteHashCode() {
246 throw new Error("Not implemented");
249 public String getRefClass(ObjectOutput out) {
250 return ("UnicastRef");
253 public String remoteToString() {
254 throw new Error("Not implemented");
257 public void dump(UnicastConnection conn) {
258 try {
259 DataInputStream din = conn.getDataInputStream();
260 for (;;) {
261 int b = din.readUnsignedByte();
262 System.out.print(Integer.toHexString(b));
263 if (b >= 32 && b < 128) {
264 System.out.print(": " + (char)b);
266 System.out.println();
269 catch (IOException _) {