UnicastServer.java [plain text]
package gnu.java.rmi.server;
import gnu.java.rmi.dgc.DGCImpl;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.rmi.NoSuchObjectException;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.ServerError;
import java.rmi.server.ObjID;
import java.rmi.server.UID;
import java.util.Hashtable;
public class UnicastServer
implements ProtocolConstants {
static private Hashtable objects = new Hashtable(); static private Hashtable refcache = new Hashtable(); static private DGCImpl dgc;
public static void exportObject(UnicastServerRef obj) {
startDGC();
objects.put(obj.objid, obj);
refcache.put(obj.myself, obj);
obj.manager.startServer();
}
public static boolean unexportObject(UnicastServerRef obj, boolean force) {
objects.remove(obj.objid);
refcache.remove(obj.myself);
obj.manager.stopServer();
return true;
}
public static UnicastServerRef getExportedRef(Remote remote){
return (UnicastServerRef)refcache.get(remote);
}
private static synchronized void startDGC() {
if (dgc == null) {
try {
dgc = new DGCImpl();
dgc.exportObject(dgc);
}
catch (RemoteException e) {
e.printStackTrace();
}
}
}
public static void dispatch(UnicastConnection conn) throws Exception {
switch (conn.getDataInputStream().readUnsignedByte()) {
case MESSAGE_CALL:
incomingMessageCall(conn);
break;
case MESSAGE_PING:
DataOutputStream out = conn.getDataOutputStream();
out.writeByte(MESSAGE_PING_ACK);
out.flush();
break;
default:
throw new Exception("bad method type");
}
}
private static void incomingMessageCall(UnicastConnection conn) throws IOException {
ObjectInputStream in = conn.startObjectInputStream();
ObjID objid = ObjID.read(in);
int method = in.readInt();
long hash = in.readLong();
UnicastServerRef uref = (UnicastServerRef)objects.get(objid);
Object returnval;
int returncode = RETURN_ACK;
Class returncls = null;
if (uref != null) {
try {
returnval = uref.incomingMessageCall(conn, method, hash);
returncls = uref.getMethodReturnType(method, hash);
}
catch (Exception e) {
returnval = e;
returncode = RETURN_NACK;
}
catch (Error e) {
returnval = new ServerError ("An Error is thrown while processing the invocation on the server", e);
returncode = RETURN_NACK;
}
}
else {
returnval = new NoSuchObjectException("");
returncode = RETURN_NACK;
}
conn.getDataOutputStream().writeByte(MESSAGE_CALL_ACK);
ObjectOutputStream out = conn.startObjectOutputStream();
out.writeByte(returncode);
(new UID()).write(out);
if(returnval != null && returncls != null)
((RMIObjectOutputStream)out).writeValue(returnval, returncls);
else if (!(returnval instanceof RMIVoidValue || returncls == Void.TYPE))
out.writeObject(returnval);
out.flush();
}
}