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