You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

AppletServer.java 7.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. /*
  2. * Javassist, a Java-bytecode translator toolkit.
  3. * Copyright (C) 1999-2005 Shigeru Chiba. All Rights Reserved.
  4. *
  5. * The contents of this file are subject to the Mozilla Public License Version
  6. * 1.1 (the "License"); you may not use this file except in compliance with
  7. * the License. Alternatively, the contents of this file may be used under
  8. * the terms of the GNU Lesser General Public License Version 2.1 or later.
  9. *
  10. * Software distributed under the License is distributed on an "AS IS" basis,
  11. * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  12. * for the specific language governing rights and limitations under the
  13. * License.
  14. */
  15. package javassist.tools.rmi;
  16. import java.io.*;
  17. import javassist.tools.web.*;
  18. import javassist.CannotCompileException;
  19. import javassist.NotFoundException;
  20. import javassist.ClassPool;
  21. import java.lang.reflect.Method;
  22. import java.util.Hashtable;
  23. import java.util.Vector;
  24. /**
  25. * An AppletServer object is a web server that an ObjectImporter
  26. * communicates with. It makes the objects specified by
  27. * <code>exportObject()</code> remotely accessible from applets.
  28. * If the classes of the exported objects are requested by the client-side
  29. * JVM, this web server sends proxy classes for the requested classes.
  30. *
  31. * @see javassist.tools.rmi.ObjectImporter
  32. */
  33. public class AppletServer extends Webserver {
  34. private StubGenerator stubGen;
  35. private Hashtable exportedNames;
  36. private Vector exportedObjects;
  37. private static final byte[] okHeader
  38. = "HTTP/1.0 200 OK\r\n\r\n".getBytes();
  39. /**
  40. * Constructs a web server.
  41. *
  42. * @param port port number
  43. */
  44. public AppletServer(String port)
  45. throws IOException, NotFoundException, CannotCompileException
  46. {
  47. this(Integer.parseInt(port));
  48. }
  49. /**
  50. * Constructs a web server.
  51. *
  52. * @param port port number
  53. */
  54. public AppletServer(int port)
  55. throws IOException, NotFoundException, CannotCompileException
  56. {
  57. this(ClassPool.getDefault(), new StubGenerator(), port);
  58. }
  59. /**
  60. * Constructs a web server.
  61. *
  62. * @param port port number
  63. * @param src the source of classs files.
  64. */
  65. public AppletServer(int port, ClassPool src)
  66. throws IOException, NotFoundException, CannotCompileException
  67. {
  68. this(new ClassPool(src), new StubGenerator(), port);
  69. }
  70. private AppletServer(ClassPool loader, StubGenerator gen, int port)
  71. throws IOException, NotFoundException, CannotCompileException
  72. {
  73. super(port);
  74. exportedNames = new Hashtable();
  75. exportedObjects = new Vector();
  76. stubGen = gen;
  77. addTranslator(loader, gen);
  78. }
  79. /**
  80. * Begins the HTTP service.
  81. */
  82. public void run() {
  83. super.run();
  84. }
  85. /**
  86. * Exports an object.
  87. * This method produces the bytecode of the proxy class used
  88. * to access the exported object. A remote applet can load
  89. * the proxy class and call a method on the exported object.
  90. *
  91. * @param name the name used for looking the object up.
  92. * @param obj the exported object.
  93. * @return the object identifier
  94. *
  95. * @see javassist.tools.rmi.ObjectImporter#lookupObject(String)
  96. */
  97. public synchronized int exportObject(String name, Object obj)
  98. throws CannotCompileException
  99. {
  100. Class clazz = obj.getClass();
  101. ExportedObject eo = new ExportedObject();
  102. eo.object = obj;
  103. eo.methods = clazz.getMethods();
  104. exportedObjects.addElement(eo);
  105. eo.identifier = exportedObjects.size() - 1;
  106. if (name != null)
  107. exportedNames.put(name, eo);
  108. try {
  109. stubGen.makeProxyClass(clazz);
  110. }
  111. catch (NotFoundException e) {
  112. throw new CannotCompileException(e);
  113. }
  114. return eo.identifier;
  115. }
  116. /**
  117. * Processes a request from a web browser (an ObjectImporter).
  118. */
  119. public void doReply(InputStream in, OutputStream out, String cmd)
  120. throws IOException, BadHttpRequest
  121. {
  122. if (cmd.startsWith("POST /rmi "))
  123. processRMI(in, out);
  124. else if (cmd.startsWith("POST /lookup "))
  125. lookupName(cmd, in, out);
  126. else
  127. super.doReply(in, out, cmd);
  128. }
  129. private void processRMI(InputStream ins, OutputStream outs)
  130. throws IOException
  131. {
  132. ObjectInputStream in = new ObjectInputStream(ins);
  133. int objectId = in.readInt();
  134. int methodId = in.readInt();
  135. Exception err = null;
  136. Object rvalue = null;
  137. try {
  138. ExportedObject eo
  139. = (ExportedObject)exportedObjects.elementAt(objectId);
  140. Object[] args = readParameters(in);
  141. rvalue = convertRvalue(eo.methods[methodId].invoke(eo.object,
  142. args));
  143. }
  144. catch(Exception e) {
  145. err = e;
  146. logging2(e.toString());
  147. }
  148. outs.write(okHeader);
  149. ObjectOutputStream out = new ObjectOutputStream(outs);
  150. if (err != null) {
  151. out.writeBoolean(false);
  152. out.writeUTF(err.toString());
  153. }
  154. else
  155. try {
  156. out.writeBoolean(true);
  157. out.writeObject(rvalue);
  158. }
  159. catch (NotSerializableException e) {
  160. logging2(e.toString());
  161. }
  162. catch (InvalidClassException e) {
  163. logging2(e.toString());
  164. }
  165. out.flush();
  166. out.close();
  167. in.close();
  168. }
  169. private Object[] readParameters(ObjectInputStream in)
  170. throws IOException, ClassNotFoundException
  171. {
  172. int n = in.readInt();
  173. Object[] args = new Object[n];
  174. for (int i = 0; i < n; ++i) {
  175. Object a = in.readObject();
  176. if (a instanceof RemoteRef) {
  177. RemoteRef ref = (RemoteRef)a;
  178. ExportedObject eo
  179. = (ExportedObject)exportedObjects.elementAt(ref.oid);
  180. a = eo.object;
  181. }
  182. args[i] = a;
  183. }
  184. return args;
  185. }
  186. private Object convertRvalue(Object rvalue)
  187. throws CannotCompileException
  188. {
  189. if (rvalue == null)
  190. return null; // the return type is void.
  191. String classname = rvalue.getClass().getName();
  192. if (stubGen.isProxyClass(classname))
  193. return new RemoteRef(exportObject(null, rvalue), classname);
  194. else
  195. return rvalue;
  196. }
  197. private void lookupName(String cmd, InputStream ins, OutputStream outs)
  198. throws IOException
  199. {
  200. ObjectInputStream in = new ObjectInputStream(ins);
  201. String name = DataInputStream.readUTF(in);
  202. ExportedObject found = (ExportedObject)exportedNames.get(name);
  203. outs.write(okHeader);
  204. ObjectOutputStream out = new ObjectOutputStream(outs);
  205. if (found == null) {
  206. logging2(name + "not found.");
  207. out.writeInt(-1); // error code
  208. out.writeUTF("error");
  209. }
  210. else {
  211. logging2(name);
  212. out.writeInt(found.identifier);
  213. out.writeUTF(found.object.getClass().getName());
  214. }
  215. out.flush();
  216. out.close();
  217. in.close();
  218. }
  219. }
  220. class ExportedObject {
  221. public int identifier;
  222. public Object object;
  223. public Method[] methods;
  224. }