@Override
@SuppressWarnings({"unchecked", "SynchronizationOnLocalVariableOrMethodParameter"})
public void callback(final Message message) {
try {
final QueueSession session = getSession(message);
MessageQueueImpl queue = (MessageQueueImpl) messageQueues.get(session);
switch (BusCommand.valueOf(message.getCommandType())) {
case Heartbeat:
if (queue != null) {
queue.heartBeat();
}
break;
case RemoteSubscribe:
if (queue == null) return;
if (message.hasPart(MessageParts.SubjectsList)) {
for (final String subject : (List<String>) message.get(List.class, MessageParts.SubjectsList)) {
remoteSubscribe(session, queue, subject);
}
}
else if (message.hasPart(MessageParts.RemoteServices)) {
for (final String subject : message.get(String.class, MessageParts.RemoteServices).split(",")) {
remoteSubscribe(session, queue, subject);
}
}
else {
remoteSubscribe(session, messageQueues.get(session),
message.get(String.class, MessageParts.Subject));
}
break;
case RemoteUnsubscribe:
if (queue == null) return;
remoteUnsubscribe(session, queue,
message.get(String.class, MessageParts.Subject));
break;
case Disconnect:
if (queue == null) return;
synchronized (messageQueues) {
queue.stopQueue();
closeQueue(queue);
session.endSession();
}
break;
case Resend:
if (queue == null) return;
case Associate: {
List<Message> deferred = null;
synchronized (messageQueues) {
if (messageQueues.containsKey(session)) {
final MessageQueue q = messageQueues.get(session);
synchronized (q) {
if (deferredQueue.containsKey(q)) {
deferred = deferredQueue.remove(q);
}
}
messageQueues.get(session).stopQueue();
}
queue = new MessageQueueImpl(transmissionbuffer, session, messageQueueTimeoutSecs);
addQueue(session, queue);
if (deferred != null) {
deferredQueue.put(queue, deferred);
}
remoteSubscribe(session, queue, BuiltInServices.ClientBus.name());
}
for (final String svc : message.get(String.class, MessageParts.RemoteServices).split(",")) {
remoteSubscribe(session, queue, svc);
}
if (isMonitor()) {
busMonitor.notifyQueueAttached(session.getSessionId(), queue);
}
final Message msg = ConversationMessage.create(message)
.toSubject(BuiltInServices.ClientBus.name())
.command(BusCommand.FinishAssociation);
final StringBuilder subjects = new StringBuilder();
for (final String s : new HashSet<String>(globalSubscriptions)) {
if (subjects.length() != 0) {
subjects.append(',');
}
subjects.append(s);
}
msg.set(RemoteServices, subjects.toString());
final StringBuilder capabilitiesBuffer = new StringBuilder(25);
final boolean first;
if (doLongPolling) {
capabilitiesBuffer.append(Capabilities.LongPolling.name());
first = false;
}
else {
capabilitiesBuffer.append(Capabilities.ShortPolling.name());
first = false;
msg.set(MessageParts.PollFrequency, hostedModeTesting ? 50 : 250);
}
if (webSocketServer || webSocketServlet) {
if (!first) {
capabilitiesBuffer.append(',');
}
capabilitiesBuffer.append(Capabilities.WebSockets.name());
/**
* Advertise where the client can find a websocket.
*/
final String webSocketURL;
final HttpServletRequest request
= message.getResource(HttpServletRequest.class, HttpServletRequest.class.getName());
if (webSocketServlet) {
webSocketURL = "ws://" + request.getHeader("Host") + webSocketPath;
}
else {
webSocketURL = "ws://" + request.getServerName() + ":" + webSocketPort + webSocketPath;
}
msg.set(MessageParts.WebSocketURL, webSocketURL);
msg.set(MessageParts.WebSocketToken, WebSocketTokenManager.getNewOneTimeToken(session));
}
if (sseEnabled && !session.hasAttribute("NoSSE")) {
capabilitiesBuffer.append(",").append(Capabilities.SSE.name());
}
msg.set(MessageParts.CapabilitiesFlags, capabilitiesBuffer.toString());