001 package railo.runtime.engine; 002 003 import java.io.ByteArrayOutputStream; 004 import java.io.DataInputStream; 005 import java.io.DataOutputStream; 006 import java.io.IOException; 007 import java.util.Iterator; 008 009 import javax.servlet.ServletException; 010 import javax.servlet.ServletOutputStream; 011 import javax.servlet.http.HttpServlet; 012 import javax.servlet.http.HttpServletRequest; 013 import javax.servlet.http.HttpServletResponse; 014 015 import org.openamf.AMFBody; 016 import org.openamf.AMFError; 017 import org.openamf.AMFMessage; 018 import org.openamf.ServiceRequest; 019 import org.openamf.io.AMFDeserializer; 020 import org.openamf.io.AMFSerializer; 021 022 import railo.commons.io.IOUtil; 023 import railo.runtime.exp.PageException; 024 import railo.runtime.net.amf.CFMLProxy; 025 import railo.runtime.net.amf.OpenAMFCaster; 026 027 028 /** 029 * AMF Engine 030 */ 031 public final class AMFEngine { 032 033 034 035 /** 036 * Main entry point for the servlet 037 * @param servlet 038 * @param req 039 * @param rsp 040 * 041 * @throws ServletException 042 * @throws IOException 043 */ 044 public void service(HttpServlet servlet, HttpServletRequest req, HttpServletResponse rsp) throws IOException { 045 046 AMFMessage requestMessage = null; 047 AMFMessage responseMessage = null; 048 requestMessage = deserializeAMFMessage(req); 049 responseMessage = processMessage(servlet, req, rsp, requestMessage); 050 serializeAMFMessage(rsp, responseMessage); 051 } 052 053 /** 054 * Uses the AMFDeserializer to deserialize the request 055 * 056 * @see org.openamf.io.AMFDeserializer 057 */ 058 private AMFMessage deserializeAMFMessage(HttpServletRequest req) throws IOException { 059 DataInputStream dis = null; 060 try { 061 dis = new DataInputStream(req.getInputStream()); 062 AMFDeserializer deserializer = new AMFDeserializer(dis); 063 AMFMessage message = deserializer.getAMFMessage(); 064 return message; 065 } 066 finally { 067 IOUtil.closeEL(dis); 068 } 069 } 070 071 /** 072 * Uses the AMFSerializer to serialize the request 073 * 074 * @see org.openamf.io.AMFSerializer 075 */ 076 private void serializeAMFMessage(HttpServletResponse resp, AMFMessage message) throws IOException { 077 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 078 DataOutputStream dos = new DataOutputStream(baos); 079 AMFSerializer serializer = new AMFSerializer(dos); 080 serializer.serializeMessage(message); 081 resp.setContentType("application/x-amf"); 082 resp.setContentLength(baos.size()); 083 ServletOutputStream sos = resp.getOutputStream(); 084 baos.writeTo(sos); 085 sos.flush(); 086 } 087 088 /** 089 * Iterates through the request message's bodies, invokes each body and 090 * then, builds a message to send as the results 091 * @param req 092 * @param rsp 093 * @param message 094 * @return AMFMessage 095 * @throws IOException 096 * @throws ServletException 097 */ 098 private AMFMessage processMessage(HttpServlet servlet, HttpServletRequest req, HttpServletResponse rsp, AMFMessage message) { 099 AMFMessage responseMessage = new AMFMessage(); 100 for (Iterator bodies = message.getBodies(); bodies.hasNext();) { 101 AMFBody requestBody = (AMFBody) bodies.next(); 102 // invoke 103 Object serviceResult = invokeBody(servlet,req, rsp, requestBody); 104 String target = getTarget(requestBody, serviceResult); 105 AMFBody responseBody = new AMFBody(target, "null", serviceResult); 106 responseMessage.addBody(responseBody); 107 } 108 return responseMessage; 109 } 110 111 112 private Object invokeBody(HttpServlet servlet, HttpServletRequest req, HttpServletResponse rsp, AMFBody requestBody) { 113 try { 114 ServiceRequest request = new ServiceRequest(requestBody); 115 rsp.getOutputStream();// MUST muss das sein? 116 117 return new CFMLProxy().invokeBody(OpenAMFCaster.getInstance(),null,servlet.getServletContext(),servlet.getServletConfig(), req, rsp, request.getServiceName(), request.getServiceMethodName(), request.getParameters()); 118 } 119 catch (Exception e) { 120 e.printStackTrace(); 121 rsp.setStatus(200); 122 AMFError error=new AMFError(); 123 e.setStackTrace(e.getStackTrace()); 124 error.setDescription(e.getMessage()); 125 126 if(e instanceof PageException){ 127 PageException pe = (PageException)e; 128 error.setCode(pe.getErrorCode()); 129 error.setCode(pe.getErrorCode()); 130 error.setDetails(pe.getDetail()); 131 } 132 133 return error; 134 } 135 } 136 137 private String getTarget(AMFBody requestBody, Object serviceResult) { 138 String target = "/onResult"; 139 if (serviceResult instanceof AMFError) { 140 target = "/onStatus"; 141 } 142 return requestBody.getResponse() + target; 143 } 144 }