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.gravity; 023 024import java.io.IOException; 025import java.io.InputStream; 026import java.io.ObjectInput; 027import java.io.ObjectOutput; 028import java.io.OutputStream; 029 030import javax.servlet.ServletConfig; 031import javax.servlet.ServletContext; 032import javax.servlet.ServletException; 033import javax.servlet.http.HttpServletRequest; 034import javax.servlet.http.HttpServletResponse; 035 036import org.granite.context.GraniteContext; 037import org.granite.messaging.webapp.HttpGraniteContext; 038import org.granite.util.ContentType; 039import org.granite.util.UUIDUtil; 040 041import flex.messaging.messages.CommandMessage; 042import flex.messaging.messages.Message; 043 044 045public 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}