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
021 package org.granite.messaging.webapp;
022
023 import java.io.BufferedInputStream;
024 import java.io.IOException;
025 import java.io.InputStream;
026 import java.io.OutputStream;
027
028 import javax.servlet.ServletContext;
029 import javax.servlet.ServletException;
030 import javax.servlet.http.HttpServletRequest;
031 import javax.servlet.http.HttpServletResponse;
032
033 import org.granite.config.GraniteConfig;
034 import org.granite.config.flex.ServicesConfig;
035 import org.granite.context.GraniteContext;
036 import org.granite.logging.Logger;
037 import org.granite.messaging.amf.AMF0Message;
038 import org.granite.messaging.amf.io.AMF0Deserializer;
039 import org.granite.messaging.amf.io.AMF0Serializer;
040 import org.granite.messaging.amf.process.AMF0MessageProcessor;
041 import org.granite.messaging.jmf.JMFDeserializer;
042 import org.granite.messaging.jmf.JMFSerializer;
043 import org.granite.messaging.jmf.JMFServletContextListener;
044 import org.granite.messaging.jmf.SharedContext;
045 import org.granite.util.ContentType;
046
047 /**
048 * @author Franck WOLFF
049 */
050 public 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 }