1 8 9 package mx4j.tools.remote.caucho; 10 11 import java.io.BufferedInputStream ; 12 import java.io.BufferedOutputStream ; 13 import java.io.IOException ; 14 import java.io.InputStream ; 15 import java.io.OutputStream ; 16 import java.lang.reflect.InvocationTargetException ; 17 import java.lang.reflect.Method ; 18 import java.util.HashMap ; 19 import java.util.Map ; 20 21 import javax.servlet.ServletException ; 22 import javax.servlet.http.HttpServlet ; 23 import javax.servlet.http.HttpServletRequest ; 24 import javax.servlet.http.HttpServletResponse ; 25 26 import mx4j.tools.remote.http.HTTPConnection; 27 28 31 public abstract class CauchoServlet extends HttpServlet 32 { 33 private Map methods; 34 35 public void init() throws ServletException 36 { 37 methods = new HashMap (); 38 mapMethods(HTTPConnection.class, methods); 39 } 40 41 protected void mapMethods(Class cls, Map methods) 42 { 43 Method [] mthds = cls.getMethods(); 44 for (int i = 0; i < mthds.length; ++i) 45 { 46 Method mthd = mthds[i]; 47 String key = mangleMethodName(mthd); 48 methods.put(key, mthd); 49 } 50 } 51 52 protected Method findMethod(String methodName) 53 { 54 return (Method ) methods.get(methodName); 55 } 56 57 protected String mangleMethodName(Method method) 58 { 59 return CauchoService.mangleMethodName(method); 60 } 61 62 protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException , IOException 63 { 64 if (!"POST".equalsIgnoreCase(request.getMethod())) throw new ServletException ("Caucho protocol requires POST"); 65 66 BufferedInputStream is = new BufferedInputStream (request.getInputStream(), 48); 67 CauchoInput input = createCauchoInput(is); 68 BufferedOutputStream bos = new BufferedOutputStream (response.getOutputStream(), 48); 69 CauchoOutput output = createCauchoOutput(bos); 70 71 invoke(request, input, output); 72 73 bos.flush(); 74 } 75 76 protected abstract CauchoInput createCauchoInput(InputStream stream); 77 78 protected abstract CauchoOutput createCauchoOutput(OutputStream stream); 79 80 protected abstract Object getService(); 81 82 protected void invoke(HttpServletRequest request, CauchoInput input, CauchoOutput output) throws IOException 83 { 84 input.startCall(); 85 Map headers = readHeaders(input); 86 String methodName = input.readMethod(); 87 Method method = findMethod(methodName); 88 if (method == null) 89 { 90 output.startReply(); 91 NoSuchMethodException x = new NoSuchMethodException (methodName); 92 output.writeFault(x); 93 output.completeReply(); 94 } else 95 { 96 Object [] values = readArguments(input, method); 97 input.completeCall(); 98 99 Object result = null; 100 try 101 { 102 result = invoke(request.getRequestURL().toString(), getService(), method, headers, values); 103 } catch (Throwable x) 104 { 105 output.startReply(); 106 output.writeFault(x); 107 output.completeReply(); 108 return; 109 } 110 output.startReply(); 111 output.writeObject(result); 112 output.completeReply(); 113 } 114 } 115 116 protected Map readHeaders(CauchoInput input) throws IOException 117 { 118 Map headers = new HashMap (); 119 String header = null; 120 while ((header = input.readHeader()) != null) headers.put(header, input.readObject(null)); 121 return headers; 122 } 123 124 protected Object [] readArguments(CauchoInput input, Method method) throws IOException 125 { 126 Class [] types = method.getParameterTypes(); 127 Object [] values = new Object [types.length]; 128 for (int i = 0; i < types.length; ++i) values[i] = input.readObject(types[i]); 129 return values; 130 } 131 132 protected Object invoke(String url, Object target, Method method, Map headers, Object [] values) throws Exception 133 { 134 if (target == null) throw new IOException ("Service is not available"); 135 String connectionId = (String ) headers.get(CauchoService.CONNECTION_ID_HEADER_NAME); 136 CauchoService.setConnectionContext(url, connectionId); 137 try 138 { 139 return method.invoke(target, values); 140 } catch (InvocationTargetException x) 141 { 142 Throwable t = x.getTargetException(); 143 if (t instanceof Exception ) throw (Exception ) t; 144 throw (Error ) t; 145 } finally 146 { 147 CauchoService.resetConnectionContext(); 148 } 149 } 150 } 151 | Popular Tags |