/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
* WSO2 Inc. licenses this file to you 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.wso2.carbon.inbound.endpoint.protocol.websocket.management;
import io.netty.handler.codec.http.websocketx.WebSocketFrame;
import org.wso2.carbon.inbound.endpoint.protocol.websocket.InboundWebsocketChannelContext;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
public class WebsocketSubscriberPathManager {
private static WebsocketSubscriberPathManager instance = null;
private ConcurrentHashMap<String, ConcurrentHashMap<String, List<InboundWebsocketChannelContext>>>
inboundSubscriberPathMap = new ConcurrentHashMap<String, ConcurrentHashMap<String, List<InboundWebsocketChannelContext>>>();
public static WebsocketSubscriberPathManager getInstance() {
if (instance == null) {
instance = new WebsocketSubscriberPathManager();
}
return instance;
}
public void addChannelContext(String inboundName,
String subscriberPath,
InboundWebsocketChannelContext ctx) {
ConcurrentHashMap<String, List<InboundWebsocketChannelContext>> subscriberPathMap =
inboundSubscriberPathMap.get(inboundName);
if (subscriberPathMap == null) {
subscriberPathMap = new ConcurrentHashMap<String, List<InboundWebsocketChannelContext>>();
ArrayList<InboundWebsocketChannelContext> listContext = new ArrayList<InboundWebsocketChannelContext>();
listContext.add(ctx);
subscriberPathMap.put(subscriberPath, listContext);
inboundSubscriberPathMap.put(inboundName, subscriberPathMap);
} else {
List<InboundWebsocketChannelContext> listContext = subscriberPathMap.get(subscriberPath);
if (listContext == null) {
listContext = new ArrayList<InboundWebsocketChannelContext>();
listContext.add(ctx);
subscriberPathMap.put(subscriberPath, listContext);
} else {
listContext.add(ctx);
}
}
}
public void removeChannelContext(String inboundName,
String subscriberPath,
InboundWebsocketChannelContext ctx) {
ConcurrentHashMap<String, List<InboundWebsocketChannelContext>> subscriberPathMap =
inboundSubscriberPathMap.get(inboundName);
List<InboundWebsocketChannelContext> listContext = subscriberPathMap.get(subscriberPath);
for (Object context : listContext.toArray()) {
if (((InboundWebsocketChannelContext) context).getChannelIdentifier()
.equals(ctx.getChannelIdentifier())) {
listContext.remove(context);
break;
}
}
if (listContext.isEmpty()) {
listContext.clear();
subscriberPathMap.remove(subscriberPath);
}
if (subscriberPathMap.isEmpty()) {
subscriberPathMap.clear();
inboundSubscriberPathMap.remove(inboundName);
}
}
public List<InboundWebsocketChannelContext> getSubscriberPathChannelContextList(String inboundName,
String subscriberPath) {
return inboundSubscriberPathMap.get(inboundName).get(subscriberPath);
}
public void broadcastOnSubscriberPath(WebSocketFrame frame,
String inboundName,
String subscriberPath) {
List<InboundWebsocketChannelContext> contextList =
getSubscriberPathChannelContextList(inboundName, subscriberPath);
for (InboundWebsocketChannelContext context : contextList) {
WebSocketFrame duplicatedFrame = frame.duplicate();
context.writeToChannel(duplicatedFrame);
}
}
public void exclusiveBroadcastOnSubscriberPath(WebSocketFrame frame,
String inboundName,
String subscriberPath,
InboundWebsocketChannelContext ctx) {
List<InboundWebsocketChannelContext> contextList =
getSubscriberPathChannelContextList(inboundName, subscriberPath);
for (InboundWebsocketChannelContext context : contextList) {
if (!context.getChannelIdentifier().equals(ctx.getChannelIdentifier())) {
WebSocketFrame duplicatedFrame = frame.duplicate();
context.writeToChannel(duplicatedFrame);
}
}
}
}