001: /*
002: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright
003: * notice. All rights reserved.
004: */
005: package com.tc.net.protocol.tcm;
006:
007: import EDU.oswego.cs.dl.util.concurrent.CopyOnWriteArrayList;
008:
009: import com.tc.logging.TCLogger;
010: import com.tc.logging.TCLogging;
011: import com.tc.util.Assert;
012:
013: import java.util.HashMap;
014: import java.util.HashSet;
015: import java.util.Iterator;
016: import java.util.List;
017: import java.util.Map;
018: import java.util.Set;
019:
020: /**
021: * provides the sessionIDs
022: *
023: * @author steve
024: */
025: class ChannelManagerImpl implements ChannelManager,
026: ChannelEventListener, ServerMessageChannelFactory {
027: private static final TCLogger logger = TCLogging
028: .getLogger(ChannelManager.class);
029: private static final MessageChannelInternal[] EMPTY_CHANNEL_ARARY = new MessageChannelInternal[] {};
030:
031: private final Map channels;
032: private final boolean transportDisconnectRemovesChannel;
033: private final ServerMessageChannelFactory channelFactory;
034: private final List eventListeners = new CopyOnWriteArrayList();
035:
036: public ChannelManagerImpl(
037: boolean transportDisconnectRemovesChannel,
038: ServerMessageChannelFactory channelFactory) {
039: this .channels = new HashMap();
040: this .transportDisconnectRemovesChannel = transportDisconnectRemovesChannel;
041: this .channelFactory = channelFactory;
042: }
043:
044: public MessageChannelInternal createNewChannel(ChannelID id) {
045: MessageChannelInternal channel = channelFactory
046: .createNewChannel(id);
047: synchronized (this ) {
048: channels.put(channel.getChannelID(), channel);
049: channel.addListener(this );
050: }
051: return channel;
052: }
053:
054: private void fireChannelCreatedEvent(MessageChannel channel) {
055: for (Iterator iter = eventListeners.iterator(); iter.hasNext();) {
056: ChannelManagerEventListener eventListener = (ChannelManagerEventListener) iter
057: .next();
058: eventListener.channelCreated(channel);
059: }
060: }
061:
062: private void fireChannelRemovedEvent(MessageChannel channel) {
063: for (Iterator iter = eventListeners.iterator(); iter.hasNext();) {
064: ChannelManagerEventListener eventListener = (ChannelManagerEventListener) iter
065: .next();
066: eventListener.channelRemoved(channel);
067: }
068: }
069:
070: public synchronized MessageChannelInternal getChannel(ChannelID id) {
071: return (MessageChannelInternal) channels.get(id);
072: }
073:
074: public synchronized MessageChannelInternal[] getChannels() {
075: return (MessageChannelInternal[]) channels.values().toArray(
076: EMPTY_CHANNEL_ARARY);
077: }
078:
079: public synchronized void closeAllChannels() {
080: MessageChannelInternal[] channelsCopy = getChannels();
081: for (int i = 0; i < channelsCopy.length; i++) {
082: channelsCopy[i].close();
083: }
084: Assert.assertEquals(0, channels.size());
085: }
086:
087: public synchronized Set getAllChannelIDs() {
088: return new HashSet(channels.keySet());
089: }
090:
091: public synchronized boolean isValidID(ChannelID channelID) {
092: if (channelID == null) {
093: return false;
094: }
095:
096: final MessageChannel channel = getChannel(channelID);
097:
098: if (channel == null) {
099: logger.warn("no channel found for " + channelID);
100: return false;
101: }
102:
103: return true;
104: }
105:
106: public void notifyChannelEvent(ChannelEvent event) {
107: MessageChannel channel = event.getChannel();
108:
109: if (ChannelEventType.CHANNEL_CLOSED_EVENT.matches(event)) {
110: removeChannel(channel);
111: } else if (ChannelEventType.TRANSPORT_DISCONNECTED_EVENT
112: .matches(event)) {
113: if (this .transportDisconnectRemovesChannel) {
114: channel.close();
115: }
116: } else if (ChannelEventType.TRANSPORT_CONNECTED_EVENT
117: .matches(event)) {
118: fireChannelCreatedEvent(channel);
119: }
120: }
121:
122: private void removeChannel(MessageChannel channel) {
123: boolean notfound;
124: synchronized (this ) {
125: notfound = (channels.remove(channel.getChannelID()) == null);
126: }
127: if (notfound) {
128: logger.warn("Remove non-exist channel:"
129: + channel.getChannelID());
130: return;
131: }
132: fireChannelRemovedEvent(channel);
133: }
134:
135: public synchronized void addEventListener(
136: ChannelManagerEventListener listener) {
137: if (listener == null) {
138: throw new IllegalArgumentException(
139: "listener must be non-null");
140: }
141: this.eventListeners.add(listener);
142: }
143:
144: }
|