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.webapp.HttpGraniteContext;
017    import org.granite.util.ContentType;
018    import org.granite.util.UUIDUtil;
019    
020    import flex.messaging.messages.CommandMessage;
021    import flex.messaging.messages.Message;
022    
023    
024    public 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    }