/*
* Copyright (C) 2011 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.client.api.base;
import org.jboss.errai.bus.client.api.messaging.Message;
import org.jboss.errai.common.client.protocols.MessageParts;
/**
* A message that is automatically routed back to the originating bus of a
* reference message (usually called the <i>incoming message</i>). When a
* ConversationMessage is dispatched, it will only be delivered to the bus that
* the incoming message originated from.
* <p/>
* <p/>
* <pre>
* public class SomeService implements MessageCallback {
* public void callback(CommandMessage message) {
* ConversationMessage.create(message) // create a ConversationMessage that
* // references the incoming message
* .setSubject("ClientService") // specify the service on the sending
* // bus that should receive the message
* .set("Text", "Hello, World!").sendNowWith(messageBusInstance); // send
* // the
* // message
* }
* }
* </pre>
* <p/>
* It is possible for a message sender to specify a
* {@link org.jboss.errai.common.client.protocols.MessageParts#ReplyTo ReplyTo}
* message component, which by default will be used to route the message. We
* refer to this as a <em>sender-driven conversation</em> as opposed to a
* <em>receiver-driven conversation</em> which is demonstrated in the code
* example above.
*/
public class ConversationMessage extends CommandMessage {
/**
* Creates a new ConversationMessage using an incoming message as a reference.
*
* @param inReplyTo
* the incoming message.
*
* @return a ConversationMessage that will be routed to the MessageBus that
* sent the {@code inReplyTo} message.
*/
public static ConversationMessage create(Message inReplyTo) {
return new ConversationMessage(inReplyTo);
}
/**
* Creates a new ConversationMessage with the specified command type and
* reference message.
*
* @param commandType
* The command type for this message. Command is an optional
* extension for creating services that can respond to different
* specific commands. Must not be null.
* @param inReplyTo
* the incoming message. Must not be null.
*/
public static ConversationMessage create(Enum<?> commandType, Message inReplyTo) {
ConversationMessage message = new ConversationMessage(inReplyTo);
message.command(commandType.name());
return message;
}
/**
* Creates a new ConversationMessage with the specified command type and
* reference message.
*
* @param commandType
* The command type for this message. Command is an optional
* extension for creating services that can respond to different
* specific commands. Must not be null.
* @param inReplyTo
* the incoming message. Must not be null.
*/
public static ConversationMessage create(String commandType, Message inReplyTo) {
ConversationMessage message = new ConversationMessage(inReplyTo);
message.command(commandType);
return message;
}
private ConversationMessage(Message inReplyTo) {
super();
if (inReplyTo.hasResource("Session")) {
setResource("Session", inReplyTo.getResource(Object.class, "Session"));
}
if (inReplyTo.hasPart(MessageParts.ReplyTo)) {
set(MessageParts.ToSubject, inReplyTo.get(String.class, MessageParts.ReplyTo));
}
if (!inReplyTo.hasResource("Session") && !inReplyTo.hasPart(MessageParts.ReplyTo)) {
throw new RuntimeException(
"cannot have a conversation. there is no session data or ReplyTo field." +
" Are you sure you referenced an incoming message?");
}
}
}