001: /*
002: * All content copyright (c) 2003-2007 Terracotta, Inc., except as may otherwise be noted in a separate copyright
003: * notice. All rights reserved.
004: */
005: package com.tc.objectserver.persistence.sleepycat;
006:
007: import EDU.oswego.cs.dl.util.concurrent.CopyOnWriteArrayList;
008:
009: import com.tc.net.protocol.tcm.ChannelID;
010: import com.tc.net.protocol.tcm.MessageChannel;
011: import com.tc.net.protocol.transport.ConnectionID;
012: import com.tc.net.protocol.transport.ConnectionIDFactoryListener;
013: import com.tc.net.protocol.transport.ConnectionIDFactory;
014: import com.tc.object.net.DSOChannelManagerEventListener;
015: import com.tc.objectserver.persistence.api.ClientStatePersistor;
016: import com.tc.objectserver.persistence.impl.ClientNotFoundException;
017: import com.tc.util.Assert;
018: import com.tc.util.sequence.MutableSequence;
019:
020: import java.util.HashSet;
021: import java.util.Iterator;
022: import java.util.List;
023: import java.util.Set;
024:
025: public class ConnectionIDFactoryImpl implements ConnectionIDFactory,
026: DSOChannelManagerEventListener {
027:
028: private final ClientStatePersistor clientStateStore;
029: private final MutableSequence connectionIDSequence;
030: private String uid;
031: private List listeners = new CopyOnWriteArrayList();
032:
033: public ConnectionIDFactoryImpl(ClientStatePersistor clientStateStore) {
034: this .clientStateStore = clientStateStore;
035: this .connectionIDSequence = clientStateStore
036: .getConnectionIDSequence();
037: this .uid = connectionIDSequence.getUID();
038: }
039:
040: public ConnectionID nextConnectionId() {
041: Assert.assertNotNull(uid);
042: long clientID = connectionIDSequence.next();
043: // Make sure we save the fact that we are giving out this id to someone in the database before giving it out.
044: clientStateStore.saveClientState(new ChannelID(clientID));
045: ConnectionID rv = new ConnectionID(clientID, uid);
046: fireCreationEvent(rv);
047: return rv;
048: }
049:
050: private void fireCreationEvent(ConnectionID rv) {
051: for (Iterator i = listeners.iterator(); i.hasNext();) {
052: ConnectionIDFactoryListener listener = (ConnectionIDFactoryListener) i
053: .next();
054: listener.connectionIDCreated(rv);
055: }
056: }
057:
058: private void fireDestroyedEvent(ConnectionID connectionID) {
059: for (Iterator i = listeners.iterator(); i.hasNext();) {
060: ConnectionIDFactoryListener listener = (ConnectionIDFactoryListener) i
061: .next();
062: listener.connectionIDDestroyed(connectionID);
063: }
064: }
065:
066: public void init(String clusterID, long nextAvailChannelID,
067: Set connections) {
068: this .uid = clusterID;
069: if (nextAvailChannelID >= 0) {
070: this .connectionIDSequence.setNext(nextAvailChannelID);
071: }
072: for (Iterator i = connections.iterator(); i.hasNext();) {
073: ConnectionID cid = (ConnectionID) i.next();
074: Assert.assertEquals(clusterID, cid.getServerID());
075: this .clientStateStore.saveClientState(new ChannelID(cid
076: .getChannelID()));
077: }
078: }
079:
080: public Set loadConnectionIDs() {
081: Assert.assertNotNull(uid);
082: Set connections = new HashSet();
083: for (Iterator i = clientStateStore.loadClientIDs().iterator(); i
084: .hasNext();) {
085: connections.add(new ConnectionID(((ChannelID) i.next())
086: .toLong(), uid));
087: }
088: return connections;
089: }
090:
091: public void registerForConnectionIDEvents(
092: ConnectionIDFactoryListener listener) {
093: listeners.add(listener);
094: }
095:
096: public void channelCreated(MessageChannel channel) {
097: // NOP
098: }
099:
100: public void channelRemoved(MessageChannel channel) {
101: ChannelID clientID = channel.getChannelID();
102: try {
103: clientStateStore.deleteClientState(clientID);
104: } catch (ClientNotFoundException e) {
105: throw new AssertionError(e);
106: }
107: fireDestroyedEvent(new ConnectionID(clientID.toLong(), uid));
108: }
109:
110: }
|