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 */
022 package org.granite.gravity;
023
024 import java.io.IOException;
025 import java.io.InputStream;
026 import java.io.ObjectInput;
027 import java.io.ObjectOutput;
028 import java.io.OutputStream;
029
030 import javax.servlet.ServletConfig;
031 import javax.servlet.ServletContext;
032 import javax.servlet.ServletException;
033 import javax.servlet.http.HttpServletRequest;
034 import javax.servlet.http.HttpServletResponse;
035
036 import org.granite.context.GraniteContext;
037 import org.granite.messaging.webapp.HttpGraniteContext;
038 import org.granite.util.ContentType;
039 import org.granite.util.UUIDUtil;
040
041 import flex.messaging.messages.CommandMessage;
042 import flex.messaging.messages.Message;
043
044
045 public class GravityServletUtil {
046
047 public static final String CONNECT_MESSAGE_KEY = AbstractGravityServlet.class.getName() + ".CONNECT_MESSAGE";
048
049 public static void init(ServletConfig config) throws ServletException {
050 GravityManager.start(config);
051 }
052
053 public static void rejectJMFContentType(HttpServletRequest request) throws ServletException {
054 if (ContentType.JMF_AMF.mimeType().equals(request.getContentType()))
055 throw new ServletException("JMF not supported, use Servlet 3 AsyncServlet");
056 }
057
058 ///////////////////////////////////////////////////////////////////////////
059 // Connect messages management (request attribute).
060
061 public static void setConnectMessage(HttpServletRequest request, Message connect) {
062 if (!(connect instanceof CommandMessage) && ((CommandMessage)connect).getOperation() != CommandMessage.CONNECT_OPERATION)
063 throw new IllegalArgumentException("Not a connect message: " + connect);
064 request.setAttribute(CONNECT_MESSAGE_KEY, connect);
065 }
066
067 public static CommandMessage getConnectMessage(HttpServletRequest request) {
068 return (CommandMessage)request.getAttribute(CONNECT_MESSAGE_KEY);
069 }
070
071 public static void removeConnectMessage(HttpServletRequest request) {
072 request.removeAttribute(CONNECT_MESSAGE_KEY);
073 }
074
075 ///////////////////////////////////////////////////////////////////////////
076 // Long polling timeout.
077
078 public static long getLongPollingTimeout(ServletContext context) {
079 return GravityManager.getGravity(context).getGravityConfig().getLongPollingTimeoutMillis();
080 }
081
082 ///////////////////////////////////////////////////////////////////////////
083 // AMF (de)serialization methods.
084
085 public static Gravity initializeRequest(ServletConfig config, Gravity gravity, HttpServletRequest request, HttpServletResponse response) {
086 HttpGraniteContext.createThreadIntance(
087 gravity.getGraniteConfig(), gravity.getServicesConfig(),
088 config.getServletContext(), request, response
089 );
090 return gravity;
091 }
092
093 public static Message[] deserialize(Gravity gravity, HttpServletRequest request) throws ClassNotFoundException, IOException {
094 InputStream is = request.getInputStream();
095 try {
096 return deserialize(gravity, request, is);
097 }
098 finally {
099 is.close();
100 }
101 }
102
103 public static Message[] deserialize(Gravity gravity, HttpServletRequest request, InputStream is) throws ClassNotFoundException, IOException {
104 ObjectInput amf3Deserializer = gravity.getGraniteConfig().newAMF3Deserializer(is);
105 Object[] objects = (Object[])amf3Deserializer.readObject();
106 Message[] messages = new Message[objects.length];
107 System.arraycopy(objects, 0, messages, 0, objects.length);
108
109 return messages;
110 }
111
112 public static void serialize(Gravity gravity, HttpServletResponse response, Message[] messages) throws IOException {
113 OutputStream os = null;
114 try {
115 // For SDK 2.0.1_Hotfix2+ (LCDS 2.5+).
116 String dsId = null;
117 for (Message message : messages) {
118 if ("nil".equals(message.getHeader(Message.DS_ID_HEADER))) {
119 if (dsId == null)
120 dsId = UUIDUtil.randomUUID();
121 message.getHeaders().put(Message.DS_ID_HEADER, dsId);
122 }
123 }
124
125 response.setStatus(HttpServletResponse.SC_OK);
126 response.setContentType(ContentType.AMF.mimeType());
127 response.setDateHeader("Expire", 0L);
128 response.setHeader("Cache-Control", "no-store");
129
130 os = response.getOutputStream();
131 ObjectOutput amf3Serializer = gravity.getGraniteConfig().newAMF3Serializer(os);
132 amf3Serializer.writeObject(messages);
133
134 os.flush();
135 response.flushBuffer();
136 }
137 finally {
138 if (os != null)
139 os.close();
140 }
141 }
142
143 public static void cleanupRequest(HttpServletRequest request) {
144 GraniteContext.release();
145 }
146 }