/**
* GRANITE DATA SERVICES
* Copyright (C) 2006-2015 GRANITE DATA SERVICES S.A.S.
*
* This file is part of the Granite Data Services Platform.
*
* Granite Data Services is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* Granite Data Services is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
* General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA, or see <http://www.gnu.org/licenses/>.
*/
package org.granite.gravity;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.io.OutputStream;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.granite.config.GraniteConfigListener;
import org.granite.context.GraniteContext;
import org.granite.messaging.jmf.JMFDeserializer;
import org.granite.messaging.jmf.JMFSerializer;
import org.granite.messaging.webapp.HttpGraniteContext;
import org.granite.util.ContentType;
import org.granite.util.UUIDUtil;
import flex.messaging.messages.CommandMessage;
import flex.messaging.messages.Message;
public class GravityServletUtil {
public static final String CONNECT_MESSAGE_KEY = AbstractGravityServlet.class.getName() + ".CONNECT_MESSAGE";
public static void init(ServletConfig config) throws ServletException {
GravityManager.start(config);
}
///////////////////////////////////////////////////////////////////////////
// Connect messages management (request attribute).
public static void setConnectMessage(HttpServletRequest request, Message connect) {
if (!(connect instanceof CommandMessage) && ((CommandMessage)connect).getOperation() != CommandMessage.CONNECT_OPERATION)
throw new IllegalArgumentException("Not a connect message: " + connect);
request.setAttribute(CONNECT_MESSAGE_KEY, connect);
}
public static CommandMessage getConnectMessage(HttpServletRequest request) {
return (CommandMessage)request.getAttribute(CONNECT_MESSAGE_KEY);
}
public static void removeConnectMessage(HttpServletRequest request) {
request.removeAttribute(CONNECT_MESSAGE_KEY);
}
///////////////////////////////////////////////////////////////////////////
// Long polling timeout.
public static long getLongPollingTimeout(ServletContext context) {
return GravityManager.getGravity(context).getGravityConfig().getLongPollingTimeoutMillis();
}
///////////////////////////////////////////////////////////////////////////
// AMF (de)serialization methods.
public static GravityInternal initializeRequest(ServletConfig config, GravityInternal gravity, HttpServletRequest request, HttpServletResponse response) {
HttpGraniteContext.createThreadIntance(
gravity.getGraniteConfig(), gravity.getServicesConfig(),
config.getServletContext(), request, response
);
return gravity;
}
public static Message[] deserialize(GravityInternal gravity, HttpServletRequest request) throws ClassNotFoundException, IOException {
InputStream is = request.getInputStream();
try {
return deserialize(gravity, request, is);
}
finally {
is.close();
}
}
public static Message[] deserialize(GravityInternal gravity, HttpServletRequest request, InputStream is) throws ClassNotFoundException, IOException {
if (ContentType.JMF_AMF.mimeType().equals(request.getContentType())) {
@SuppressWarnings("resource")
JMFDeserializer deserializer = new JMFDeserializer(is, gravity.getGraniteConfig().getSharedContext());
return (Message[])deserializer.readObject();
}
ObjectInput amf3Deserializer = gravity.getGraniteConfig().newAMF3Deserializer(is);
Object[] objects = (Object[])amf3Deserializer.readObject();
Message[] messages = new Message[objects.length];
System.arraycopy(objects, 0, messages, 0, objects.length);
return messages;
}
public static ObjectOutput newSerializer(GravityInternal gravity, OutputStream os, ContentType contentType) {
if (contentType == ContentType.JMF_AMF)
return new JMFSerializer(os, gravity.getGraniteConfig().getSharedContext());
return gravity.getGraniteConfig().newAMF3Serializer(os);
}
public static void serialize(GravityInternal gravity, HttpServletResponse response, Message[] messages, ContentType contentType) throws ServletException, IOException {
if (contentType == ContentType.JMF_AMF && gravity.getGraniteConfig().getSharedContext() == null)
throw GraniteConfigListener.newSharedContextNotInitializedException();
OutputStream os = null;
try {
// For SDK 2.0.1_Hotfix2+ (LCDS 2.5+).
String dsId = null;
for (Message message : messages) {
if ("nil".equals(message.getHeader(Message.DS_ID_HEADER))) {
if (dsId == null)
dsId = UUIDUtil.randomUUID();
message.getHeaders().put(Message.DS_ID_HEADER, dsId);
}
}
response.setStatus(HttpServletResponse.SC_OK);
response.setContentType(contentType.mimeType());
response.setDateHeader("Expire", 0L);
response.setHeader("Cache-Control", "no-store");
os = response.getOutputStream();
ObjectOutput serializer = newSerializer(gravity, os, contentType);
serializer.writeObject(messages);
serializer.flush();
os.flush();
response.flushBuffer();
}
finally {
if (os != null)
os.close();
}
}
public static void cleanupRequest(HttpServletRequest request) {
GraniteContext.release();
}
}