/*
* 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.WampInvocationMessage;
import com.sonycsl.wamp.message.WampMessage;
import com.sonycsl.wamp.message.WampMessageFactory;
import com.sonycsl.wamp.message.WampRegisterMessage;
import com.sonycsl.wamp.message.WampRegisteredMessage;
import com.sonycsl.wamp.message.WampUnregisterMessage;
import com.sonycsl.wamp.message.WampUnregisteredMessage;
import com.sonycsl.wamp.util.DoubleKeyMap;
import org.json.JSONObject;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
abstract public class WampCallee extends WampRole {
private final DoubleKeyMap<WampPeer, Integer, WampMessage> mRegs = new DoubleKeyMap<WampPeer, Integer, WampMessage>();
private final DoubleKeyMap<WampPeer, Integer, WampMessage> mUnregs = new DoubleKeyMap<WampPeer, Integer, WampMessage>();
private final Map<WampPeer, Map<Integer, String>> mProcMaps = new ConcurrentHashMap<WampPeer, Map<Integer, String>>();
@Override
public final String getRoleName() {
return "callee";
}
@Override
protected final boolean resolveTxMessageImpl(WampPeer receiver, WampMessage msg) {
if (msg.isRegisterMessage()) {
mRegs.put(receiver, msg.asRegisterMessage().getRequestId(), msg);
if (mProcMaps.get(receiver) == null) {
mProcMaps.put(receiver, new ConcurrentHashMap<Integer, String>());
}
return true;
}
if (msg.isUnregisterMessage()) {
mUnregs.put(receiver, msg.asUnregisterMessage().getRequestId(), msg);
return true;
}
return false;
}
@Override
protected final boolean resolveRxMessageImpl(WampPeer transmitter, WampMessage msg,
OnReplyListener listener) {
if (msg.isRegisteredMessage()) {
return resolveRegisteredMessage(transmitter, msg);
}
if (msg.isUnregisteredMessage()) {
return resolveUnregisteredMessage(transmitter, msg);
}
if (msg.isInvocationMessage()) {
return resolveInvocationMessage(transmitter, msg, listener);
}
return false;
}
private boolean resolveRegisteredMessage(WampPeer transmitter, WampMessage msg) {
WampRegisteredMessage registeredMsg = msg.asRegisteredMessage();
if (!mRegs.containsKey(transmitter, registeredMsg.getRequestId())) {
return false;
}
WampRegisterMessage request = mRegs.get(transmitter, registeredMsg.getRequestId())
.asRegisterMessage();
WampRegisteredMessage response = msg.asRegisteredMessage();
if (request.getRequestId() != response.getRequestId()) {
return false;
}
Map<Integer, String> procMap = mProcMaps.get(transmitter);
if (procMap == null) {
return false;
}
procMap.put(response.getRegistrationId(), request.getProcedure());
mRegs.remove(transmitter, registeredMsg.getRequestId());
return true;
}
private boolean resolveUnregisteredMessage(WampPeer transmitter, WampMessage msg) {
WampUnregisteredMessage unregisteredMsg = msg.asUnregisteredMessage();
if (!mUnregs.containsKey(transmitter, unregisteredMsg.getRequestId())) {
return false;
}
WampUnregisterMessage request = mUnregs.get(transmitter, unregisteredMsg.getRequestId())
.asUnregisterMessage();
WampUnregisteredMessage response = msg.asUnregisteredMessage();
if (request.getRequestId() != response.getRequestId()) {
return false;
}
Map<Integer, String> procMap = mProcMaps.get(transmitter);
if (procMap == null) {
return false;
}
if (!procMap.containsKey(request.getRegistrationId())) {
return false;
}
procMap.remove(request.getRegistrationId());
mUnregs.remove(transmitter, unregisteredMsg.getRequestId());
return true;
}
private boolean resolveInvocationMessage(final WampPeer transmitter, final WampMessage msg,
final OnReplyListener listener) {
WampInvocationMessage invocation = msg.asInvocationMessage();
final Map<Integer, String> procMap = mProcMaps.get(transmitter);
if (procMap == null) {
return false;
}
final int regId = invocation.getRegistrationId();
if (!procMap.containsKey(regId)) {
listener.onReply(transmitter, WampMessageFactory.createError(msg.getMessageType(), -1,
new JSONObject(), WampError.NO_SUCH_PROCEDURE));
return true;
}
new Thread(new Runnable() {
@Override
public void run() {
WampMessage reply = invocation(procMap.get(regId), msg);
if (!reply.isYieldMessage() && !reply.isErrorMessage()) {
return;
}
listener.onReply(transmitter, reply);
}
}).start();
return true;
}
abstract protected WampMessage invocation(String procedure, WampMessage msg);
}