/* * Copyright (C) 2012 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jboss.errai.bus.server.io; import static org.jboss.errai.bus.client.api.base.CommandMessage.createWithParts; import static org.jboss.errai.bus.client.api.base.CommandMessage.createWithPartsFromRawMap; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; import org.jboss.errai.bus.client.api.QueueSession; import org.jboss.errai.bus.client.api.RoutingFlag; import org.jboss.errai.bus.client.api.messaging.Message; import org.jboss.errai.common.client.protocols.MessageParts; import org.jboss.errai.marshalling.client.api.json.EJArray; import org.jboss.errai.marshalling.client.api.json.EJValue; import org.jboss.errai.marshalling.client.marshallers.ErraiProtocolEnvelopeMarshaller; import org.jboss.errai.marshalling.server.DecodingSession; import org.jboss.errai.marshalling.server.JSONDecoder; import org.jboss.errai.marshalling.server.JSONStreamDecoder; import org.jboss.errai.marshalling.server.MappingContextSingleton; /** * The <tt>MessageFactory</tt> facilitates the building of a command message using a JSON string */ public class MessageFactory { /** * Decodes a JSON string to a map (string name -> object) * * @param in - JSON string * @return map representing the string */ public static Map<String, Object> decodeToMap(String in) { //noinspection unchecked return (Map<String, Object>) JSONDecoder.decode(in); } /** * Creates the command message from the given JSON string and session. The message is constructed in * parts depending on the string * * @param session - the queue session in which the message exists * @param request - * @param json - the string representing the parts of the message * @return the message array constructed using the JSON string */ public static Message createCommandMessage(QueueSession session, HttpServletRequest request, String json) { if (json.length() == 0) return null; Map<String, Object> parts = decodeToMap(json); parts.remove(MessageParts.SessionID.name()); return from(parts, session, request); } @SuppressWarnings("unchecked") public static Message createCommandMessage(QueueSession session, String json) { if (json.length() == 0) return null; Message msg = createWithPartsFromRawMap(ErraiProtocolEnvelopeMarshaller.INSTANCE.demarshall(JSONDecoder.decode(json), new DecodingSession(MappingContextSingleton.get()))) .setResource("Session", session) .setResource("SessionID", session.getSessionId()); msg.setFlag(RoutingFlag.FromRemote); return msg; } public static List<Message> createCommandMessage(QueueSession session, HttpServletRequest request) throws IOException { EJValue value = JSONStreamDecoder.decode(request.getInputStream()); if (value.isObject() != null) { return Collections.singletonList(from(getParts(value), session, request)); } else if (value.isArray() != null) { EJArray arr = value.isArray(); List<Message> messages = new ArrayList<Message>(arr.size()); for (int i = 0; i < arr.size(); i++) { messages.add(from(getParts(arr.get(i)), session, request)); } return messages; } else if (value.isNull()) { return Collections.<Message>emptyList(); } else { throw new RuntimeException("bad payload"); } } public static List<Message> createCommandMessage(QueueSession session, InputStream inputStream) throws IOException { EJValue value = JSONStreamDecoder.decode(inputStream); if (value.isObject() != null) { return Collections.singletonList(from(getParts(value), session, null)); } else if (value.isArray() != null) { EJArray arr = value.isArray(); List<Message> messages = new ArrayList<Message>(arr.size()); for (int i = 0; i < arr.size(); i++) { messages.add(from(getParts(arr.get(i)), session, null)); } return messages; } else { throw new RuntimeException("bad payload"); } } public static List<Message> createCommandMessage(QueueSession session, EJValue value) { if (value.isObject() != null) { return Collections.singletonList(from(getParts(value), session, null)); } else if (value.isArray() != null) { EJArray arr = value.isArray(); List<Message> messages = new ArrayList<Message>(arr.size()); for (int i = 0; i < arr.size(); i++) { messages.add(from(getParts(arr.get(i)), session, null)); } return messages; } else { throw new RuntimeException("bad payload"); } } private static Map getParts(EJValue value) { return ErraiProtocolEnvelopeMarshaller.INSTANCE.demarshall(value, new DecodingSession(MappingContextSingleton.get())); } @SuppressWarnings("unchecked") private static Message from(Map parts, QueueSession session, HttpServletRequest request) { Message msg = createWithParts(parts) .setResource("Session", session) .setResource("SessionID", session.getSessionId()) .setResource(HttpServletRequest.class.getName(), request); msg.setFlag(RoutingFlag.FromRemote); return msg; } }