/* * Copyright (C) 2013-2014 Sony Computer Science Laboratories, Inc. All Rights Reserved. * Copyright (C) 2014 Sony Corporation. All Rights Reserved. */ package com.sonycsl.wamp.role; import com.sonycsl.wamp.WampError; import com.sonycsl.wamp.WampPeer; import com.sonycsl.wamp.message.WampEventMessage; import com.sonycsl.wamp.message.WampMessage; import com.sonycsl.wamp.message.WampMessageFactory; import com.sonycsl.wamp.message.WampSubscribeMessage; import com.sonycsl.wamp.message.WampSubscribedMessage; import com.sonycsl.wamp.message.WampUnsubscribeMessage; import com.sonycsl.wamp.message.WampUnsubscribedMessage; import com.sonycsl.wamp.util.DoubleKeyMap; import org.json.JSONObject; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; abstract public class WampSubscriber extends WampRole { private final DoubleKeyMap<WampPeer, Integer, WampMessage> mSubs = new DoubleKeyMap<WampPeer, Integer, WampMessage>(); private final DoubleKeyMap<WampPeer, Integer, WampMessage> mUnsubs = new DoubleKeyMap<WampPeer, Integer, WampMessage>(); private final Map<WampPeer, Map<Integer, String>> mTopicMaps = new ConcurrentHashMap<WampPeer, Map<Integer, String>>(); @Override public final String getRoleName() { return "subscriber"; } @Override public boolean resolveTxMessageImpl(WampPeer receiver, WampMessage msg) { if (msg.isSubscribeMessage()) { mSubs.put(receiver, msg.asSubscribeMessage().getRequestId(), msg); if (!mTopicMaps.containsKey(receiver)) { mTopicMaps.put(receiver, new ConcurrentHashMap<Integer, String>()); } return true; } if (msg.isUnsubscribeMessage()) { mUnsubs.put(receiver, msg.asUnsubscribeMessage().getRequestId(), msg); return true; } return false; } @Override public boolean resolveRxMessageImpl(WampPeer transmitter, WampMessage msg, OnReplyListener listener) { if (msg.isSubscribedMessage()) { return resolveSubscribedMessage(transmitter, msg); } if (msg.isUnsubscribedMessage()) { return resolveUnsubscribedMessage(transmitter, msg); } if (msg.isEventMessage()) { return resolveEventMessage(transmitter, msg, listener); } return false; } private boolean resolveSubscribedMessage(WampPeer transmitter, WampMessage msg) { WampSubscribedMessage subscribedMsg = msg.asSubscribedMessage(); if (!mSubs.containsKey(transmitter, subscribedMsg.getRequestId())) { return false; } WampSubscribeMessage request = mSubs.get(transmitter, subscribedMsg.getRequestId()) .asSubscribeMessage(); WampSubscribedMessage response = msg.asSubscribedMessage(); if (request.getRequestId() != response.getRequestId()) { return false; } Map<Integer, String> topicMap = mTopicMaps.get(transmitter); if (topicMap == null) { return false; } topicMap.put(response.getSubscriptionId(), request.getTopic()); mSubs.remove(transmitter, subscribedMsg.getRequestId()); return true; } private boolean resolveUnsubscribedMessage(WampPeer transmitter, WampMessage msg) { WampUnsubscribedMessage unsubscribedMsg = msg.asUnsubscribedMessage(); if (!mUnsubs.containsKey(transmitter, unsubscribedMsg.getRequestId())) { return false; } WampUnsubscribeMessage request = mUnsubs.get(transmitter, unsubscribedMsg.getRequestId()) .asUnsubscribeMessage(); WampUnsubscribedMessage response = msg.asUnsubscribedMessage(); if (request.getRequestId() != response.getRequestId()) { return false; } Map<Integer, String> topicMap = mTopicMaps.get(transmitter); if (topicMap == null) { return false; } if (!topicMap.containsKey(request.getSubscriptionId())) { return false; } topicMap.remove(request.getSubscriptionId()); mUnsubs.remove(transmitter, unsubscribedMsg.getRequestId()); return true; } private boolean resolveEventMessage(WampPeer transmitter, WampMessage msg, OnReplyListener listener) { WampEventMessage event = msg.asEventMessage(); Map<Integer, String> topicMap = mTopicMaps.get(transmitter); if (topicMap == null) { return false; } final int subId = event.getSubscriptionId(); if (!topicMap.containsKey(subId)) { listener.onReply(transmitter, WampMessageFactory.createError(msg.getMessageType(), -1, new JSONObject(), WampError.NO_SUCH_SUBSCRIPTION)); return true; } onEvent(topicMap.get(subId), msg); return true; } abstract protected void onEvent(String topic, WampMessage msg); }