001package org.granite.gravity;
002
003import java.io.IOException;
004import java.io.InputStream;
005import java.io.ObjectInput;
006import java.io.ObjectOutput;
007import java.io.OutputStream;
008
009import javax.servlet.ServletConfig;
010import javax.servlet.ServletContext;
011import javax.servlet.ServletException;
012import javax.servlet.http.HttpServletRequest;
013import javax.servlet.http.HttpServletResponse;
014
015import org.granite.context.GraniteContext;
016import org.granite.messaging.webapp.HttpGraniteContext;
017import org.granite.util.ContentType;
018import org.granite.util.UUIDUtil;
019
020import flex.messaging.messages.CommandMessage;
021import flex.messaging.messages.Message;
022
023
024public class GravityServletUtil {
025
026    public static final String CONNECT_MESSAGE_KEY = AbstractGravityServlet.class.getName() + ".CONNECT_MESSAGE";
027
028    public static void init(ServletConfig config) throws ServletException {
029        GravityManager.start(config);
030    }
031    
032
033        ///////////////////////////////////////////////////////////////////////////
034        // Connect messages management (request attribute).
035        
036        public static void setConnectMessage(HttpServletRequest request, Message connect) {
037                if (!(connect instanceof CommandMessage) && ((CommandMessage)connect).getOperation() != CommandMessage.CONNECT_OPERATION)
038                        throw new IllegalArgumentException("Not a connect message: " + connect);
039                request.setAttribute(CONNECT_MESSAGE_KEY, connect);
040        }
041        
042        public static CommandMessage getConnectMessage(HttpServletRequest request) {
043                return (CommandMessage)request.getAttribute(CONNECT_MESSAGE_KEY);
044        }
045        
046        public static void removeConnectMessage(HttpServletRequest request) {
047                request.removeAttribute(CONNECT_MESSAGE_KEY);
048        }
049
050        ///////////////////////////////////////////////////////////////////////////
051        // Long polling timeout.
052        
053        public static long getLongPollingTimeout(ServletContext context) {
054                return GravityManager.getGravity(context).getGravityConfig().getLongPollingTimeoutMillis();
055        }
056
057        ///////////////////////////////////////////////////////////////////////////
058        // AMF (de)serialization methods.
059        
060        public static Gravity initializeRequest(ServletConfig config, Gravity gravity, HttpServletRequest request, HttpServletResponse response) {
061        HttpGraniteContext.createThreadIntance(
062            gravity.getGraniteConfig(), gravity.getServicesConfig(),
063            config.getServletContext(), request, response
064        );
065        return gravity;
066        }
067
068        public static Message[] deserialize(Gravity gravity, HttpServletRequest request) throws ClassNotFoundException, IOException {
069                InputStream is = request.getInputStream();
070                try {
071                        return deserialize(gravity, request, is);
072                }
073                finally {
074                        is.close();
075                }
076        }
077        
078        public static Message[] deserialize(Gravity gravity, HttpServletRequest request, InputStream is) throws ClassNotFoundException, IOException {
079                ObjectInput amf3Deserializer = gravity.getGraniteConfig().newAMF3Deserializer(is);
080        Object[] objects = (Object[])amf3Deserializer.readObject();
081        Message[] messages = new Message[objects.length];
082        System.arraycopy(objects, 0, messages, 0, objects.length);
083        
084        return messages;
085        }
086        
087        public static void serialize(Gravity gravity, HttpServletResponse response, Message[] messages) throws IOException {
088                OutputStream os = null;
089                try {
090            // For SDK 2.0.1_Hotfix2+ (LCDS 2.5+).
091                        String dsId = null;
092            for (Message message : messages) {
093                    if ("nil".equals(message.getHeader(Message.DS_ID_HEADER))) {
094                        if (dsId == null)
095                                dsId = UUIDUtil.randomUUID();
096                        message.getHeaders().put(Message.DS_ID_HEADER, dsId);
097                    }
098            }
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                ObjectOutput amf3Serializer = gravity.getGraniteConfig().newAMF3Serializer(os);
107                amf3Serializer.writeObject(messages);
108                
109                os.flush();
110                response.flushBuffer();
111                }
112                finally {
113                        if (os != null)
114                                os.close();
115                }
116        }
117        
118        public static void cleanupRequest(HttpServletRequest request) {
119                GraniteContext.release();
120        }
121}