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
054        ///////////////////////////////////////////////////////////////////////////
055        // Connect messages management (request attribute).
056        
057        public static void setConnectMessage(HttpServletRequest request, Message connect) {
058                if (!(connect instanceof CommandMessage) && ((CommandMessage)connect).getOperation() != CommandMessage.CONNECT_OPERATION)
059                        throw new IllegalArgumentException("Not a connect message: " + connect);
060                request.setAttribute(CONNECT_MESSAGE_KEY, connect);
061        }
062        
063        public static CommandMessage getConnectMessage(HttpServletRequest request) {
064                return (CommandMessage)request.getAttribute(CONNECT_MESSAGE_KEY);
065        }
066        
067        public static void removeConnectMessage(HttpServletRequest request) {
068                request.removeAttribute(CONNECT_MESSAGE_KEY);
069        }
070
071        ///////////////////////////////////////////////////////////////////////////
072        // Long polling timeout.
073        
074        public static long getLongPollingTimeout(ServletContext context) {
075                return GravityManager.getGravity(context).getGravityConfig().getLongPollingTimeoutMillis();
076        }
077
078        ///////////////////////////////////////////////////////////////////////////
079        // AMF (de)serialization methods.
080        
081        public static Gravity initializeRequest(ServletConfig config, Gravity gravity, HttpServletRequest request, HttpServletResponse response) {
082        HttpGraniteContext.createThreadIntance(
083            gravity.getGraniteConfig(), gravity.getServicesConfig(),
084            config.getServletContext(), request, response
085        );
086        return gravity;
087        }
088
089        public static Message[] deserialize(Gravity gravity, HttpServletRequest request) throws ClassNotFoundException, IOException {
090                InputStream is = request.getInputStream();
091                try {
092                        return deserialize(gravity, request, is);
093                }
094                finally {
095                        is.close();
096                }
097        }
098        
099        public static Message[] deserialize(Gravity gravity, HttpServletRequest request, InputStream is) throws ClassNotFoundException, IOException {
100                ObjectInput amf3Deserializer = gravity.getGraniteConfig().newAMF3Deserializer(is);
101        Object[] objects = (Object[])amf3Deserializer.readObject();
102        Message[] messages = new Message[objects.length];
103        System.arraycopy(objects, 0, messages, 0, objects.length);
104        
105        return messages;
106        }
107        
108        public static void serialize(Gravity gravity, HttpServletResponse response, Message[] messages) throws IOException {
109                OutputStream os = null;
110                try {
111            // For SDK 2.0.1_Hotfix2+ (LCDS 2.5+).
112                        String dsId = null;
113            for (Message message : messages) {
114                    if ("nil".equals(message.getHeader(Message.DS_ID_HEADER))) {
115                        if (dsId == null)
116                                dsId = UUIDUtil.randomUUID();
117                        message.getHeaders().put(Message.DS_ID_HEADER, dsId);
118                    }
119            }
120                        
121                response.setStatus(HttpServletResponse.SC_OK);
122                response.setContentType(ContentType.AMF.mimeType());
123                response.setDateHeader("Expire", 0L);
124                response.setHeader("Cache-Control", "no-store");
125                
126                os = response.getOutputStream();
127                ObjectOutput amf3Serializer = gravity.getGraniteConfig().newAMF3Serializer(os);
128                amf3Serializer.writeObject(messages);
129                
130                os.flush();
131                response.flushBuffer();
132                }
133                finally {
134                        if (os != null)
135                                os.close();
136                }
137        }
138        
139        public static void cleanupRequest(HttpServletRequest request) {
140                GraniteContext.release();
141        }
142}