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