diff options
| author | slewis | 2005-01-13 08:36:54 +0000 |
|---|---|---|
| committer | slewis | 2005-01-13 08:36:54 +0000 |
| commit | fa7024f4593e8b7536a13f658c0741bc99319b74 (patch) | |
| tree | 0aeba4557b3e0036265b4328be33e577bf9b8d00 | |
| parent | 10bde74edb4d67ed0abcec745369547e85a62dfc (diff) | |
| download | org.eclipse.ecf-fa7024f4593e8b7536a13f658c0741bc99319b74.tar.gz org.eclipse.ecf-fa7024f4593e8b7536a13f658c0741bc99319b74.tar.xz org.eclipse.ecf-fa7024f4593e8b7536a13f658c0741bc99319b74.zip | |
Formatting of source code
3 files changed, 1728 insertions, 1641 deletions
diff --git a/framework/bundles/org.eclipse.ecf.provider/src/org/eclipse/ecf/provider/generic/ClientSOContainer.java b/framework/bundles/org.eclipse.ecf.provider/src/org/eclipse/ecf/provider/generic/ClientSOContainer.java index d2be87dbd..52ab2442e 100644 --- a/framework/bundles/org.eclipse.ecf.provider/src/org/eclipse/ecf/provider/generic/ClientSOContainer.java +++ b/framework/bundles/org.eclipse.ecf.provider/src/org/eclipse/ecf/provider/generic/ClientSOContainer.java @@ -1,13 +1,11 @@ -/**************************************************************************** -* Copyright (c) 2004 Composent, Inc. and others. -* All rights reserved. This program and the accompanying materials -* are made available under the terms of the Eclipse Public License v1.0 -* which accompanies this distribution, and is available at -* http://www.eclipse.org/legal/epl-v10.html -* -* Contributors: -* Composent, Inc. - initial API and implementation -*****************************************************************************/ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ package org.eclipse.ecf.provider.generic; @@ -34,348 +32,369 @@ import org.eclipse.ecf.core.identity.ID; import org.eclipse.ecf.provider.generic.gmm.Member; public abstract class ClientSOContainer extends SOContainer { - ISynchAsynchConnection connection; - protected ID remoteServerID; - byte connectionState; - public static final byte UNCONNECTED = 0; - public static final byte CONNECTING = 1; - public static final byte CONNECTED = 2; - - static final class Lock { - } - - Lock connectLock; - - public ClientSOContainer(ISharedObjectContainerConfig config) { - super(config); - connection = null; - connectionState = UNCONNECTED; - connectLock = new Lock(); - } - - public void dispose(long wait) { - synchronized (connectLock) { - isClosing = true; - if (isConnected()) { - this.leaveGroup(); - } else if (isConnecting()) { - killConnection(connection); - } - remoteServerID = null; - } - super.dispose(wait); - } - - public final boolean isGroupServer() { - return false; - } - - public final boolean isGroupManager() { - return false; - } - - public ID getGroupID() { - return remoteServerID; - } - - public void joinGroup(ID remote, Object data) - throws SharedObjectContainerJoinException { - // first notify synchonously - fireContainerEvent(new SharedObjectContainerJoinGroupEvent(this.getID(),remote,data)); - try { - if (isClosing) - throw new IllegalStateException("container is closing"); - debug("joingroup:" + remote + ":" + data); - ISynchAsynchConnection aConnection = getClientConnection(remote, - data); - if (aConnection == null) { - ConnectException c = new ConnectException("join failed to" - + ":" + remote.getName()); - throw c; - } - Object response; - synchronized (connectLock) { - if (isConnected()) { - killConnection(aConnection); - aConnection = null; - ConnectException c = new ConnectException( - "already connected to " + getGroupID()); - throw c; - } - if (isConnecting()) { - killConnection(aConnection); - aConnection = null; - ConnectException c = new ConnectException( - "currently connecting"); - throw c; - } - connectionState = CONNECTING; - connection = aConnection; - } - synchronized (aConnection) { - try { - Object connectData = getConnectData(remote, data); - response = aConnection.connect(remote, - connectData, getConnectTimeout()); - } catch (IOException e) { - synchronized (connectLock) { - killConnection(aConnection); - if (connection != aConnection) { - aConnection = null; - throw e; - } - connectionState = UNCONNECTED; - connection = null; - remoteServerID = null; - } - throw e; - } - synchronized (connectLock) { - // If not in correct state, disconnect and return - if (connection != aConnection) { - killConnection(aConnection); - aConnection = null; - ConnectException c = new ConnectException( - "join failed because not in correct state"); - throw c; - } - ID serverID = null; - try { - serverID = acceptNewServer(remote, response); - } catch (Exception e) { - killConnection(aConnection); - aConnection = null; - connection = null; - remoteServerID = null; - connectionState = UNCONNECTED; - ConnectException c = new ConnectException( - "join refused locally via acceptNewServer"); - throw c; - } - aConnection.start(); - remoteServerID = serverID; - connectionState = CONNECTED; - } - } - } catch (Exception e) { - SharedObjectContainerJoinException except = new SharedObjectContainerJoinException(e.getClass().getName()+" wrapped: "+e.getMessage()); - except.setStackTrace(e.getStackTrace()); - dumpStack("Exception in joinGroup",e); - throw except; - } - } - - protected int getConnectTimeout() { - return 0; - } - - protected void handleLeaveGroupMessage(ContainerMessage mess) { - ContainerMessage.LeaveGroupMessage lgm = (ContainerMessage.LeaveGroupMessage) mess.getData(); - ID fromID = mess.getFromContainerID(); - if (fromID == null || !fromID.equals(remoteServerID)) { - // we ignore anything not from our server - return; - } - debug("We've been ejected from group "+remoteServerID); - synchronized (getGroupMembershipLock()) { - memberLeave(fromID,connection); - } - // Now notify that we've been ejected - fireContainerEvent(new SharedObjectContainerEjectedEvent(fromID,getID(),lgm.getData())); - } - protected void handleViewChangeMessage(ContainerMessage mess) - throws IOException { - debug("handleViewChangeMessage(" + mess + ")"); - ContainerMessage.ViewChangeMessage vc = (ContainerMessage.ViewChangeMessage) mess - .getData(); - if (vc == null) - throw new IOException("view change message is null"); - ID fromID = mess.getFromContainerID(); - ID toID = mess.getToContainerID(); - if (fromID == null || !fromID.equals(remoteServerID)) { - throw new IOException("view change message from " + fromID - + " is not same as " + remoteServerID); - } - ID[] changeIDs = vc.getChangeIDs(); - if (changeIDs == null) { - // do nothing if we've got no changes - } else { - for (int i = 0; i < changeIDs.length; i++) { - if (vc.isAdd()) { - groupManager.addMember(new Member(changeIDs[i])); - // Notify listeners - fireContainerEvent(new SharedObjectContainerJoinedEvent(getID(),changeIDs[i])); - } else { - if (changeIDs[i].equals(getID())) { - // We've been ejected. - ID serverID = remoteServerID; - synchronized (getGroupMembershipLock()) { - memberLeave(remoteServerID,connection); - } - // Notify listeners that we've been ejected - fireContainerEvent(new SharedObjectContainerEjectedEvent(getID(),serverID,vc.getData())); - } else { - groupManager.removeMember(changeIDs[i]); - // Notify listeners that another remote has gone away - fireContainerEvent(new SharedObjectContainerDepartedEvent(getID(),changeIDs[i])); - } - } - } - } - } - - protected void forwardExcluding(ID from, ID excluding, ContainerMessage data) - throws IOException { - // NOP - } - - protected Serializable getConnectData(ID target, Object data) { - return ContainerMessage.makeJoinGroupMessage(getID(), target, - getNextSequenceNumber(), (Serializable) data); - } - - protected Serializable getLeaveData(ID target) { - return null; - } - - public void leaveGroup() { - debug("leaveGroup"); - ID groupID = getGroupID(); - fireContainerEvent(new SharedObjectContainerLeaveGroupEvent(this.getID(),groupID)); - synchronized (connectLock) { - // If we are currently connected - if (isConnected()) { - synchronized (connection) { - try { - connection.sendSynch(groupID, - getBytesForObject(ContainerMessage - .makeLeaveGroupMessage(getID(), - groupID, - getNextSequenceNumber(), - getLeaveData(groupID)))); - } catch (Exception e) { - } - synchronized (getGroupMembershipLock()) { - memberLeave(groupID, connection); - } - } - } - connectionState = UNCONNECTED; - connection = null; - remoteServerID = null; - } - // notify listeners - fireContainerEvent(new SharedObjectContainerDepartedEvent(this.getID(),groupID)); - } - - protected abstract ISynchAsynchConnection getClientConnection( - ID remoteSpace, Object data) - throws ConnectionInstantiationException; - protected void queueContainerMessage(ContainerMessage message) - throws IOException { - // Do it - connection.sendAsynch(message.getToContainerID(), - getBytesForObject(message)); - } - - protected void forwardExcluding(ID from, ID excluding, byte msg, - Serializable data) throws IOException { /* NOP */ - } - - protected void forwardToRemote(ID from, ID to, ContainerMessage message) - throws IOException { /* NOP */ - } - - protected ID getIDForConnection(IAsynchConnection conn) { - return remoteServerID; - } - - protected void memberLeave(ID fromID, IAsynchConnection conn) { - if (fromID.equals(remoteServerID)) { - groupManager.removeNonLocalMembers(); - super.memberLeave(fromID, conn); - connectionState = UNCONNECTED; - connection = null; - remoteServerID = null; - } else if (fromID.equals(getID())) { - super.memberLeave(fromID, conn); - } - } - - protected void sendMessage(ContainerMessage data) throws IOException { - // Get connect lock, then call super version - synchronized (connectLock) { - checkConnected(); - super.sendMessage(data); - } - } - - protected ID[] sendCreateMsg(ID toID, SharedObjectDescription createInfo) - throws IOException { - // Get connect lock, then call super version - synchronized (connectLock) { - checkConnected(); - return super.sendCreateSharedObjectMessage(toID, createInfo); - } - } - - protected void processDisconnect(DisconnectConnectionEvent evt) { - // Get connect lock, and just return if this connection has been - // terminated - synchronized (connectLock) { - super.processDisconnect(evt); - } - } - - protected void processAsynchPacket(AsynchConnectionEvent evt) - throws IOException { - // Get connect lock, then call super version - synchronized (connectLock) { - checkConnected(); - super.processAsynch(evt); - } - } - - protected Serializable processSynch(SynchConnectionEvent evt) - throws IOException { - synchronized (connectLock) { - checkConnected(); - IConnection conn = evt.getConnection(); - if (connection != conn) - throw new ConnectException("not connected"); - return super.processSynch(evt); - } - } - - protected boolean isConnected() { - return (connectionState == CONNECTED); - } - - protected boolean isConnecting() { - return (connectionState == CONNECTING); - } - - private void checkConnected() throws ConnectException { - if (!isConnected()) - throw new ConnectException("not connected"); - } - - protected ID acceptNewServer(ID orginalTarget, Object serverData) throws Exception { - ContainerMessage aPacket = (ContainerMessage) serverData; - ID fromID = aPacket.getFromContainerID(); - if (fromID == null) - throw new InvalidObjectException("server id is null"); - ID[] ids = ((ContainerMessage.ViewChangeMessage) aPacket.getData()).changeIDs; - if (ids == null) - throw new java.io.InvalidObjectException("id array null"); - for (int i = 0; i < ids.length; i++) { - ID id = ids[i]; - if (id != null && !id.equals(getID())) { - addNewRemoteMember(id, null); - // notify listeners - fireContainerEvent(new SharedObjectContainerJoinedEvent(this.getID(),id)); - } - } - return fromID; - } + ISynchAsynchConnection connection; + + protected ID remoteServerID; + + byte connectionState; + + public static final byte UNCONNECTED = 0; + + public static final byte CONNECTING = 1; + + public static final byte CONNECTED = 2; + + static final class Lock { + } + + Lock connectLock; + + public ClientSOContainer(ISharedObjectContainerConfig config) { + super(config); + connection = null; + connectionState = UNCONNECTED; + connectLock = new Lock(); + } + + public void dispose(long wait) { + synchronized (connectLock) { + isClosing = true; + if (isConnected()) { + this.leaveGroup(); + } else if (isConnecting()) { + killConnection(connection); + } + remoteServerID = null; + } + super.dispose(wait); + } + + public final boolean isGroupServer() { + return false; + } + + public final boolean isGroupManager() { + return false; + } + + public ID getGroupID() { + return remoteServerID; + } + + public void joinGroup(ID remote, Object data) + throws SharedObjectContainerJoinException { + // first notify synchonously + fireContainerEvent(new SharedObjectContainerJoinGroupEvent( + this.getID(), remote, data)); + try { + if (isClosing) + throw new IllegalStateException("container is closing"); + debug("joingroup:" + remote + ":" + data); + ISynchAsynchConnection aConnection = getClientConnection(remote, + data); + if (aConnection == null) { + ConnectException c = new ConnectException("join failed to" + + ":" + remote.getName()); + throw c; + } + Object response; + synchronized (connectLock) { + if (isConnected()) { + killConnection(aConnection); + aConnection = null; + ConnectException c = new ConnectException( + "already connected to " + getGroupID()); + throw c; + } + if (isConnecting()) { + killConnection(aConnection); + aConnection = null; + ConnectException c = new ConnectException( + "currently connecting"); + throw c; + } + connectionState = CONNECTING; + connection = aConnection; + } + synchronized (aConnection) { + try { + Object connectData = getConnectData(remote, data); + response = aConnection.connect(remote, connectData, + getConnectTimeout()); + } catch (IOException e) { + synchronized (connectLock) { + killConnection(aConnection); + if (connection != aConnection) { + aConnection = null; + throw e; + } + connectionState = UNCONNECTED; + connection = null; + remoteServerID = null; + } + throw e; + } + synchronized (connectLock) { + // If not in correct state, disconnect and return + if (connection != aConnection) { + killConnection(aConnection); + aConnection = null; + ConnectException c = new ConnectException( + "join failed because not in correct state"); + throw c; + } + ID serverID = null; + try { + serverID = acceptNewServer(remote, response); + } catch (Exception e) { + killConnection(aConnection); + aConnection = null; + connection = null; + remoteServerID = null; + connectionState = UNCONNECTED; + ConnectException c = new ConnectException( + "join refused locally via acceptNewServer"); + throw c; + } + aConnection.start(); + remoteServerID = serverID; + connectionState = CONNECTED; + } + } + } catch (Exception e) { + dumpStack("Exception in joinGroup", e); + SharedObjectContainerJoinException except = new SharedObjectContainerJoinException( + "joinGroup exception in container " + getID() + " joining " + + remote + ": " + e.getClass().getName() + ": " + + e.getMessage()); + + except.setStackTrace(e.getStackTrace()); + throw except; + } + } + + protected int getConnectTimeout() { + return 0; + } + + protected void handleLeaveGroupMessage(ContainerMessage mess) { + ContainerMessage.LeaveGroupMessage lgm = (ContainerMessage.LeaveGroupMessage) mess + .getData(); + ID fromID = mess.getFromContainerID(); + if (fromID == null || !fromID.equals(remoteServerID)) { + // we ignore anything not from our server + return; + } + debug("We've been ejected from group " + remoteServerID); + synchronized (getGroupMembershipLock()) { + memberLeave(fromID, connection); + } + // Now notify that we've been ejected + fireContainerEvent(new SharedObjectContainerEjectedEvent(fromID, + getID(), lgm.getData())); + } + + protected void handleViewChangeMessage(ContainerMessage mess) + throws IOException { + debug("handleViewChangeMessage(" + mess + ")"); + ContainerMessage.ViewChangeMessage vc = (ContainerMessage.ViewChangeMessage) mess + .getData(); + if (vc == null) + throw new IOException("view change message is null"); + ID fromID = mess.getFromContainerID(); + ID toID = mess.getToContainerID(); + if (fromID == null || !fromID.equals(remoteServerID)) { + throw new IOException("view change message from " + fromID + + " is not same as " + remoteServerID); + } + ID[] changeIDs = vc.getChangeIDs(); + if (changeIDs == null) { + // do nothing if we've got no changes + } else { + for (int i = 0; i < changeIDs.length; i++) { + if (vc.isAdd()) { + groupManager.addMember(new Member(changeIDs[i])); + // Notify listeners + fireContainerEvent(new SharedObjectContainerJoinedEvent( + getID(), changeIDs[i])); + } else { + if (changeIDs[i].equals(getID())) { + // We've been ejected. + ID serverID = remoteServerID; + synchronized (getGroupMembershipLock()) { + memberLeave(remoteServerID, connection); + } + // Notify listeners that we've been ejected + fireContainerEvent(new SharedObjectContainerEjectedEvent( + getID(), serverID, vc.getData())); + } else { + groupManager.removeMember(changeIDs[i]); + // Notify listeners that another remote has gone away + fireContainerEvent(new SharedObjectContainerDepartedEvent( + getID(), changeIDs[i])); + } + } + } + } + } + + protected void forwardExcluding(ID from, ID excluding, ContainerMessage data) + throws IOException { + // NOP + } + + protected Serializable getConnectData(ID target, Object data) { + return ContainerMessage.makeJoinGroupMessage(getID(), target, + getNextSequenceNumber(), (Serializable) data); + } + + protected Serializable getLeaveData(ID target) { + return null; + } + + public void leaveGroup() { + debug("leaveGroup"); + ID groupID = getGroupID(); + fireContainerEvent(new SharedObjectContainerLeaveGroupEvent(this + .getID(), groupID)); + synchronized (connectLock) { + // If we are currently connected + if (isConnected()) { + synchronized (connection) { + try { + connection.sendSynch(groupID, + getBytesForObject(ContainerMessage + .makeLeaveGroupMessage(getID(), + groupID, + getNextSequenceNumber(), + getLeaveData(groupID)))); + } catch (Exception e) { + } + synchronized (getGroupMembershipLock()) { + memberLeave(groupID, connection); + } + } + } + connectionState = UNCONNECTED; + connection = null; + remoteServerID = null; + } + // notify listeners + fireContainerEvent(new SharedObjectContainerDepartedEvent(this.getID(), + groupID)); + } + + protected abstract ISynchAsynchConnection getClientConnection( + ID remoteSpace, Object data) + throws ConnectionInstantiationException; + + protected void queueContainerMessage(ContainerMessage message) + throws IOException { + // Do it + connection.sendAsynch(message.getToContainerID(), + getBytesForObject(message)); + } + + protected void forwardExcluding(ID from, ID excluding, byte msg, + Serializable data) throws IOException { /* NOP */ + } + + protected void forwardToRemote(ID from, ID to, ContainerMessage message) + throws IOException { /* NOP */ + } + + protected ID getIDForConnection(IAsynchConnection conn) { + return remoteServerID; + } + + protected void memberLeave(ID fromID, IAsynchConnection conn) { + if (fromID.equals(remoteServerID)) { + groupManager.removeNonLocalMembers(); + super.memberLeave(fromID, conn); + connectionState = UNCONNECTED; + connection = null; + remoteServerID = null; + } else if (fromID.equals(getID())) { + super.memberLeave(fromID, conn); + } + } + + protected void sendMessage(ContainerMessage data) throws IOException { + // Get connect lock, then call super version + synchronized (connectLock) { + checkConnected(); + super.sendMessage(data); + } + } + + protected ID[] sendCreateMsg(ID toID, SharedObjectDescription createInfo) + throws IOException { + // Get connect lock, then call super version + synchronized (connectLock) { + checkConnected(); + return super.sendCreateSharedObjectMessage(toID, createInfo); + } + } + + protected void processDisconnect(DisconnectConnectionEvent evt) { + // Get connect lock, and just return if this connection has been + // terminated + synchronized (connectLock) { + super.processDisconnect(evt); + } + } + + protected void processAsynchPacket(AsynchConnectionEvent evt) + throws IOException { + // Get connect lock, then call super version + synchronized (connectLock) { + checkConnected(); + super.processAsynch(evt); + } + } + + protected Serializable processSynch(SynchConnectionEvent evt) + throws IOException { + synchronized (connectLock) { + checkConnected(); + IConnection conn = evt.getConnection(); + if (connection != conn) + throw new ConnectException("not connected"); + return super.processSynch(evt); + } + } + + protected boolean isConnected() { + return (connectionState == CONNECTED); + } + + protected boolean isConnecting() { + return (connectionState == CONNECTING); + } + + private void checkConnected() throws ConnectException { + if (!isConnected()) + throw new ConnectException("not connected"); + } + + protected ID acceptNewServer(ID orginalTarget, Object serverData) + throws Exception { + ContainerMessage aPacket = (ContainerMessage) serverData; + ID fromID = aPacket.getFromContainerID(); + if (fromID == null) + throw new InvalidObjectException("server id is null"); + ID[] ids = ((ContainerMessage.ViewChangeMessage) aPacket.getData()).changeIDs; + if (ids == null) + throw new java.io.InvalidObjectException("id array null"); + for (int i = 0; i < ids.length; i++) { + ID id = ids[i]; + if (id != null && !id.equals(getID())) { + addNewRemoteMember(id, null); + // notify listeners + fireContainerEvent(new SharedObjectContainerJoinedEvent(this + .getID(), id)); + } + } + return fromID; + } }
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf.provider/src/org/eclipse/ecf/provider/generic/SOContainer.java b/framework/bundles/org.eclipse.ecf.provider/src/org/eclipse/ecf/provider/generic/SOContainer.java index 91df01c63..47620db92 100644 --- a/framework/bundles/org.eclipse.ecf.provider/src/org/eclipse/ecf/provider/generic/SOContainer.java +++ b/framework/bundles/org.eclipse.ecf.provider/src/org/eclipse/ecf/provider/generic/SOContainer.java @@ -47,1017 +47,1063 @@ import org.eclipse.ecf.provider.Trace; import org.eclipse.ecf.provider.generic.gmm.Member; public abstract class SOContainer implements ISharedObjectContainer { - class LoadingSharedObject implements ISharedObject { - Object credentials; - SharedObjectDescription description; - Thread runner = null; - ID fromID = null; - - LoadingSharedObject(ID fromID, SharedObjectDescription sd, Object credentials) { - this.fromID = fromID; - this.description = sd; - this.credentials = credentials; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.ecf.core.ISharedObject#dispose(org.eclipse.ecf.core.identity.ID) - */ - public void dispose(ID containerID) { - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.ecf.core.ISharedObject#getAdapter(java.lang.Class) - */ - public Object getAdapter(Class clazz) { - return null; - } - - ID getHomeID() { - return description.getHomeID(); - } - - ID getID() { - return description.getID(); - } - - Thread getThread() { - return new Thread(loadingThreadGroup, new Runnable() { - public void run() { - try { - if (Thread.currentThread().isInterrupted() - || isClosing()) - throw new InterruptedException( - "Loading interrupted for object " - + getID().getName()); - // First load object - ISharedObject obj = load(description); - // Create wrapper object and move from loading to active - // list. - SOWrapper wrap = makeNewRemoteSharedObjectWrapper(fromID,description,obj); - // Get config info for new object - SOConfig aConfig = wrap.getConfig(); - // Call init method on new object. - obj.init(aConfig); - // Check to make sure thread has not been - // interrupted...if it has, throw - if (Thread.currentThread().isInterrupted() - || isClosing()) - throw new InterruptedException( - "Loading interrupted for object " - + getID().getName()); - // Finally, we move from loading to active, and then the object is done - SOContainer.this.moveFromLoadingToActive(wrap); - } catch (Exception e) { - dumpStack("Exception loading object ", e); - SOContainer.this.removeFromLoading(getID()); - try { - sendCreateResponse(getHomeID(), getID(), e, - description.getIdentifier()); - } catch (Exception e1) { - dumpStack("Exception sending create response from LoadingSharedObject.run", e1); - } - } - } - }, getID().getName() + ":load"); - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.ecf.core.ISharedObject#handleEvent(org.eclipse.ecf.core.util.Event) - */ - public void handleEvent(Event event) { - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.ecf.core.ISharedObject#handleEvents(org.eclipse.ecf.core.util.Event[]) - */ - public void handleEvents(Event[] events) { - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.ecf.core.ISharedObject#init(org.eclipse.ecf.core.ISharedObjectConfig) - */ - public void init(ISharedObjectConfig initData) - throws SharedObjectInitException { - } - - void start() { - if (runner == null) { - runner = (Thread) AccessController - .doPrivileged(new PrivilegedAction() { - public Object run() { - return getThread(); - } - }); - runner.setDaemon(true); - runner.start(); - } - } - } - - class MessageReceiver implements ISynchAsynchConnectionEventHandler { - /* - * (non-Javadoc) - * - * @see org.eclipse.ecf.internal.comm.IConnectionEventHandler#getAdapter(java.lang.Class) - */ - public Object getAdapter(Class clazz) { - return null; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.ecf.internal.comm.IAsynchConnectionEventHandler#handleAsynchEvent(org.eclipse.ecf.internal.comm.AsynchConnectionEvent) - */ - public void handleAsynchEvent(AsynchConnectionEvent event) - throws IOException { - processAsynch(event); - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.ecf.internal.comm.IConnectionEventHandler#handleDisconnectEvent(org.eclipse.ecf.internal.comm.ConnectionEvent) - */ - public void handleDisconnectEvent(DisconnectConnectionEvent event) { - processDisconnect(event); - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.ecf.internal.comm.IConnectionEventHandler#handleSuspectEvent(org.eclipse.ecf.internal.comm.ConnectionEvent) - */ - public boolean handleSuspectEvent(ConnectionEvent event) { - return false; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.ecf.internal.comm.ISynchConnectionEventHandler#handleSynchEvent(org.eclipse.ecf.internal.comm.SynchConnectionEvent) - */ - public Object handleSynchEvent(SynchConnectionEvent event) - throws IOException { - return processSynch(event); - } - } - - static Trace debug = Trace.create("container"); - public static final String DEFAULT_OBJECT_ARG_KEY = SOContainer.class - .getName() - + ".sharedobjectargs"; - public static final String DEFAULT_OBJECT_ARGTYPES_KEY = SOContainer.class - .getName() - + ".sharedobjectargs"; - protected ISharedObjectContainerConfig config = null; - protected SOContainerGMM groupManager = null; - protected boolean isClosing = false; - private Vector listeners = null; - protected ThreadGroup loadingThreadGroup = null; - protected MessageReceiver receiver; - private long sequenceNumber = 0L; - protected SOManager sharedObjectManager = null; - protected ThreadGroup sharedObjectThreadGroup = null; - - public SOContainer(ISharedObjectContainerConfig config) { - if (config == null) - throw new InstantiationError("config must not be null"); - this.config = config; - groupManager = new SOContainerGMM(this, new Member(config.getID())); - sharedObjectManager = new SOManager(this); - loadingThreadGroup = makeLoadingThreadGroup(); - sharedObjectThreadGroup = getSharedObjectThreadGroup(); - listeners = new Vector(); - receiver = new MessageReceiver(); - debug("<init>"); - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.ecf.core.ISharedObjectContainer#addListener(org.eclipse.ecf.core.ISharedObjectContainerListener, - * java.lang.String) - */ - public void addListener(ISharedObjectContainerListener l, String filter) { - synchronized (listeners) { - listeners.add(new ContainerListener(l, filter)); - } - } - - protected boolean addNewRemoteMember(ID memberID, Object data) { - debug("addNewRemoteMember:" + memberID); - return groupManager.addMember(new Member(memberID, data)); - } - - protected ISharedObject addSharedObject0(SharedObjectDescription sd, - ISharedObject s) throws Exception { - addSharedObjectWrapper(makeNewSharedObjectWrapper(sd, s)); - return s; - } - - protected void addSharedObjectAndWait(SharedObjectDescription sd, - ISharedObject s, ISharedObjectContainerTransaction t) - throws Exception { - if (sd.getID() == null || s == null) { - throw new SharedObjectAddException("Object id is null, or instance is null"); - } - ISharedObject so = addSharedObject0(sd, s); - // Wait right here until committed - if (t != null) - t.waitToCommit(); - } - - protected void addSharedObjectWrapper(SOWrapper wrapper) throws Exception { - if (wrapper == null) - return; - ID id = wrapper.getObjID(); - synchronized (getGroupMembershipLock()) { - Object obj = groupManager.getFromAny(id); - if (obj != null) { - throw new SharedObjectAddException("SharedObject with id " - + id.getName() + " already in container"); - } - // Call initialize. If this throws it halts everything - wrapper.init(); - // Put in table - groupManager.addSharedObjectToActive(wrapper); - } - } - - protected boolean addToLoading(LoadingSharedObject lso) { - return groupManager.addLoadingSharedObject(lso); - } - - /** - * Check remote creation of shared objects. This method is called by the remote shared object - * creation message handler, to verify that the shared object from container 'fromID' to - * container 'toID' with description 'desc' is to be allowed to be created within the current - * container. If this method throws, a failure (and exception will be sent back to caller - * If this method returns null, the create message is ignored. If this method returns a - * non-null object, the creation is allowed to proceed. The default implementation is to return - * a non-null object - * - * @param fromID the ID of the container sending us this create request - * @param toID the ID (or null) of the container intended to receive this request - * @param seq the sequence number associated with the container message - * @param desc the SharedObjectDescription that describes the shared object to be created - * - * @returns Object null if the create message is to be ignored, non-null if the creation - * should continue - * - * @throws Exception may throw any Exception to communicate back (via sendCreateResponse) to - * the sender that the creation has failed - */ - protected Object checkRemoteCreate(ID fromID, ID toID, long seq, - SharedObjectDescription desc) throws Exception { - debug("checkRemoteCreate(" + fromID + "," + toID + "," + seq + "," + desc - + ")"); - return desc; - } - - protected void debug(String msg) { - if (Trace.ON && debug != null) { - debug.msg(msg + ":" + config.getID()); - } - } - - protected boolean destroySharedObject(ID sharedObjectID) { - return groupManager.removeSharedObject(sharedObjectID); - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.ecf.core.ISharedObjectContainer#dispose(long) - */ - public void dispose(long waittime) { - debug("dispose(" + waittime + ")"); - isClosing = true; - // notify listeners - fireContainerEvent(new SharedObjectContainerDisposeEvent(getID())); - // Clear group manager - if (groupManager != null) { - groupManager.removeAllMembers(); - groupManager = null; - } - // Clear shared object manager - if (sharedObjectManager != null) { - sharedObjectManager.dispose(); - sharedObjectManager = null; - } - if (sharedObjectThreadGroup != null) { - sharedObjectThreadGroup.interrupt(); - sharedObjectThreadGroup = null; - } - if (loadingThreadGroup != null) { - loadingThreadGroup.interrupt(); - loadingThreadGroup = null; - } - if (listeners != null) { - listeners.clear(); - listeners = null; - } - } - - protected void dumpStack(String msg, Throwable e) { - if (Trace.ON && debug != null) { - debug.dumpStack(e, msg + ":" + config.getID()); - } - } - - protected void fireContainerEvent(IContainerEvent event) { - synchronized (listeners) { - for (Iterator i = listeners.iterator(); i.hasNext();) { - ContainerListener l = (ContainerListener) i.next(); - l.handleEvent(event); - } - } - } - - protected final void forward(ID fromID, ID toID, ContainerMessage data) - throws IOException { - if (toID == null) { - forwardExcluding(fromID, fromID, data); - } else { - forwardToRemote(fromID, toID, data); - } - } - - abstract protected void forwardExcluding(ID from, ID excluding, - ContainerMessage data) throws IOException; - - abstract protected void forwardToRemote(ID from, ID to, - ContainerMessage data) throws IOException; - - /* - * (non-Javadoc) - * - * @see org.eclipse.ecf.core.ISharedObjectContainer#getAdapter(java.lang.Class) - */ - public Object getAdapter(Class adapter) { - return null; - } - - /** - * @param sd - * @return Object [] - */ - public Object[] getArgsFromProperties(SharedObjectDescription sd) { - if (sd == null) - return null; - Map aMap = sd.getProperties(); - if (aMap == null) - return null; - Object obj = aMap.get(DEFAULT_OBJECT_ARG_KEY); - if (obj == null) - return null; - if (obj instanceof Object[]) { - Object[] ret = (Object[]) obj; - aMap.remove(DEFAULT_OBJECT_ARG_KEY); - return ret; - } else - return null; - } - - /** - * @param sd - * @return String [] - */ - public String[] getArgTypesFromProperties(SharedObjectDescription sd) { - if (sd == null) - return null; - Map aMap = sd.getProperties(); - if (aMap == null) - return null; - Object obj = aMap.get(DEFAULT_OBJECT_ARGTYPES_KEY); - if (obj == null) - return null; - if (obj instanceof String[]) { - String[] ret = (String[]) obj; - aMap.remove(DEFAULT_OBJECT_ARGTYPES_KEY); - return ret; - } else - return null; - } - - protected byte[] getBytesForObject(Serializable obj) throws IOException { - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - ObjectOutputStream oos = new ObjectOutputStream(bos); - oos.writeObject(obj); - return bos.toByteArray(); - } - - protected ClassLoader getClassLoaderForContainer() { - return this.getClass().getClassLoader(); - } - - /** - * @param sd - * @return ClassLoader - */ - protected ClassLoader getClassLoaderForSharedObject( - SharedObjectDescription sd) { - if (sd != null) { - ClassLoader cl = sd.getClassLoader(); - if (cl != null) - return cl; - else - return getClassLoaderForContainer(); - } else - return getClassLoaderForContainer(); - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.ecf.core.ISharedObjectContainer#getConfig() - */ - public ISharedObjectContainerConfig getConfig() { - return config; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.ecf.core.ISharedObjectContainer#getGroupID() - */ - public abstract ID getGroupID(); - - /* - * (non-Javadoc) - * - * @see org.eclipse.ecf.core.ISharedObjectContainer#getGroupMemberIDs() - */ - public ID[] getGroupMemberIDs() { - return groupManager.getMemberIDs(); - } - - protected Object getGroupMembershipLock() { - return groupManager; - } - - public ID getID() { - return config.getID(); - } - - protected int getMaxGroupMembers() { - return groupManager.getMaxMembers(); - } - - protected Thread getNewSharedObjectThread(ID sharedObjectID, - Runnable runnable) { - return new Thread(sharedObjectThreadGroup, runnable, sharedObjectID - .getName() - + ":run"); - } - - protected long getNextSequenceNumber() { - if (sequenceNumber == Long.MAX_VALUE) { - sequenceNumber = 0; - return sequenceNumber; - } else - return sequenceNumber++; - } - - protected ContainerMessage getObjectFromBytes(byte[] bytes) - throws IOException { - ByteArrayInputStream bis = new ByteArrayInputStream(bytes); - ObjectInputStream ois = new ObjectInputStream(bis); - Object obj = null; - try { - obj = ois.readObject(); - } catch (ClassNotFoundException e) { - dumpStack("class not found for message", e); - return null; - } - if (obj instanceof ContainerMessage) { - return (ContainerMessage) obj; - } else { - debug("message received is not containermessage:" + obj); - return null; - } - } - - protected IOSGIService getOSGIServiceInterface() { - return null; - } - - public ID[] getOtherMemberIDs() { - return groupManager.getOtherMemberIDs(); - } - - protected ISynchAsynchConnectionEventHandler getReceiver() { - return receiver; - } - - protected ISharedObject getSharedObject(ID id) { - SOWrapper wrap = getSharedObjectWrapper(id); - if (wrap == null) - return null; - else - return wrap.getSharedObject(); - } - - protected ID[] getSharedObjectIDs() { - return groupManager.getSharedObjectIDs(); - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.ecf.core.ISharedObjectContainer#getSharedObjectManager() - */ - public ISharedObjectManager getSharedObjectManager() { - return sharedObjectManager; - } - - protected ThreadGroup getSharedObjectThreadGroup() { - return new ThreadGroup(getID() + ":SOs"); - } - - protected SOWrapper getSharedObjectWrapper(ID id) { - return groupManager.getFromActive(id); - } - - protected void handleAsynchIOException(IOException except, - AsynchConnectionEvent e) { - // If we get IO Exception, we'll disconnect...if we can - killConnection(e.getConnection()); - } - - protected void handleCreateMessage(ContainerMessage mess) - throws IOException { - debug("handleCreateMessage:" + mess); - ContainerMessage.CreateMessage create = (ContainerMessage.CreateMessage) mess - .getData(); - SharedObjectDescription desc = (SharedObjectDescription) create - .getData(); - ID fromID = mess.getFromContainerID(); - ID toID = mess.getToContainerID(); - long seq = mess.getSequence(); - Object checkCreateResult = null; - ID sharedObjectID = desc.getID(); - // Check to make sure that the remote creation is allowed. - // If this method throws, a failure (and exception will be sent back to caller - // If this method returns null, the create message is ignored. If this method - // returns a non-null object, the creation is allowed to proceed - try { - checkCreateResult = checkRemoteCreate(fromID, toID, seq, desc); - } catch (Exception e) { - SharedObjectAddException addException = new SharedObjectAddException("shared object " - + sharedObjectID + " rejected by container "+getID(),e); - dumpStack("Exception in checkRemoteCreate",addException); - try { - sendCreateResponse(fromID, sharedObjectID,addException, desc.getIdentifier()); - } catch (IOException except) { - logException("Exception from sendCreateResponse in handleCreateResponse", except); - } - return; - } - // Then if result from check is non-null, we continue. If null, we ignore - if (checkCreateResult != null) { - LoadingSharedObject lso = new LoadingSharedObject(fromID,desc, checkCreateResult); - synchronized (getGroupMembershipLock()) { - if (!addToLoading(lso)) { - try { - sendCreateResponse(fromID, sharedObjectID, - new SharedObjectAddException("shared object " - + sharedObjectID + " already exists in container "+getID()), desc.getIdentifier()); - } catch (IOException e) { - logException("Exception in handleCreateMessage.sendCreateResponse", e); - } - } - forward(fromID, toID, mess); - return; - } - } - synchronized (getGroupMembershipLock()) { - forward(fromID, toID, mess); - } - } - - protected void handleCreateResponseMessage(ContainerMessage mess) - throws IOException { - debug("handleCreateResponseMessage:" + mess); - ID fromID = mess.getFromContainerID(); - ID toID = mess.getToContainerID(); - long seq = mess.getSequence(); - ContainerMessage.CreateResponseMessage resp = (ContainerMessage.CreateResponseMessage) mess - .getData(); - if (toID != null && toID.equals(getID())) { - ID sharedObjectID = resp.getSharedObjectID(); - SOWrapper sow = getSharedObjectWrapper(sharedObjectID); - if (sow != null) { - sow.deliverCreateResponse(fromID, resp); - } else { - log("handleCreateResponseMessage...wrapper now found for " - + sharedObjectID); - } - } else { - forwardToRemote(fromID, toID, mess); - } - } - - /** - * @param mess - */ - protected abstract void handleLeaveGroupMessage(ContainerMessage mess); - - protected void handleSharedObjectDisposeMessage(ContainerMessage mess) - throws IOException { - debug("handleSharedObjectDisposeMessage:" + mess); - ID fromID = mess.getFromContainerID(); - ID toID = mess.getToContainerID(); - long seq = mess.getSequence(); - ContainerMessage.SharedObjectDisposeMessage resp = (ContainerMessage.SharedObjectDisposeMessage) mess - .getData(); - ID sharedObjectID = resp.getSharedObjectID(); - synchronized (getGroupMembershipLock()) { - if (groupManager.isLoading(sharedObjectID)) { - groupManager.removeSharedObjectFromLoading(sharedObjectID); - } else { - groupManager.removeSharedObject(sharedObjectID); - } - forward(fromID, toID, mess); - } - } - - protected void handleSharedObjectMessage(ContainerMessage mess) - throws IOException { - debug("handleSharedObjectMessage:" + mess); - ID fromID = mess.getFromContainerID(); - ID toID = mess.getToContainerID(); - long seq = mess.getSequence(); - ContainerMessage.SharedObjectMessage resp = (ContainerMessage.SharedObjectMessage) mess - .getData(); - synchronized (getGroupMembershipLock()) { - if (toID == null || toID.equals(getID())) { - SOWrapper sow = getSharedObjectWrapper(resp - .getFromSharedObjectID()); - if (sow != null) { - sow.deliverSharedObjectMessage(fromID, resp.getData()); - } - } - forward(fromID, toID, mess); - } - } - - protected void handleUnidentifiedMessage(ContainerMessage mess) - throws IOException { - // do nothing - } - - protected abstract void handleViewChangeMessage(ContainerMessage mess) - throws IOException; - - protected boolean isClosing() { - return isClosing; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.ecf.core.ISharedObjectContainer#isGroupManager() - */ - public abstract boolean isGroupManager(); - - /* - * (non-Javadoc) - * - * @see org.eclipse.ecf.core.ISharedObjectContainer#isGroupServer() - */ - public abstract boolean isGroupServer(); - - /* - * (non-Javadoc) - * - * @see org.eclipse.ecf.core.ISharedObjectContainer#joinGroup(org.eclipse.ecf.core.identity.ID, - * java.lang.Object) - */ - public abstract void joinGroup(ID groupID, Object loginData) - throws SharedObjectContainerJoinException; - - protected void killConnection(IConnection conn) { - debug("killconnection"); - try { - if (conn != null) - conn.disconnect(); - } catch (IOException e) { - logException("Exception in killConnection", e); - } - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.ecf.core.ISharedObjectContainer#leaveGroup() - */ - public abstract void leaveGroup(); - - protected ISharedObject load(SharedObjectDescription sd) throws Exception { - return sharedObjectManager.loadSharedObject(sd); - } - - protected void log(String msg) { - debug(msg); - } - - protected void logException(String msg, Throwable e) { - dumpStack(msg, e); - } - - protected ThreadGroup makeLoadingThreadGroup() { - return new ThreadGroup(getID() + ":load"); - } - - protected SOConfig makeNewSharedObjectConfig(SharedObjectDescription sd, - ISharedObject obj) { - ID homeID = sd.getHomeID(); - if (homeID == null) - homeID = getID(); - return new SOConfig(sd.getID(), homeID, this, sd.getProperties()); - } - - protected SOConfig makeNewRemoteSharedObjectConfig(ID fromID, SharedObjectDescription sd, - ISharedObject obj) { - ID homeID = sd.getHomeID(); - if (homeID == null) - homeID = fromID; - return new SOConfig(sd.getID(), homeID, this, sd.getProperties()); - } - - protected SOContext makeNewSharedObjectContext(SOConfig config, - QueueEnqueue queue) { - return new SOContext(config.getSharedObjectID(), config - .getHomeContainerID(), this, config.getProperties(), queue); - } - protected SOContext makeNewRemoteSharedObjectContext(SOConfig config, - QueueEnqueue queue) { - return new SOContext(config.getSharedObjectID(), config - .getHomeContainerID(), this, config.getProperties(), queue); - } - - protected SOWrapper makeNewSharedObjectWrapper(SharedObjectDescription sd, - ISharedObject s) { - SOConfig newConfig = makeNewSharedObjectConfig(sd, s); - return new SOWrapper(newConfig, s, this); - } - protected SOWrapper makeNewRemoteSharedObjectWrapper(ID fromID, SharedObjectDescription sd, - ISharedObject s) { - SOConfig newConfig = makeNewRemoteSharedObjectConfig(fromID, sd, s); - return new SOWrapper(newConfig, s, this); - } - - protected void memberLeave(ID target, IConnection conn) { - debug("memberLeave:" + target + ":" + conn); - if (target == null) - return; - if (groupManager.removeMember(target)) { - try { - forwardExcluding(getID(), target, ContainerMessage - .makeViewChangeMessage(getID(), null, - getNextSequenceNumber(), new ID[] { target }, - false, null)); - } catch (IOException e) { - logException("Exception in memberLeave.forwardExcluding", e); - } - } - if (conn != null) - killConnection(conn); - } - - protected void moveFromLoadingToActive(SOWrapper wrap) { - groupManager.moveSharedObjectFromLoadingToActive(wrap); - } - - protected void notifySharedObjectActivated(ID sharedObjectID) { - groupManager.notifyOthersActivated(sharedObjectID); - } - - protected void notifySharedObjectDeactivated(ID sharedObjectID) { - groupManager.notifyOthersDeactivated(sharedObjectID); - } - protected ContainerMessage validateContainerMessage(Object mess) { - // Message must not be null - if (mess == null) { - debug("Ignoring null ContainerMessage"); - return null; - } - if (mess instanceof ContainerMessage) { - ContainerMessage contmess = (ContainerMessage) mess; - ID fromID = contmess.getFromContainerID(); - if (fromID == null) { - debug("Ignoring ContainerMessage from null sender...ignoring"); - return null; - } - ID toID = contmess.getToContainerID(); - if (toID == null) { - return contmess; - } else { - if (toID.equals(getID())) { - return contmess; - } else { - debug("Ignoring ContainerMessage from "+fromID+" to "+toID); - return null; - } - } - // OK - } else { - debug("Ignoring invalid ContainerMessage:"+mess); - return null; - } - - } - protected void processAsynch(AsynchConnectionEvent e) { - try { - Object obj = e.getData(); - if (obj == null) { - debug("Ignoring null data in event "+e); - return; - } - if (!(obj instanceof byte [])) { - debug("Ignoring event without valid data "+e); - } - ContainerMessage mess = validateContainerMessage(getObjectFromBytes((byte[]) obj)); - if (mess == null) { - return; - } - Serializable submess = mess.getData(); - if (submess != null) { - if (submess instanceof ContainerMessage.CreateMessage) { - handleCreateMessage(mess); - } else if (submess instanceof ContainerMessage.CreateResponseMessage) { - handleCreateResponseMessage(mess); - } else if (submess instanceof ContainerMessage.SharedObjectDisposeMessage) { - handleSharedObjectDisposeMessage(mess); - } else if (submess instanceof ContainerMessage.SharedObjectMessage) { - handleSharedObjectMessage(mess); - } else if (submess instanceof ContainerMessage.ViewChangeMessage) { - handleViewChangeMessage(mess); - } else { - handleUnidentifiedMessage(mess); - } - } else { - handleUnidentifiedMessage(mess); - } - } catch (IOException except) { - handleAsynchIOException(except, e); - } - } - - protected void processDisconnect(DisconnectConnectionEvent e) { - debug("processDisconnect:" + e); - try { - ContainerMessage mess = getObjectFromBytes((byte[]) e.getData()); - } catch (Exception except) { - logException("Exception in processDisconnect ", except); - } - } - - protected Serializable processSynch(SynchConnectionEvent e) - throws IOException { - debug("processSynch:" + e); - ContainerMessage mess = getObjectFromBytes((byte[]) e.getData()); - Serializable data = mess.getData(); - // Must be non null - if (data != null && data instanceof ContainerMessage.LeaveGroupMessage) { - handleLeaveGroupMessage(mess); - } - return null; - } - - abstract protected void queueContainerMessage(ContainerMessage mess) - throws IOException; - - protected void removeFromLoading(ID id) { - groupManager.removeSharedObjectFromLoading(id); - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.ecf.core.ISharedObjectContainer#removeListener(org.eclipse.ecf.core.ISharedObjectContainerListener) - */ - public void removeListener(ISharedObjectContainerListener l) { - synchronized (listeners) { - for (Enumeration e = listeners.elements(); e.hasMoreElements();) { - ContainerListener list = (ContainerListener) e.nextElement(); - if (list.isListener(l)) { - // found it...so remove - listeners.remove(list); - } - } - } - } - - protected boolean removeRemoteMember(ID remoteMember) { - return groupManager.removeMember(remoteMember); - } - - protected ISharedObject removeSharedObject(ID id) { - synchronized (getGroupMembershipLock()) { - SOWrapper wrap = groupManager.getFromActive(id); - if (wrap == null) - return null; - groupManager.removeSharedObject(id); - return wrap.getSharedObject(); - } - } - - protected void sendCreate(ID sharedObjectID, ID toContainerID, - SharedObjectDescription sd) throws IOException { - sendCreateSharedObjectMessage(toContainerID, sd); - } - - protected void sendCreateResponse(ID homeID, ID sharedObjectID, - Throwable t, long identifier) throws IOException { - sendCreateResponseSharedObjectMessage(homeID, sharedObjectID, t, - identifier); - } - - protected void sendCreateResponseSharedObjectMessage(ID toContainerID, - ID fromSharedObject, Throwable t, long ident) throws IOException { - sendMessage(ContainerMessage.makeSharedObjectCreateResponseMessage( - getID(), toContainerID, getNextSequenceNumber(), - fromSharedObject, t, ident)); - } - - protected ID[] sendCreateSharedObjectMessage(ID toContainerID, - SharedObjectDescription sd) throws IOException { - ID[] returnIDs = null; - if (toContainerID == null) { - synchronized (getGroupMembershipLock()) { - // Send message to all - sendMessage(ContainerMessage.makeSharedObjectCreateMessage( - getID(), toContainerID, getNextSequenceNumber(), sd)); - returnIDs = getOtherMemberIDs(); - } - } else { - // If the create msg is directed to this space, no msg will be sent - if (getID().equals(toContainerID)) { - returnIDs = new ID[0]; - } else { - sendMessage(ContainerMessage.makeSharedObjectCreateMessage( - getID(), toContainerID, getNextSequenceNumber(), sd)); - returnIDs = new ID[1]; - returnIDs[0] = toContainerID; - } - } - return returnIDs; - } - - protected void sendDispose(ID toContainerID, ID sharedObjectID) - throws IOException { - sendDisposeSharedObjectMessage(toContainerID, sharedObjectID); - } - - protected void sendDisposeSharedObjectMessage(ID toContainerID, - ID fromSharedObject) throws IOException { - sendMessage(ContainerMessage.makeSharedObjectDisposeMessage(getID(), - toContainerID, getNextSequenceNumber(), fromSharedObject)); - } - - protected void sendMessage(ContainerMessage data) throws IOException { - synchronized (getGroupMembershipLock()) { - ID ourID = getID(); - // We don't send to ourselves - if (!ourID.equals(data.getToContainerID())) { - debug("sendcontainermessage:" + data); - queueContainerMessage(data); - } - } - } - - protected void sendMessage(ID toContainerID, ID sharedObjectID, - Object message) throws IOException { - if (message == null) - return; - sendSharedObjectMessage(toContainerID, sharedObjectID, - (Serializable) message); - } - - protected void sendSharedObjectMessage(ID toContainerID, - ID fromSharedObject, Serializable data) throws IOException { - sendMessage(ContainerMessage.makeSharedObjectMessage(getID(), - toContainerID, getNextSequenceNumber(), fromSharedObject, data)); - } - - protected void setIsClosing() { - isClosing = true; - } - - protected void setMaxGroupMembers(int max) { - groupManager.setMaxMembers(max); - } + class LoadingSharedObject implements ISharedObject { + Object credentials; + + SharedObjectDescription description; + + Thread runner = null; + + ID fromID = null; + + LoadingSharedObject(ID fromID, SharedObjectDescription sd, + Object credentials) { + this.fromID = fromID; + this.description = sd; + this.credentials = credentials; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObject#dispose(org.eclipse.ecf.core.identity.ID) + */ + public void dispose(ID containerID) { + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObject#getAdapter(java.lang.Class) + */ + public Object getAdapter(Class clazz) { + return null; + } + + ID getHomeID() { + return description.getHomeID(); + } + + ID getID() { + return description.getID(); + } + + Thread getThread() { + return new Thread(loadingThreadGroup, new Runnable() { + public void run() { + try { + if (Thread.currentThread().isInterrupted() + || isClosing()) + throw new InterruptedException( + "Loading interrupted for object " + + getID().getName()); + // First load object + ISharedObject obj = load(description); + // Create wrapper object and move from loading to active + // list. + SOWrapper wrap = makeNewRemoteSharedObjectWrapper( + fromID, description, obj); + // Get config info for new object + SOConfig aConfig = wrap.getConfig(); + // Call init method on new object. + obj.init(aConfig); + // Check to make sure thread has not been + // interrupted...if it has, throw + if (Thread.currentThread().isInterrupted() + || isClosing()) + throw new InterruptedException( + "Loading interrupted for object " + + getID().getName()); + // Finally, we move from loading to active, and then the + // object is done + SOContainer.this.moveFromLoadingToActive(wrap); + } catch (Exception e) { + dumpStack("Exception loading object ", e); + SOContainer.this.removeFromLoading(getID()); + try { + sendCreateResponse(getHomeID(), getID(), e, + description.getIdentifier()); + } catch (Exception e1) { + dumpStack( + "Exception sending create response from LoadingSharedObject.run", + e1); + } + } + } + }, getID().getName() + ":load"); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObject#handleEvent(org.eclipse.ecf.core.util.Event) + */ + public void handleEvent(Event event) { + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObject#handleEvents(org.eclipse.ecf.core.util.Event[]) + */ + public void handleEvents(Event[] events) { + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObject#init(org.eclipse.ecf.core.ISharedObjectConfig) + */ + public void init(ISharedObjectConfig initData) + throws SharedObjectInitException { + } + + void start() { + if (runner == null) { + runner = (Thread) AccessController + .doPrivileged(new PrivilegedAction() { + public Object run() { + return getThread(); + } + }); + runner.setDaemon(true); + runner.start(); + } + } + } + + class MessageReceiver implements ISynchAsynchConnectionEventHandler { + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.internal.comm.IConnectionEventHandler#getAdapter(java.lang.Class) + */ + public Object getAdapter(Class clazz) { + return null; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.internal.comm.IAsynchConnectionEventHandler#handleAsynchEvent(org.eclipse.ecf.internal.comm.AsynchConnectionEvent) + */ + public void handleAsynchEvent(AsynchConnectionEvent event) + throws IOException { + processAsynch(event); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.internal.comm.IConnectionEventHandler#handleDisconnectEvent(org.eclipse.ecf.internal.comm.ConnectionEvent) + */ + public void handleDisconnectEvent(DisconnectConnectionEvent event) { + processDisconnect(event); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.internal.comm.IConnectionEventHandler#handleSuspectEvent(org.eclipse.ecf.internal.comm.ConnectionEvent) + */ + public boolean handleSuspectEvent(ConnectionEvent event) { + return false; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.internal.comm.ISynchConnectionEventHandler#handleSynchEvent(org.eclipse.ecf.internal.comm.SynchConnectionEvent) + */ + public Object handleSynchEvent(SynchConnectionEvent event) + throws IOException { + return processSynch(event); + } + } + + static Trace debug = Trace.create("container"); + + public static final String DEFAULT_OBJECT_ARG_KEY = SOContainer.class + .getName() + + ".sharedobjectargs"; + + public static final String DEFAULT_OBJECT_ARGTYPES_KEY = SOContainer.class + .getName() + + ".sharedobjectargs"; + + protected ISharedObjectContainerConfig config = null; + + protected SOContainerGMM groupManager = null; + + protected boolean isClosing = false; + + private Vector listeners = null; + + protected ThreadGroup loadingThreadGroup = null; + + protected MessageReceiver receiver; + + private long sequenceNumber = 0L; + + protected SOManager sharedObjectManager = null; + + protected ThreadGroup sharedObjectThreadGroup = null; + + public SOContainer(ISharedObjectContainerConfig config) { + if (config == null) + throw new InstantiationError("config must not be null"); + this.config = config; + groupManager = new SOContainerGMM(this, new Member(config.getID())); + sharedObjectManager = new SOManager(this); + loadingThreadGroup = makeLoadingThreadGroup(); + sharedObjectThreadGroup = getSharedObjectThreadGroup(); + listeners = new Vector(); + receiver = new MessageReceiver(); + debug("<init>"); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObjectContainer#addListener(org.eclipse.ecf.core.ISharedObjectContainerListener, + * java.lang.String) + */ + public void addListener(ISharedObjectContainerListener l, String filter) { + synchronized (listeners) { + listeners.add(new ContainerListener(l, filter)); + } + } + + protected boolean addNewRemoteMember(ID memberID, Object data) { + debug("addNewRemoteMember:" + memberID); + return groupManager.addMember(new Member(memberID, data)); + } + + protected ISharedObject addSharedObject0(SharedObjectDescription sd, + ISharedObject s) throws Exception { + addSharedObjectWrapper(makeNewSharedObjectWrapper(sd, s)); + return s; + } + + protected void addSharedObjectAndWait(SharedObjectDescription sd, + ISharedObject s, ISharedObjectContainerTransaction t) + throws Exception { + if (sd.getID() == null || s == null) { + throw new SharedObjectAddException( + "Object id is null, or instance is null"); + } + ISharedObject so = addSharedObject0(sd, s); + // Wait right here until committed + if (t != null) + t.waitToCommit(); + } + + protected void addSharedObjectWrapper(SOWrapper wrapper) throws Exception { + if (wrapper == null) + return; + ID id = wrapper.getObjID(); + synchronized (getGroupMembershipLock()) { + Object obj = groupManager.getFromAny(id); + if (obj != null) { + throw new SharedObjectAddException("SharedObject with id " + + id.getName() + " already in container"); + } + // Call initialize. If this throws it halts everything + wrapper.init(); + // Put in table + groupManager.addSharedObjectToActive(wrapper); + } + } + + protected boolean addToLoading(LoadingSharedObject lso) { + return groupManager.addLoadingSharedObject(lso); + } + + /** + * Check remote creation of shared objects. This method is called by the + * remote shared object creation message handler, to verify that the shared + * object from container 'fromID' to container 'toID' with description + * 'desc' is to be allowed to be created within the current container. If + * this method throws, a failure (and exception will be sent back to caller + * If this method returns null, the create message is ignored. If this + * method returns a non-null object, the creation is allowed to proceed. The + * default implementation is to return a non-null object + * + * @param fromID + * the ID of the container sending us this create request + * @param toID + * the ID (or null) of the container intended to receive this + * request + * @param seq + * the sequence number associated with the container message + * @param desc + * the SharedObjectDescription that describes the shared object + * to be created + * + * @returns Object null if the create message is to be ignored, non-null if + * the creation should continue + * + * @throws Exception + * may throw any Exception to communicate back (via + * sendCreateResponse) to the sender that the creation has + * failed + */ + protected Object checkRemoteCreate(ID fromID, ID toID, long seq, + SharedObjectDescription desc) throws Exception { + debug("checkRemoteCreate(" + fromID + "," + toID + "," + seq + "," + + desc + ")"); + return desc; + } + + protected void debug(String msg) { + if (Trace.ON && debug != null) { + debug.msg(msg + ":" + config.getID()); + } + } + + protected boolean destroySharedObject(ID sharedObjectID) { + return groupManager.removeSharedObject(sharedObjectID); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObjectContainer#dispose(long) + */ + public void dispose(long waittime) { + debug("dispose(" + waittime + ")"); + isClosing = true; + // notify listeners + fireContainerEvent(new SharedObjectContainerDisposeEvent(getID())); + // Clear group manager + if (groupManager != null) { + groupManager.removeAllMembers(); + groupManager = null; + } + // Clear shared object manager + if (sharedObjectManager != null) { + sharedObjectManager.dispose(); + sharedObjectManager = null; + } + if (sharedObjectThreadGroup != null) { + sharedObjectThreadGroup.interrupt(); + sharedObjectThreadGroup = null; + } + if (loadingThreadGroup != null) { + loadingThreadGroup.interrupt(); + loadingThreadGroup = null; + } + if (listeners != null) { + listeners.clear(); + listeners = null; + } + } + + protected void dumpStack(String msg, Throwable e) { + if (Trace.ON && debug != null) { + debug.dumpStack(e, msg + ":" + config.getID()); + } + } + + protected void fireContainerEvent(IContainerEvent event) { + synchronized (listeners) { + for (Iterator i = listeners.iterator(); i.hasNext();) { + ContainerListener l = (ContainerListener) i.next(); + l.handleEvent(event); + } + } + } + + protected final void forward(ID fromID, ID toID, ContainerMessage data) + throws IOException { + if (toID == null) { + forwardExcluding(fromID, fromID, data); + } else { + forwardToRemote(fromID, toID, data); + } + } + + abstract protected void forwardExcluding(ID from, ID excluding, + ContainerMessage data) throws IOException; + + abstract protected void forwardToRemote(ID from, ID to, + ContainerMessage data) throws IOException; + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObjectContainer#getAdapter(java.lang.Class) + */ + public Object getAdapter(Class adapter) { + return null; + } + + /** + * @param sd + * @return Object [] + */ + public Object[] getArgsFromProperties(SharedObjectDescription sd) { + if (sd == null) + return null; + Map aMap = sd.getProperties(); + if (aMap == null) + return null; + Object obj = aMap.get(DEFAULT_OBJECT_ARG_KEY); + if (obj == null) + return null; + if (obj instanceof Object[]) { + Object[] ret = (Object[]) obj; + aMap.remove(DEFAULT_OBJECT_ARG_KEY); + return ret; + } else + return null; + } + + /** + * @param sd + * @return String [] + */ + public String[] getArgTypesFromProperties(SharedObjectDescription sd) { + if (sd == null) + return null; + Map aMap = sd.getProperties(); + if (aMap == null) + return null; + Object obj = aMap.get(DEFAULT_OBJECT_ARGTYPES_KEY); + if (obj == null) + return null; + if (obj instanceof String[]) { + String[] ret = (String[]) obj; + aMap.remove(DEFAULT_OBJECT_ARGTYPES_KEY); + return ret; + } else + return null; + } + + protected byte[] getBytesForObject(Serializable obj) throws IOException { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(bos); + oos.writeObject(obj); + return bos.toByteArray(); + } + + protected ClassLoader getClassLoaderForContainer() { + return this.getClass().getClassLoader(); + } + + /** + * @param sd + * @return ClassLoader + */ + protected ClassLoader getClassLoaderForSharedObject( + SharedObjectDescription sd) { + if (sd != null) { + ClassLoader cl = sd.getClassLoader(); + if (cl != null) + return cl; + else + return getClassLoaderForContainer(); + } else + return getClassLoaderForContainer(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObjectContainer#getConfig() + */ + public ISharedObjectContainerConfig getConfig() { + return config; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObjectContainer#getGroupID() + */ + public abstract ID getGroupID(); + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObjectContainer#getGroupMemberIDs() + */ + public ID[] getGroupMemberIDs() { + return groupManager.getMemberIDs(); + } + + protected Object getGroupMembershipLock() { + return groupManager; + } + + public ID getID() { + return config.getID(); + } + + protected int getMaxGroupMembers() { + return groupManager.getMaxMembers(); + } + + protected Thread getNewSharedObjectThread(ID sharedObjectID, + Runnable runnable) { + return new Thread(sharedObjectThreadGroup, runnable, sharedObjectID + .getName() + + ":run"); + } + + protected long getNextSequenceNumber() { + if (sequenceNumber == Long.MAX_VALUE) { + sequenceNumber = 0; + return sequenceNumber; + } else + return sequenceNumber++; + } + + protected ContainerMessage getObjectFromBytes(byte[] bytes) + throws IOException { + ByteArrayInputStream bis = new ByteArrayInputStream(bytes); + ObjectInputStream ois = new ObjectInputStream(bis); + Object obj = null; + try { + obj = ois.readObject(); + } catch (ClassNotFoundException e) { + dumpStack("class not found for message", e); + return null; + } + if (obj instanceof ContainerMessage) { + return (ContainerMessage) obj; + } else { + debug("message received is not containermessage:" + obj); + return null; + } + } + + protected IOSGIService getOSGIServiceInterface() { + return null; + } + + public ID[] getOtherMemberIDs() { + return groupManager.getOtherMemberIDs(); + } + + protected ISynchAsynchConnectionEventHandler getReceiver() { + return receiver; + } + + protected ISharedObject getSharedObject(ID id) { + SOWrapper wrap = getSharedObjectWrapper(id); + if (wrap == null) + return null; + else + return wrap.getSharedObject(); + } + + protected ID[] getSharedObjectIDs() { + return groupManager.getSharedObjectIDs(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObjectContainer#getSharedObjectManager() + */ + public ISharedObjectManager getSharedObjectManager() { + return sharedObjectManager; + } + + protected ThreadGroup getSharedObjectThreadGroup() { + return new ThreadGroup(getID() + ":SOs"); + } + + protected SOWrapper getSharedObjectWrapper(ID id) { + return groupManager.getFromActive(id); + } + + protected void handleAsynchIOException(IOException except, + AsynchConnectionEvent e) { + // If we get IO Exception, we'll disconnect...if we can + killConnection(e.getConnection()); + } + + protected void handleCreateMessage(ContainerMessage mess) + throws IOException { + debug("handleCreateMessage:" + mess); + ContainerMessage.CreateMessage create = (ContainerMessage.CreateMessage) mess + .getData(); + SharedObjectDescription desc = (SharedObjectDescription) create + .getData(); + ID fromID = mess.getFromContainerID(); + ID toID = mess.getToContainerID(); + long seq = mess.getSequence(); + Object checkCreateResult = null; + ID sharedObjectID = desc.getID(); + // Check to make sure that the remote creation is allowed. + // If this method throws, a failure (and exception will be sent back to + // caller + // If this method returns null, the create message is ignored. If this + // method + // returns a non-null object, the creation is allowed to proceed + try { + checkCreateResult = checkRemoteCreate(fromID, toID, seq, desc); + } catch (Exception e) { + SharedObjectAddException addException = new SharedObjectAddException( + "shared object " + sharedObjectID + + " rejected by container " + getID(), e); + dumpStack("Exception in checkRemoteCreate", addException); + try { + sendCreateResponse(fromID, sharedObjectID, addException, desc + .getIdentifier()); + } catch (IOException except) { + logException( + "Exception from sendCreateResponse in handleCreateResponse", + except); + } + return; + } + // Then if result from check is non-null, we continue. If null, we + // ignore + if (checkCreateResult != null) { + LoadingSharedObject lso = new LoadingSharedObject(fromID, desc, + checkCreateResult); + synchronized (getGroupMembershipLock()) { + if (!addToLoading(lso)) { + try { + sendCreateResponse(fromID, sharedObjectID, + new SharedObjectAddException("shared object " + + sharedObjectID + + " already exists in container " + + getID()), desc.getIdentifier()); + } catch (IOException e) { + logException( + "Exception in handleCreateMessage.sendCreateResponse", + e); + } + } + forward(fromID, toID, mess); + return; + } + } + synchronized (getGroupMembershipLock()) { + forward(fromID, toID, mess); + } + } + + protected void handleCreateResponseMessage(ContainerMessage mess) + throws IOException { + debug("handleCreateResponseMessage:" + mess); + ID fromID = mess.getFromContainerID(); + ID toID = mess.getToContainerID(); + long seq = mess.getSequence(); + ContainerMessage.CreateResponseMessage resp = (ContainerMessage.CreateResponseMessage) mess + .getData(); + if (toID != null && toID.equals(getID())) { + ID sharedObjectID = resp.getSharedObjectID(); + SOWrapper sow = getSharedObjectWrapper(sharedObjectID); + if (sow != null) { + sow.deliverCreateResponse(fromID, resp); + } else { + log("handleCreateResponseMessage...wrapper now found for " + + sharedObjectID); + } + } else { + forwardToRemote(fromID, toID, mess); + } + } + + /** + * @param mess + */ + protected abstract void handleLeaveGroupMessage(ContainerMessage mess); + + protected void handleSharedObjectDisposeMessage(ContainerMessage mess) + throws IOException { + debug("handleSharedObjectDisposeMessage:" + mess); + ID fromID = mess.getFromContainerID(); + ID toID = mess.getToContainerID(); + long seq = mess.getSequence(); + ContainerMessage.SharedObjectDisposeMessage resp = (ContainerMessage.SharedObjectDisposeMessage) mess + .getData(); + ID sharedObjectID = resp.getSharedObjectID(); + synchronized (getGroupMembershipLock()) { + if (groupManager.isLoading(sharedObjectID)) { + groupManager.removeSharedObjectFromLoading(sharedObjectID); + } else { + groupManager.removeSharedObject(sharedObjectID); + } + forward(fromID, toID, mess); + } + } + + protected void handleSharedObjectMessage(ContainerMessage mess) + throws IOException { + debug("handleSharedObjectMessage:" + mess); + ID fromID = mess.getFromContainerID(); + ID toID = mess.getToContainerID(); + long seq = mess.getSequence(); + ContainerMessage.SharedObjectMessage resp = (ContainerMessage.SharedObjectMessage) mess + .getData(); + synchronized (getGroupMembershipLock()) { + if (toID == null || toID.equals(getID())) { + SOWrapper sow = getSharedObjectWrapper(resp + .getFromSharedObjectID()); + if (sow != null) { + sow.deliverSharedObjectMessage(fromID, resp.getData()); + } + } + forward(fromID, toID, mess); + } + } + + protected void handleUnidentifiedMessage(ContainerMessage mess) + throws IOException { + // do nothing + } + + protected abstract void handleViewChangeMessage(ContainerMessage mess) + throws IOException; + + protected boolean isClosing() { + return isClosing; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObjectContainer#isGroupManager() + */ + public abstract boolean isGroupManager(); + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObjectContainer#isGroupServer() + */ + public abstract boolean isGroupServer(); + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObjectContainer#joinGroup(org.eclipse.ecf.core.identity.ID, + * java.lang.Object) + */ + public abstract void joinGroup(ID groupID, Object loginData) + throws SharedObjectContainerJoinException; + + protected void killConnection(IConnection conn) { + debug("killconnection"); + try { + if (conn != null) + conn.disconnect(); + } catch (IOException e) { + logException("Exception in killConnection", e); + } + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObjectContainer#leaveGroup() + */ + public abstract void leaveGroup(); + + protected ISharedObject load(SharedObjectDescription sd) throws Exception { + return sharedObjectManager.loadSharedObject(sd); + } + + protected void log(String msg) { + debug(msg); + } + + protected void logException(String msg, Throwable e) { + dumpStack(msg, e); + } + + protected ThreadGroup makeLoadingThreadGroup() { + return new ThreadGroup(getID() + ":load"); + } + + protected SOConfig makeNewSharedObjectConfig(SharedObjectDescription sd, + ISharedObject obj) { + ID homeID = sd.getHomeID(); + if (homeID == null) + homeID = getID(); + return new SOConfig(sd.getID(), homeID, this, sd.getProperties()); + } + + protected SOConfig makeNewRemoteSharedObjectConfig(ID fromID, + SharedObjectDescription sd, ISharedObject obj) { + ID homeID = sd.getHomeID(); + if (homeID == null) + homeID = fromID; + return new SOConfig(sd.getID(), homeID, this, sd.getProperties()); + } + + protected SOContext makeNewSharedObjectContext(SOConfig config, + QueueEnqueue queue) { + return new SOContext(config.getSharedObjectID(), config + .getHomeContainerID(), this, config.getProperties(), queue); + } + + protected SOContext makeNewRemoteSharedObjectContext(SOConfig config, + QueueEnqueue queue) { + return new SOContext(config.getSharedObjectID(), config + .getHomeContainerID(), this, config.getProperties(), queue); + } + + protected SOWrapper makeNewSharedObjectWrapper(SharedObjectDescription sd, + ISharedObject s) { + SOConfig newConfig = makeNewSharedObjectConfig(sd, s); + return new SOWrapper(newConfig, s, this); + } + + protected SOWrapper makeNewRemoteSharedObjectWrapper(ID fromID, + SharedObjectDescription sd, ISharedObject s) { + SOConfig newConfig = makeNewRemoteSharedObjectConfig(fromID, sd, s); + return new SOWrapper(newConfig, s, this); + } + + protected void memberLeave(ID target, IConnection conn) { + debug("memberLeave:" + target + ":" + conn); + if (target == null) + return; + if (groupManager.removeMember(target)) { + try { + forwardExcluding(getID(), target, ContainerMessage + .makeViewChangeMessage(getID(), null, + getNextSequenceNumber(), new ID[] { target }, + false, null)); + } catch (IOException e) { + logException("Exception in memberLeave.forwardExcluding", e); + } + } + if (conn != null) + killConnection(conn); + } + + protected void moveFromLoadingToActive(SOWrapper wrap) { + groupManager.moveSharedObjectFromLoadingToActive(wrap); + } + + protected void notifySharedObjectActivated(ID sharedObjectID) { + groupManager.notifyOthersActivated(sharedObjectID); + } + + protected void notifySharedObjectDeactivated(ID sharedObjectID) { + groupManager.notifyOthersDeactivated(sharedObjectID); + } + + protected ContainerMessage validateContainerMessage(Object mess) { + // Message must not be null + if (mess == null) { + debug("Ignoring null ContainerMessage"); + return null; + } + if (mess instanceof ContainerMessage) { + ContainerMessage contmess = (ContainerMessage) mess; + ID fromID = contmess.getFromContainerID(); + if (fromID == null) { + debug("Ignoring ContainerMessage from null sender...ignoring"); + return null; + } + ID toID = contmess.getToContainerID(); + if (toID == null) { + return contmess; + } else { + if (toID.equals(getID())) { + return contmess; + } else { + debug("Ignoring ContainerMessage from " + fromID + " to " + + toID); + return null; + } + } + // OK + } else { + debug("Ignoring invalid ContainerMessage:" + mess); + return null; + } + + } + + protected void processAsynch(AsynchConnectionEvent e) { + try { + Object obj = e.getData(); + if (obj == null) { + debug("Ignoring null data in event " + e); + return; + } + if (!(obj instanceof byte[])) { + debug("Ignoring event without valid data " + e); + } + ContainerMessage mess = validateContainerMessage(getObjectFromBytes((byte[]) obj)); + if (mess == null) { + return; + } + Serializable submess = mess.getData(); + if (submess != null) { + if (submess instanceof ContainerMessage.CreateMessage) { + handleCreateMessage(mess); + } else if (submess instanceof ContainerMessage.CreateResponseMessage) { + handleCreateResponseMessage(mess); + } else if (submess instanceof ContainerMessage.SharedObjectDisposeMessage) { + handleSharedObjectDisposeMessage(mess); + } else if (submess instanceof ContainerMessage.SharedObjectMessage) { + handleSharedObjectMessage(mess); + } else if (submess instanceof ContainerMessage.ViewChangeMessage) { + handleViewChangeMessage(mess); + } else { + handleUnidentifiedMessage(mess); + } + } else { + handleUnidentifiedMessage(mess); + } + } catch (IOException except) { + handleAsynchIOException(except, e); + } + } + + protected void processDisconnect(DisconnectConnectionEvent e) { + debug("processDisconnect:" + e); + try { + ContainerMessage mess = getObjectFromBytes((byte[]) e.getData()); + } catch (Exception except) { + logException("Exception in processDisconnect ", except); + } + } + + protected Serializable processSynch(SynchConnectionEvent e) + throws IOException { + debug("processSynch:" + e); + ContainerMessage mess = getObjectFromBytes((byte[]) e.getData()); + Serializable data = mess.getData(); + // Must be non null + if (data != null && data instanceof ContainerMessage.LeaveGroupMessage) { + handleLeaveGroupMessage(mess); + } + return null; + } + + abstract protected void queueContainerMessage(ContainerMessage mess) + throws IOException; + + protected void removeFromLoading(ID id) { + groupManager.removeSharedObjectFromLoading(id); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObjectContainer#removeListener(org.eclipse.ecf.core.ISharedObjectContainerListener) + */ + public void removeListener(ISharedObjectContainerListener l) { + synchronized (listeners) { + for (Enumeration e = listeners.elements(); e.hasMoreElements();) { + ContainerListener list = (ContainerListener) e.nextElement(); + if (list.isListener(l)) { + // found it...so remove + listeners.remove(list); + } + } + } + } + + protected boolean removeRemoteMember(ID remoteMember) { + return groupManager.removeMember(remoteMember); + } + + protected ISharedObject removeSharedObject(ID id) { + synchronized (getGroupMembershipLock()) { + SOWrapper wrap = groupManager.getFromActive(id); + if (wrap == null) + return null; + groupManager.removeSharedObject(id); + return wrap.getSharedObject(); + } + } + + protected void sendCreate(ID sharedObjectID, ID toContainerID, + SharedObjectDescription sd) throws IOException { + sendCreateSharedObjectMessage(toContainerID, sd); + } + + protected void sendCreateResponse(ID homeID, ID sharedObjectID, + Throwable t, long identifier) throws IOException { + sendCreateResponseSharedObjectMessage(homeID, sharedObjectID, t, + identifier); + } + + protected void sendCreateResponseSharedObjectMessage(ID toContainerID, + ID fromSharedObject, Throwable t, long ident) throws IOException { + sendMessage(ContainerMessage.makeSharedObjectCreateResponseMessage( + getID(), toContainerID, getNextSequenceNumber(), + fromSharedObject, t, ident)); + } + + protected ID[] sendCreateSharedObjectMessage(ID toContainerID, + SharedObjectDescription sd) throws IOException { + ID[] returnIDs = null; + if (toContainerID == null) { + synchronized (getGroupMembershipLock()) { + // Send message to all + sendMessage(ContainerMessage.makeSharedObjectCreateMessage( + getID(), toContainerID, getNextSequenceNumber(), sd)); + returnIDs = getOtherMemberIDs(); + } + } else { + // If the create msg is directed to this space, no msg will be sent + if (getID().equals(toContainerID)) { + returnIDs = new ID[0]; + } else { + sendMessage(ContainerMessage.makeSharedObjectCreateMessage( + getID(), toContainerID, getNextSequenceNumber(), sd)); + returnIDs = new ID[1]; + returnIDs[0] = toContainerID; + } + } + return returnIDs; + } + + protected void sendDispose(ID toContainerID, ID sharedObjectID) + throws IOException { + sendDisposeSharedObjectMessage(toContainerID, sharedObjectID); + } + + protected void sendDisposeSharedObjectMessage(ID toContainerID, + ID fromSharedObject) throws IOException { + sendMessage(ContainerMessage.makeSharedObjectDisposeMessage(getID(), + toContainerID, getNextSequenceNumber(), fromSharedObject)); + } + + protected void sendMessage(ContainerMessage data) throws IOException { + synchronized (getGroupMembershipLock()) { + ID ourID = getID(); + // We don't send to ourselves + if (!ourID.equals(data.getToContainerID())) { + debug("sendcontainermessage:" + data); + queueContainerMessage(data); + } + } + } + + protected void sendMessage(ID toContainerID, ID sharedObjectID, + Object message) throws IOException { + if (message == null) + return; + sendSharedObjectMessage(toContainerID, sharedObjectID, + (Serializable) message); + } + + protected void sendSharedObjectMessage(ID toContainerID, + ID fromSharedObject, Serializable data) throws IOException { + sendMessage(ContainerMessage.makeSharedObjectMessage(getID(), + toContainerID, getNextSequenceNumber(), fromSharedObject, data)); + } + + protected void setIsClosing() { + isClosing = true; + } + + protected void setMaxGroupMembers(int max) { + groupManager.setMaxMembers(max); + } }
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf.provider/src/org/eclipse/ecf/provider/generic/SOManager.java b/framework/bundles/org.eclipse.ecf.provider/src/org/eclipse/ecf/provider/generic/SOManager.java index efdded9d4..81b218eb6 100644 --- a/framework/bundles/org.eclipse.ecf.provider/src/org/eclipse/ecf/provider/generic/SOManager.java +++ b/framework/bundles/org.eclipse.ecf.provider/src/org/eclipse/ecf/provider/generic/SOManager.java @@ -1,13 +1,13 @@ /**************************************************************************** -* Copyright (c) 2004 Composent, Inc. and others. -* All rights reserved. This program and the accompanying materials -* are made available under the terms of the Eclipse Public License v1.0 -* which accompanies this distribution, and is available at -* http://www.eclipse.org/legal/epl-v10.html -* -* Contributors: -* Composent, Inc. - initial API and implementation -*****************************************************************************/ + * Copyright (c) 2004 Composent, Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Composent, Inc. - initial API and implementation + *****************************************************************************/ /* * Created on Dec 20, 2004 @@ -47,289 +47,311 @@ import org.eclipse.ecf.provider.Trace; * */ public class SOManager implements ISharedObjectManager { - static Trace debug = Trace.create("sharedobjectmanager"); - SOContainer container = null; - Vector connectors = null; + static Trace debug = Trace.create("sharedobjectmanager"); - public SOManager(SOContainer cont) { - super(); - this.container = cont; - connectors = new Vector(); - } + SOContainer container = null; - protected void debug(String msg) { - if (Trace.ON && debug != null) { - debug.msg(msg + ":" + container.getID()); - } - } + Vector connectors = null; - protected void dumpStack(String msg, Throwable e) { - if (Trace.ON && debug != null) { - debug.dumpStack(e, msg + ":" + container.getID()); - } - } + public SOManager(SOContainer cont) { + super(); + this.container = cont; + connectors = new Vector(); + } - protected void addConnector(ISharedObjectConnector conn) { - connectors.add(conn); - } + protected void debug(String msg) { + if (Trace.ON && debug != null) { + debug.msg(msg + ":" + container.getID()); + } + } - protected boolean removeConnector(ISharedObjectConnector conn) { - return connectors.remove(conn); - } + protected void dumpStack(String msg, Throwable e) { + if (Trace.ON && debug != null) { + debug.dumpStack(e, msg + ":" + container.getID()); + } + } - protected List getConnectors() { - return connectors; - } + protected void addConnector(ISharedObjectConnector conn) { + connectors.add(conn); + } - protected Class[] getArgTypes(String[] argTypes, Object[] args, - ClassLoader cl) throws ClassNotFoundException { - return AbstractFactory.getClassesForTypes(argTypes, args, cl); - } + protected boolean removeConnector(ISharedObjectConnector conn) { + return connectors.remove(conn); + } - protected ISharedObject makeSharedObjectInstance(final Class newClass, - final Class[] argTypes, final Object[] args) throws Exception { - Object newObject = null; - try { - newObject = AccessController - .doPrivileged(new PrivilegedExceptionAction() { - public Object run() throws Exception { - Constructor aConstructor = newClass - .getConstructor(argTypes); - aConstructor.setAccessible(true); - return aConstructor.newInstance(args); - } - }); - } catch (java.security.PrivilegedActionException e) { - throw e.getException(); - } - return verifySharedObject(newObject); - } + protected List getConnectors() { + return connectors; + } - protected ISharedObject verifySharedObject(Object newSharedObject) { - if (newSharedObject instanceof ISharedObject) - return (ISharedObject) newSharedObject; - else - throw new ClassCastException("shared object " - + newSharedObject.toString() + " does not implement " - + ISharedObject.class.getName()); - } + protected Class[] getArgTypes(String[] argTypes, Object[] args, + ClassLoader cl) throws ClassNotFoundException { + return AbstractFactory.getClassesForTypes(argTypes, args, cl); + } - protected ISharedObject loadSharedObject(SharedObjectDescription sd) - throws Exception { - // First get classloader - ClassLoader cl = container.getClassLoaderForSharedObject(sd); - // Then get args array from properties - Object[] args = container.getArgsFromProperties(sd); - // And arg types - String[] types = container.getArgTypesFromProperties(sd); - Class[] argTypes = getArgTypes(types, args, cl); - // Now load top-level class - final Class newClass = Class.forName(sd.getClassname(), true, cl); - return makeSharedObjectInstance(newClass, argTypes, args); - } + protected ISharedObject makeSharedObjectInstance(final Class newClass, + final Class[] argTypes, final Object[] args) throws Exception { + Object newObject = null; + try { + newObject = AccessController + .doPrivileged(new PrivilegedExceptionAction() { + public Object run() throws Exception { + Constructor aConstructor = newClass + .getConstructor(argTypes); + aConstructor.setAccessible(true); + return aConstructor.newInstance(args); + } + }); + } catch (java.security.PrivilegedActionException e) { + throw e.getException(); + } + return verifySharedObject(newObject); + } - /* - * (non-Javadoc) - * - * @see org.eclipse.ecf.core.ISharedObjectManager#getSharedObjectIDs() - */ - public ID[] getSharedObjectIDs() { - debug("getSharedObjectIDs()"); - return container.getSharedObjectIDs(); - } + protected ISharedObject verifySharedObject(Object newSharedObject) { + if (newSharedObject instanceof ISharedObject) + return (ISharedObject) newSharedObject; + else + throw new ClassCastException("shared object " + + newSharedObject.toString() + " does not implement " + + ISharedObject.class.getName()); + } - /* - * (non-Javadoc) - * - * @see org.eclipse.ecf.core.ISharedObjectManager#createSharedObject(org.eclipse.ecf.core.SharedObjectDescription, - * org.eclipse.ecf.core.ISharedObjectContainerTransaction) - */ - public ID createSharedObject(SharedObjectDescription sd, - ISharedObjectContainerTransaction trans) - throws SharedObjectCreateException { - debug("createSharedObject(" + sd + "," + trans + ")"); - // notify listeners - if (sd == null) throw new SharedObjectCreateException("SharedObjectDescription cannot be null"); - ID sharedObjectID = sd.getID(); - if (sharedObjectID == null) throw new SharedObjectCreateException("New object ID cannot be null"); - container.fireContainerEvent(new SharedObjectManagerCreateEvent(container.getID(),sd)); - ISharedObject newObject = null; - Throwable t = null; - ID result = sharedObjectID; - try { - newObject = loadSharedObject(sd); - result = addSharedObject(sharedObjectID, newObject, sd.getProperties(), trans); - } catch (Exception e) { - dumpStack("Exception in createSharedObject",e); - SharedObjectCreateException newExcept = new SharedObjectCreateException("Container "+container.getID()+" had exception creating shared object "+sharedObjectID+": "+e.getClass().getName()+": "+e.getMessage()); - newExcept.setStackTrace(e.getStackTrace()); - throw newExcept; - } - return result; - } + protected ISharedObject loadSharedObject(SharedObjectDescription sd) + throws Exception { + // First get classloader + ClassLoader cl = container.getClassLoaderForSharedObject(sd); + // Then get args array from properties + Object[] args = container.getArgsFromProperties(sd); + // And arg types + String[] types = container.getArgTypesFromProperties(sd); + Class[] argTypes = getArgTypes(types, args, cl); + // Now load top-level class + final Class newClass = Class.forName(sd.getClassname(), true, cl); + return makeSharedObjectInstance(newClass, argTypes, args); + } - /* - * (non-Javadoc) - * - * @see org.eclipse.ecf.core.ISharedObjectManager#addSharedObject(org.eclipse.ecf.core.identity.ID, - * org.eclipse.ecf.core.ISharedObject, java.util.Map, - * org.eclipse.ecf.core.ISharedObjectContainerTransaction) - */ - public ID addSharedObject(ID sharedObjectID, ISharedObject sharedObject, - Map properties, ISharedObjectContainerTransaction trans) - throws SharedObjectAddException { - debug("addSharedObject(" + sharedObjectID + "," + sharedObject + "," - + properties + "," + trans + ")"); - // notify listeners - container.fireContainerEvent(new SharedObjectManagerAddEvent(container.getID(),sharedObjectID,sharedObject,properties)); - Throwable t = null; - ID result = sharedObjectID; - try { - ISharedObject so = sharedObject; - SharedObjectDescription sd = new SharedObjectDescription( - sharedObject.getClass().getClassLoader(), sharedObjectID, - container.getID(), sharedObject.getClass().getName(), - properties, 0); - container.addSharedObjectAndWait(sd, so, trans); - } catch (Exception e) { - dumpStack("Exception in addSharedObject",e); - SharedObjectAddException newExcept = new SharedObjectAddException("Container "+container.getID()+" had exception adding shared object "+sharedObjectID+": "+e.getClass().getName()+": "+e.getMessage()); - newExcept.setStackTrace(e.getStackTrace()); - throw newExcept; - } - // notify listeners - container.fireContainerEvent(new SharedObjectActivatedEvent(container.getID(), result, container.getGroupMemberIDs())); - return result; - } + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObjectManager#getSharedObjectIDs() + */ + public ID[] getSharedObjectIDs() { + debug("getSharedObjectIDs()"); + return container.getSharedObjectIDs(); + } - /* - * (non-Javadoc) - * - * @see org.eclipse.ecf.core.ISharedObjectManager#getSharedObject(org.eclipse.ecf.core.identity.ID) - */ - public ISharedObject getSharedObject(ID sharedObjectID) { - debug("getSharedObject(" + sharedObjectID + ")"); - return container.getSharedObject(sharedObjectID); - } + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObjectManager#createSharedObject(org.eclipse.ecf.core.SharedObjectDescription, + * org.eclipse.ecf.core.ISharedObjectContainerTransaction) + */ + public ID createSharedObject(SharedObjectDescription sd, + ISharedObjectContainerTransaction trans) + throws SharedObjectCreateException { + debug("createSharedObject(" + sd + "," + trans + ")"); + // notify listeners + if (sd == null) + throw new SharedObjectCreateException( + "SharedObjectDescription cannot be null"); + ID sharedObjectID = sd.getID(); + if (sharedObjectID == null) + throw new SharedObjectCreateException( + "New object ID cannot be null"); + container.fireContainerEvent(new SharedObjectManagerCreateEvent( + container.getID(), sd)); + ISharedObject newObject = null; + Throwable t = null; + ID result = sharedObjectID; + try { + newObject = loadSharedObject(sd); + result = addSharedObject(sharedObjectID, newObject, sd + .getProperties(), trans); + } catch (Exception e) { + dumpStack("Exception in createSharedObject", e); + SharedObjectCreateException newExcept = new SharedObjectCreateException( + "Container " + container.getID() + + " had exception creating shared object " + + sharedObjectID + ": " + e.getClass().getName() + + ": " + e.getMessage()); + newExcept.setStackTrace(e.getStackTrace()); + throw newExcept; + } + return result; + } - /* - * (non-Javadoc) - * - * @see org.eclipse.ecf.core.ISharedObjectManager#removeSharedObject(org.eclipse.ecf.core.identity.ID) - */ - public ISharedObject removeSharedObject(ID sharedObjectID) { - debug("removeSharedObject(" + sharedObjectID + ")"); - // notify listeners - container.fireContainerEvent(new SharedObjectManagerRemoveEvent(container.getID(),sharedObjectID)); - return container.removeSharedObject(sharedObjectID); - } + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObjectManager#addSharedObject(org.eclipse.ecf.core.identity.ID, + * org.eclipse.ecf.core.ISharedObject, java.util.Map, + * org.eclipse.ecf.core.ISharedObjectContainerTransaction) + */ + public ID addSharedObject(ID sharedObjectID, ISharedObject sharedObject, + Map properties, ISharedObjectContainerTransaction trans) + throws SharedObjectAddException { + debug("addSharedObject(" + sharedObjectID + "," + sharedObject + "," + + properties + "," + trans + ")"); + // notify listeners + container.fireContainerEvent(new SharedObjectManagerAddEvent(container + .getID(), sharedObjectID, sharedObject, properties)); + Throwable t = null; + ID result = sharedObjectID; + try { + ISharedObject so = sharedObject; + SharedObjectDescription sd = new SharedObjectDescription( + sharedObject.getClass().getClassLoader(), sharedObjectID, + container.getID(), sharedObject.getClass().getName(), + properties, 0); + container.addSharedObjectAndWait(sd, so, trans); + } catch (Exception e) { + dumpStack("Exception in addSharedObject", e); + SharedObjectAddException newExcept = new SharedObjectAddException( + "Container " + container.getID() + + " had exception adding shared object " + + sharedObjectID + ": " + e.getClass().getName() + + ": " + e.getMessage()); + newExcept.setStackTrace(e.getStackTrace()); + throw newExcept; + } + // notify listeners + container.fireContainerEvent(new SharedObjectActivatedEvent(container + .getID(), result, container.getGroupMemberIDs())); + return result; + } - /* - * (non-Javadoc) - * - * @see org.eclipse.ecf.core.ISharedObjectManager#connectSharedObjects(org.eclipse.ecf.core.identity.ID, - * org.eclipse.ecf.core.identity.ID[]) - */ - public ISharedObjectConnector connectSharedObjects(ID sharedObjectFrom, - ID[] sharedObjectsTo) throws SharedObjectConnectException { - debug("connectSharedObjects(" + sharedObjectFrom + "," - + sharedObjectsTo + ")"); - // notify listeners - container.fireContainerEvent(new SharedObjectManagerConnectEvent(container.getID(),sharedObjectFrom,sharedObjectsTo)); - if (sharedObjectFrom == null) - throw new SharedObjectConnectException("sender cannot be null"); - if (sharedObjectsTo == null) - throw new SharedObjectConnectException("receivers cannot be null"); - ISharedObjectConnector result = null; - synchronized (container.getGroupMembershipLock()) { - // Get from to make sure it's there - SOWrapper wrap = container.getSharedObjectWrapper(sharedObjectFrom); - if (wrap == null) - throw new SharedObjectConnectException("sender object " - + sharedObjectFrom.getName() + " not found"); - QueueEnqueue[] queues = new QueueEnqueue[sharedObjectsTo.length]; - for (int i = 0; i < sharedObjectsTo.length; i++) { - SOWrapper w = container - .getSharedObjectWrapper(sharedObjectsTo[i]); - if (w == null) - throw new SharedObjectConnectException("receiver object " - + sharedObjectsTo[i].getName() + " not found"); - queues[i] = new QueueEnqueueImpl(w.getQueue()); - } - // OK now we've got ids and wrappers, make a connector - result = new SOConnector(sharedObjectFrom, sharedObjectsTo, queues); - } - return result; - } + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObjectManager#getSharedObject(org.eclipse.ecf.core.identity.ID) + */ + public ISharedObject getSharedObject(ID sharedObjectID) { + debug("getSharedObject(" + sharedObjectID + ")"); + return container.getSharedObject(sharedObjectID); + } - /* - * (non-Javadoc) - * - * @see org.eclipse.ecf.core.ISharedObjectManager#disconnectSharedObjects(org.eclipse.ecf.core.ISharedObjectConnector) - */ - public void disconnectSharedObjects(ISharedObjectConnector connector) - throws SharedObjectDisconnectException { - if (connector != null) { - debug("disconnectSharedObjects(" + connector.getSender() + ")"); - // notify listeners - container.fireContainerEvent(new SharedObjectManagerDisconnectEvent(container.getID(),connector.getSender())); - } - if (connector == null) - throw new SharedObjectDisconnectException("connect cannot be null"); - if (!removeConnector(connector)) { - throw new SharedObjectDisconnectException("connector " + connector - + " not found"); - } - connector.dispose(); - } + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObjectManager#removeSharedObject(org.eclipse.ecf.core.identity.ID) + */ + public ISharedObject removeSharedObject(ID sharedObjectID) { + debug("removeSharedObject(" + sharedObjectID + ")"); + // notify listeners + container.fireContainerEvent(new SharedObjectManagerRemoveEvent( + container.getID(), sharedObjectID)); + return container.removeSharedObject(sharedObjectID); + } - protected void dispose() { - debug("dispose()"); - for (Enumeration e = connectors.elements(); e.hasMoreElements();) { - ISharedObjectConnector conn = (ISharedObjectConnector) e - .nextElement(); - conn.dispose(); - } - connectors.clear(); - } + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObjectManager#connectSharedObjects(org.eclipse.ecf.core.identity.ID, + * org.eclipse.ecf.core.identity.ID[]) + */ + public ISharedObjectConnector connectSharedObjects(ID sharedObjectFrom, + ID[] sharedObjectsTo) throws SharedObjectConnectException { + debug("connectSharedObjects(" + sharedObjectFrom + "," + + sharedObjectsTo + ")"); + // notify listeners + container.fireContainerEvent(new SharedObjectManagerConnectEvent( + container.getID(), sharedObjectFrom, sharedObjectsTo)); + if (sharedObjectFrom == null) + throw new SharedObjectConnectException("sender cannot be null"); + if (sharedObjectsTo == null) + throw new SharedObjectConnectException("receivers cannot be null"); + ISharedObjectConnector result = null; + synchronized (container.getGroupMembershipLock()) { + // Get from to make sure it's there + SOWrapper wrap = container.getSharedObjectWrapper(sharedObjectFrom); + if (wrap == null) + throw new SharedObjectConnectException("sender object " + + sharedObjectFrom.getName() + " not found"); + QueueEnqueue[] queues = new QueueEnqueue[sharedObjectsTo.length]; + for (int i = 0; i < sharedObjectsTo.length; i++) { + SOWrapper w = container + .getSharedObjectWrapper(sharedObjectsTo[i]); + if (w == null) + throw new SharedObjectConnectException("receiver object " + + sharedObjectsTo[i].getName() + " not found"); + queues[i] = new QueueEnqueueImpl(w.getQueue()); + } + // OK now we've got ids and wrappers, make a connector + result = new SOConnector(sharedObjectFrom, sharedObjectsTo, queues); + } + return result; + } - /* - * (non-Javadoc) - * - * @see org.eclipse.ecf.core.ISharedObjectManager#getSharedObjectConnectors(org.eclipse.ecf.core.identity.ID) - */ - public List getSharedObjectConnectors(ID sharedObjectFrom) { - debug("getSharedObjectConnectors(" + sharedObjectFrom + ")"); - List results = new ArrayList(); - for (Enumeration e = connectors.elements(); e.hasMoreElements();) { - ISharedObjectConnector conn = (ISharedObjectConnector) e - .nextElement(); - if (sharedObjectFrom.equals(conn.getSender())) { - results.add(conn); - } - } - return results; - } + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObjectManager#disconnectSharedObjects(org.eclipse.ecf.core.ISharedObjectConnector) + */ + public void disconnectSharedObjects(ISharedObjectConnector connector) + throws SharedObjectDisconnectException { + if (connector != null) { + debug("disconnectSharedObjects(" + connector.getSender() + ")"); + // notify listeners + container + .fireContainerEvent(new SharedObjectManagerDisconnectEvent( + container.getID(), connector.getSender())); + } + if (connector == null) + throw new SharedObjectDisconnectException("connect cannot be null"); + if (!removeConnector(connector)) { + throw new SharedObjectDisconnectException("connector " + connector + + " not found"); + } + connector.dispose(); + } - public static Class[] getClassesForTypes(String[] argTypes, Object[] args, - ClassLoader cl) throws ClassNotFoundException { - Class clazzes[] = null; - if (args == null || args.length == 0) - clazzes = new Class[0]; - else if (argTypes != null) { - clazzes = new Class[argTypes.length]; - for (int i = 0; i < argTypes.length; i++) { - clazzes[i] = Class.forName(argTypes[i], true, cl); - } - } else { - clazzes = new Class[args.length]; - for (int i = 0; i < args.length; i++) { - if (args[i] == null) - clazzes[i] = null; - else - clazzes[i] = args[i].getClass(); - } - } - return clazzes; - } + protected void dispose() { + debug("dispose()"); + for (Enumeration e = connectors.elements(); e.hasMoreElements();) { + ISharedObjectConnector conn = (ISharedObjectConnector) e + .nextElement(); + conn.dispose(); + } + connectors.clear(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObjectManager#getSharedObjectConnectors(org.eclipse.ecf.core.identity.ID) + */ + public List getSharedObjectConnectors(ID sharedObjectFrom) { + debug("getSharedObjectConnectors(" + sharedObjectFrom + ")"); + List results = new ArrayList(); + for (Enumeration e = connectors.elements(); e.hasMoreElements();) { + ISharedObjectConnector conn = (ISharedObjectConnector) e + .nextElement(); + if (sharedObjectFrom.equals(conn.getSender())) { + results.add(conn); + } + } + return results; + } + + public static Class[] getClassesForTypes(String[] argTypes, Object[] args, + ClassLoader cl) throws ClassNotFoundException { + Class clazzes[] = null; + if (args == null || args.length == 0) + clazzes = new Class[0]; + else if (argTypes != null) { + clazzes = new Class[argTypes.length]; + for (int i = 0; i < argTypes.length; i++) { + clazzes[i] = Class.forName(argTypes[i], true, cl); + } + } else { + clazzes = new Class[args.length]; + for (int i = 0; i < args.length; i++) { + if (args[i] == null) + clazzes[i] = null; + else + clazzes[i] = args[i].getClass(); + } + } + return clazzes; + } }
\ No newline at end of file |
