001/* 002 GRANITE DATA SERVICES 003 Copyright (C) 2011 GRANITE DATA SERVICES S.A.S. 004 005 This file is part of Granite Data Services. 006 007 Granite Data Services is free software; you can redistribute it and/or modify 008 it under the terms of the GNU Library General Public License as published by 009 the Free Software Foundation; either version 2 of the License, or (at your 010 option) any later version. 011 012 Granite Data Services is distributed in the hope that it will be useful, but 013 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 014 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License 015 for more details. 016 017 You should have received a copy of the GNU Library General Public License 018 along with this library; if not, see <http://www.gnu.org/licenses/>. 019*/ 020 021package org.granite.messaging.webapp; 022 023import java.io.BufferedInputStream; 024import java.io.IOException; 025import java.io.InputStream; 026import java.io.OutputStream; 027 028import javax.servlet.ServletContext; 029import javax.servlet.ServletException; 030import javax.servlet.http.HttpServletRequest; 031import javax.servlet.http.HttpServletResponse; 032 033import org.granite.config.GraniteConfig; 034import org.granite.config.flex.ServicesConfig; 035import org.granite.context.GraniteContext; 036import org.granite.logging.Logger; 037import org.granite.messaging.amf.AMF0Message; 038import org.granite.messaging.amf.io.AMF0Deserializer; 039import org.granite.messaging.amf.io.AMF0Serializer; 040import org.granite.messaging.amf.process.AMF0MessageProcessor; 041import org.granite.messaging.jmf.JMFDeserializer; 042import org.granite.messaging.jmf.JMFSerializer; 043import org.granite.messaging.jmf.JMFServletContextListener; 044import org.granite.messaging.jmf.SharedContext; 045import org.granite.util.ContentType; 046 047/** 048 * @author Franck WOLFF 049 */ 050public class AMFEndpoint { 051 052 private static final Logger log = Logger.getLogger(AMFEndpoint.class); 053 054 private SharedContext jmfSharedContext = null; 055 056 public void init(ServletContext context) { 057 jmfSharedContext = JMFServletContextListener.getSharedContext(context); 058 059 } 060 061 public void destroy() { 062 jmfSharedContext = null; 063 } 064 065 public void service(GraniteConfig graniteConfig, ServicesConfig servicesConfig, ServletContext context, 066 HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { 067 068 if (ContentType.JMF_AMF.mimeType().equals(request.getContentType())) 069 serviceJMFAMF(graniteConfig, servicesConfig, context, request, response); 070 else 071 serviceAMF(graniteConfig, servicesConfig, context, request, response); 072 } 073 074 protected void serviceAMF(GraniteConfig graniteConfig, ServicesConfig servicesConfig, ServletContext context, 075 HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { 076 log.debug(">> Incoming AMF0 request from: %s", request.getRequestURL()); 077 078 InputStream is = null; 079 OutputStream os = null; 080 081 try { 082 is = new BufferedInputStream(request.getInputStream()); 083 084 HttpGraniteContext.createThreadIntance( 085 graniteConfig, servicesConfig, context, 086 request, response 087 ); 088 089 log.debug(">> Deserializing AMF0 request..."); 090 091 AMF0Deserializer deserializer = new AMF0Deserializer(is); 092 AMF0Message amf0Request = deserializer.getAMFMessage(); 093 094 log.debug(">> Processing AMF0 request: %s", amf0Request); 095 096 AMF0Message amf0Response = AMF0MessageProcessor.process(amf0Request); 097 098 log.debug("<< Serializing AMF0 response: %s", amf0Response); 099 100 response.setStatus(HttpServletResponse.SC_OK); 101 response.setContentType(ContentType.AMF.mimeType()); 102 response.setDateHeader("Expire", 0L); 103 response.setHeader("Cache-Control", "no-store"); 104 105 os = response.getOutputStream(); 106 AMF0Serializer serializer = new AMF0Serializer(os); 107 108 serializer.serializeMessage(amf0Response); 109 110 response.flushBuffer(); 111 } 112 catch (IOException e) { 113 if ("org.apache.catalina.connector.ClientAbortException".equals(e.getClass().getName())) 114 log.debug(e, "Connection closed by client"); 115 else 116 log.error(e, "AMF message error"); 117 throw e; 118 } 119 catch (Exception e) { 120 log.error(e, "AMF message error"); 121 throw new ServletException(e); 122 } 123 finally { 124 GraniteContext.release(); 125 } 126 } 127 128 protected void serviceJMFAMF(GraniteConfig graniteConfig, ServicesConfig servicesConfig, ServletContext context, 129 HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { 130 131 log.debug(">> Incoming JMF+AMF request from: %s", request.getRequestURL()); 132 133 if (jmfSharedContext == null) 134 throw JMFServletContextListener.newSharedContextNotInitializedException(); 135 136 InputStream is = null; 137 OutputStream os = null; 138 139 try { 140 is = request.getInputStream(); 141 142 HttpGraniteContext.createThreadIntance( 143 graniteConfig, servicesConfig, context, 144 request, response 145 ); 146 147 log.debug(">> Deserializing JMF+AMF request..."); 148 149 @SuppressWarnings("all") // JDK7 warning (Resource leak: 'deserializer' is never closed)... 150 JMFDeserializer deserializer = new JMFDeserializer(is, jmfSharedContext); 151 AMF0Message amf0Request = (AMF0Message)deserializer.readObject(); 152 153 log.debug(">> Processing AMF0 request: %s", amf0Request); 154 155 AMF0Message amf0Response = AMF0MessageProcessor.process(amf0Request); 156 157 log.debug("<< Serializing JMF+AMF response: %s", amf0Response); 158 159 response.setStatus(HttpServletResponse.SC_OK); 160 response.setContentType(ContentType.JMF_AMF.mimeType()); 161 response.setDateHeader("Expire", 0L); 162 response.setHeader("Cache-Control", "no-store"); 163 164 os = response.getOutputStream(); 165 166 @SuppressWarnings("all") // JDK7 warning (Resource leak: 'serializer' is never closed)... 167 JMFSerializer serializer = new JMFSerializer(os, jmfSharedContext); 168 serializer.writeObject(amf0Response); 169 170 response.flushBuffer(); 171 } 172 catch (IOException e) { 173 if ("org.apache.catalina.connector.ClientAbortException".equals(e.getClass().getName())) 174 log.debug(e, "Connection closed by client"); 175 else 176 log.error(e, "JMF+AMF message error"); 177 throw e; 178 } 179 catch (Exception e) { 180 log.error(e, "JMF+AMF message error"); 181 throw new ServletException(e); 182 } 183 finally { 184 GraniteContext.release(); 185 } 186 } 187}