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 }