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:
59: public class UnicastServer
60: implements ProtocolConstants {
61:
62: static private Hashtable objects = new Hashtable();
63: static private Map refcache = Collections.synchronizedMap(new IdentityHashMap());
64: static private DGCImpl dgc;
65:
66: public static void exportObject(UnicastServerRef obj) {
67: startDGC();
68: objects.put(obj.objid, obj);
69: refcache.put(obj.myself, obj);
70: obj.manager.startServer();
71: }
72:
73:
74: public static boolean unexportObject(UnicastServerRef obj, boolean force) {
75: objects.remove(obj.objid);
76: refcache.remove(obj.myself);
77: obj.manager.stopServer();
78: return true;
79: }
80:
81: public static UnicastServerRef getExportedRef(Remote remote){
82: return (UnicastServerRef)refcache.get(remote);
83: }
84:
85: private static synchronized void startDGC() {
86: if (dgc == null) {
87: try {
88: dgc = new DGCImpl();
89:
90:
91: dgc.exportObject(dgc);
92: }
93: catch (RemoteException e) {
94: e.printStackTrace();
95: }
96: }
97: }
98:
99: public static void dispatch(UnicastConnection conn) throws Exception {
100: switch (conn.getDataInputStream().readUnsignedByte()) {
101: case MESSAGE_CALL:
102: incomingMessageCall(conn);
103: break;
104: case MESSAGE_PING:
105:
106: DataOutputStream out = conn.getDataOutputStream();
107: out.writeByte(MESSAGE_PING_ACK);
108: out.flush();
109: break;
110: default:
111: throw new Exception("bad method type");
112: }
113: }
114:
115: private static void incomingMessageCall(UnicastConnection conn) throws IOException {
116: ObjectInputStream in = conn.startObjectInputStream();
117:
118: ObjID objid = ObjID.read(in);
119: int method = in.readInt();
120: long hash = in.readLong();
121:
122:
123:
124:
125: UnicastServerRef uref = (UnicastServerRef)objects.get(objid);
126: Object returnval;
127: int returncode = RETURN_ACK;
128:
129:
130: Class returncls = null;
131: if (uref != null) {
132: try {
133:
134: returnval = uref.incomingMessageCall(conn, method, hash);
135: returncls = uref.getMethodReturnType(method, hash);
136: }
137: catch (Exception e) {
138: returnval = e;
139: returncode = RETURN_NACK;
140: }
141: catch (Error e) {
142: returnval = new ServerError ("An Error is thrown while processing the invocation on the server", e);
143: returncode = RETURN_NACK;
144: }
145: }
146: else {
147: returnval = new NoSuchObjectException("");
148: returncode = RETURN_NACK;
149: }
150:
151: conn.getDataOutputStream().writeByte(MESSAGE_CALL_ACK);
152:
153: ObjectOutputStream out = conn.startObjectOutputStream();
154:
155: out.writeByte(returncode);
156: (new UID()).write(out);
157:
158:
159:
160: if(returnval != null && returncls != null)
161: ((RMIObjectOutputStream)out).writeValue(returnval, returncls);
162:
163:
164: else if (!(returnval instanceof RMIVoidValue || returncls == Void.TYPE))
165: out.writeObject(returnval);
166:
167: out.flush();
168: }
169:
170: }