package gnu.java.rmi.server;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.server.ObjID;
import java.rmi.server.Operation;
import java.rmi.server.RMIClientSocketFactory;
import java.rmi.server.RemoteCall;
import java.rmi.server.RemoteObject;
import java.rmi.server.RemoteRef;
import java.rmi.server.UID;
public class UnicastRef
implements RemoteRef, ProtocolConstants {
public ObjID objid;
UnicastConnectionManager manager;
public UnicastRef() {
}
public UnicastRef(ObjID objid, String host, int port, RMIClientSocketFactory csf) {
this(objid);
manager = UnicastConnectionManager.getInstance(host, port, csf);
}
public UnicastRef(ObjID objid) {
this.objid = objid;
}
public Object invoke(Remote obj, Method method, Object[] params, long opnum) throws Exception {
Object svrobj = manager.serverobj;
if(svrobj != null && method.getDeclaringClass().isInstance(svrobj)){
Object ret = null;
try{
ret = method.invoke(svrobj, params);
}catch(InvocationTargetException e){
throw (Exception)e.getTargetException();
}
return ret;
}
return (invokeCommon(obj, method, params, -1, opnum));
}
private Object invokeCommon(Remote obj, Method method, Object[] params, int opnum, long hash) throws Exception {
UnicastConnection conn;
try {
conn = manager.getConnection();
}
catch (IOException e1) {
throw new RemoteException("connection failed to host: " + manager.serverName, e1);
}
ObjectOutputStream out;
DataOutputStream dout;
try {
dout = conn.getDataOutputStream();
dout.writeByte(MESSAGE_CALL);
out = conn.startObjectOutputStream();
objid.write(out);
out.writeInt(opnum);
out.writeLong(hash);
Class clss[] = method.getParameterTypes();
for(int i = 0; i < clss.length; i++)
((RMIObjectOutputStream)out).writeValue(params[i], clss[i]);
out.flush();
}
catch (IOException e2) {
throw new RemoteException("call failed: ", e2);
}
int returncode;
Object returnval;
DataInputStream din;
ObjectInputStream in;
UID ack;
try {
din = conn.getDataInputStream();
if ((returncode = din.readUnsignedByte()) != MESSAGE_CALL_ACK) {
conn.disconnect();
throw new RemoteException("Call not acked:" + returncode);
}
in = conn.startObjectInputStream(); returncode = in.readUnsignedByte();
ack = UID.read(in);
Class cls = method.getReturnType();
if (returncode == RETURN_NACK) {
returnval = in.readObject();
} else if(cls == Void.TYPE) {
returnval = null;
} else {
returnval = ((RMIObjectInputStream)in).readValue(cls); }
} catch (IOException e3) {
throw new RemoteException("call return failed: ", e3);
}
manager.discardConnection(conn);
if (returncode != RETURN_ACK && returnval != null) {
if (returncode == RETURN_NACK) throw (Exception)returnval;
else throw new RemoteException("unexpected returncode: " + returncode);
}
return (returnval);
}
public RemoteCall newCall(RemoteObject obj, Operation[] op, int opnum, long hash) throws RemoteException {
UnicastConnection conn;
try {
conn = manager.getConnection();
}
catch (IOException e1) {
throw new RemoteException("connection failed to host: " + manager.serverName, e1);
}
return (new UnicastRemoteCall(conn, objid, opnum, hash));
}
public void invoke(RemoteCall call) throws Exception {
UnicastRemoteCall c = (UnicastRemoteCall)call;
call.executeCall();
}
public void done(RemoteCall call) throws RemoteException {
UnicastRemoteCall c = (UnicastRemoteCall)call;
try{
c.done();
} catch(IOException e){}
UnicastConnection conn = c.getConnection();
manager.discardConnection(conn);
}
public void writeExternal(ObjectOutput out) throws IOException {
if (manager == null) {
throw new IOException("no connection");
}
manager.write(out);
objid.write(out);
out.writeByte(0); }
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
manager = UnicastConnectionManager.read(in);
objid = ObjID.read(in);
byte ack = in.readByte();
if (ack != RETURN_ACK && ack != 0) {
throw new IOException("no ack found");
}
}
public boolean remoteEquals(RemoteRef ref) {
throw new Error("Not implemented");
}
public int remoteHashCode() {
throw new Error("Not implemented");
}
public String getRefClass(ObjectOutput out) {
return ("UnicastRef");
}
public String remoteToString() {
throw new Error("Not implemented");
}
public void dump(UnicastConnection conn) {
try {
DataInputStream din = conn.getDataInputStream();
for (;;) {
int b = din.readUnsignedByte();
System.out.print(Integer.toHexString(b));
if (b >= 32 && b < 128) {
System.out.print(": " + (char)b);
}
System.out.println();
}
}
catch (IOException _) {
}
}
}