Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpnehrer2005-02-02 15:45:19 -0500
committerpnehrer2005-02-02 15:45:19 -0500
commitd44dd594131c7c864d335be33ec6b2f0436e3bdd (patch)
treecf2dcbc8fa9a44747f79b2958f8869ba137fe079 /examples/bundles
parent1ebdaf7cddc27342e532e6ae0f8d3f404b32ba15 (diff)
downloadorg.eclipse.ecf-d44dd594131c7c864d335be33ec6b2f0436e3bdd.tar.gz
org.eclipse.ecf-d44dd594131c7c864d335be33ec6b2f0436e3bdd.tar.xz
org.eclipse.ecf-d44dd594131c7c864d335be33ec6b2f0436e3bdd.zip
Refactored, fixed bugs, and made SharedSDOEditor work!
Diffstat (limited to 'examples/bundles')
-rw-r--r--examples/bundles/org.eclipse.ecf.example.sdo.editor/META-INF/MANIFEST.MF2
-rw-r--r--examples/bundles/org.eclipse.ecf.example.sdo.editor/src/org/eclipse/ecf/example/sdo/editor/EditorPlugin.java295
-rw-r--r--examples/bundles/org.eclipse.ecf.example.sdo.editor/src/org/eclipse/ecf/example/sdo/editor/PublishedGraphTracker.java618
-rw-r--r--examples/bundles/org.eclipse.ecf.example.sdo.editor/src/org/eclipse/ecf/example/sdo/editor/SharedSDOEditor.java171
-rw-r--r--examples/bundles/org.eclipse.ecf.sdo/src/org/eclipse/ecf/internal/sdo/DataGraphSharing.java16
-rw-r--r--examples/bundles/org.eclipse.ecf.sdo/src/org/eclipse/ecf/internal/sdo/SharedDataGraph.java19
-rw-r--r--examples/bundles/org.eclipse.ecf.sdo/src/org/eclipse/ecf/sdo/IDataGraphSharing.java18
-rw-r--r--examples/bundles/org.eclipse.ecf.sdo/src/org/eclipse/ecf/sdo/IPublicationCallback.java29
-rw-r--r--examples/bundles/org.eclipse.ecf.sdo/src/org/eclipse/ecf/sdo/WaitablePublicationCallback.java48
9 files changed, 713 insertions, 503 deletions
diff --git a/examples/bundles/org.eclipse.ecf.example.sdo.editor/META-INF/MANIFEST.MF b/examples/bundles/org.eclipse.ecf.example.sdo.editor/META-INF/MANIFEST.MF
index 8d07a12cd..22615b4d4 100644
--- a/examples/bundles/org.eclipse.ecf.example.sdo.editor/META-INF/MANIFEST.MF
+++ b/examples/bundles/org.eclipse.ecf.example.sdo.editor/META-INF/MANIFEST.MF
@@ -15,3 +15,5 @@ Require-Bundle: org.eclipse.ui,
org.eclipse.ecf.test.provider,
org.eclipse.ecf.example.collab
Eclipse-AutoStart: true
+Provide-Package: org.eclipse.ecf.example.sdo.editor
+Export-Package: org.eclipse.ecf.example.sdo.editor
diff --git a/examples/bundles/org.eclipse.ecf.example.sdo.editor/src/org/eclipse/ecf/example/sdo/editor/EditorPlugin.java b/examples/bundles/org.eclipse.ecf.example.sdo.editor/src/org/eclipse/ecf/example/sdo/editor/EditorPlugin.java
index 7f6f5f349..82381c9fe 100644
--- a/examples/bundles/org.eclipse.ecf.example.sdo.editor/src/org/eclipse/ecf/example/sdo/editor/EditorPlugin.java
+++ b/examples/bundles/org.eclipse.ecf.example.sdo.editor/src/org/eclipse/ecf/example/sdo/editor/EditorPlugin.java
@@ -21,9 +21,10 @@ import org.eclipse.ecf.core.identity.IDFactory;
import org.eclipse.ecf.core.util.ECFException;
import org.eclipse.ecf.example.collab.Client;
import org.eclipse.ecf.sdo.ISharedDataGraph;
-import org.eclipse.ecf.sdo.ISubscriptionCallback;
import org.eclipse.ecf.sdo.IUpdateConsumer;
import org.eclipse.ecf.sdo.SDOPlugin;
+import org.eclipse.ecf.sdo.WaitablePublicationCallback;
+import org.eclipse.ecf.sdo.WaitableSubscriptionCallback;
import org.eclipse.ecf.sdo.emf.EMFUpdateProvider;
import org.eclipse.ecf.test.EventSpy;
import org.eclipse.ui.plugin.AbstractUIPlugin;
@@ -37,141 +38,159 @@ import commonj.sdo.DataGraph;
* @author pnehrer
*/
public class EditorPlugin extends AbstractUIPlugin {
- // The shared instance.
- private static EditorPlugin plugin;
-
- // Resource bundle.
- private ResourceBundle resourceBundle;
-
- private ISharedObjectContainer container;
-
- private PublishedGraphTracker tracker;
-
- /**
- * The constructor.
- */
- public EditorPlugin() {
- super();
- plugin = this;
- try {
- resourceBundle = ResourceBundle
- .getBundle("org.eclipse.ecf.example.sdo.editor.EditorPluginResources");
- } catch (MissingResourceException x) {
- resourceBundle = null;
- }
- }
-
- /**
- * This method is called upon plug-in activation
- */
- public void start(BundleContext context) throws Exception {
- super.start(context);
- }
-
- /**
- * This method is called when the plug-in is stopped
- */
- public void stop(BundleContext context) throws Exception {
- super.stop(context);
- }
-
- /**
- * Returns the shared instance.
- */
- public static EditorPlugin getDefault() {
- return plugin;
- }
-
- /**
- * Returns the string from the plugin's resource bundle, or 'key' if not
- * found.
- */
- public static String getResourceString(String key) {
- ResourceBundle bundle = EditorPlugin.getDefault().getResourceBundle();
- try {
- return (bundle != null) ? bundle.getString(key) : key;
- } catch (MissingResourceException e) {
- return key;
- }
- }
-
- /**
- * Returns the plugin's resource bundle,
- */
- public ResourceBundle getResourceBundle() {
- return resourceBundle;
- }
-
- public void log(Throwable t) {
- if (t instanceof CoreException)
- getLog().log(((CoreException) t).getStatus());
- else
- getLog().log(
- new Status(Status.ERROR, getBundle().getSymbolicName(), 0,
- "An unexpected error occurred.", t));
- }
-
- public synchronized ISharedDataGraph subscribe(String path,
- ISubscriptionCallback callback, IUpdateConsumer consumer)
- throws ECFException {
- initialize();
- SDOPlugin.getDefault().setDebug(true);
- ID id = IDFactory.makeStringID(path);
- ISharedDataGraph result = SDOPlugin.getDefault().getDataGraphSharing(
- container).subscribe(id, callback, new EMFUpdateProvider(),
- consumer);
- tracker.add(id);
- return result;
- }
-
- public synchronized ISharedDataGraph publish(String path,
- DataGraph dataGraph, IUpdateConsumer consumer) throws ECFException {
- initialize();
- SDOPlugin.getDefault().setDebug(true);
- ID id = IDFactory.makeStringID(path);
- ISharedDataGraph result = SDOPlugin.getDefault().getDataGraphSharing(
- container).publish(dataGraph, id, new EMFUpdateProvider(),
- consumer);
- tracker.add(id);
- return result;
- }
-
- public synchronized boolean isPublished(String path) throws ECFException {
- initialize();
- return tracker.isPublished(IDFactory.makeStringID(path));
- }
-
- public synchronized void checkConnected() throws ECFException {
- initialize();
- }
-
- private void initialize() throws ECFException {
- if (tracker == null) {
- Client client;
- try {
- client = new Client();
- } catch (Exception e) {
- throw new ECFException(e);
- }
-
- container = client.getContainer();
- if (container == null)
- throw new ECFException("Not connected.");
-
- PublishedGraphTracker tracker = new PublishedGraphTracker();
- container.getSharedObjectManager().addSharedObject(
- IDFactory.makeStringID(PublishedGraphTracker.class
- .getName()), tracker, null, null);
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- // ignore
- }
-
- this.tracker = tracker;
- container.getSharedObjectManager()
- .addSharedObject(IDFactory.makeStringID("debug"),
- new EventSpy(), null, null);
- }
- }
+ // The shared instance.
+ private static EditorPlugin plugin;
+
+ // Resource bundle.
+ private ResourceBundle resourceBundle;
+
+ private ISharedObjectContainer container;
+
+ private PublishedGraphTracker tracker;
+
+ /**
+ * The constructor.
+ */
+ public EditorPlugin() {
+ super();
+ plugin = this;
+ try {
+ resourceBundle = ResourceBundle
+ .getBundle("org.eclipse.ecf.example.sdo.editor.EditorPluginResources");
+ } catch (MissingResourceException x) {
+ resourceBundle = null;
+ }
+ }
+
+ /**
+ * This method is called upon plug-in activation
+ */
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ }
+
+ /**
+ * This method is called when the plug-in is stopped
+ */
+ public void stop(BundleContext context) throws Exception {
+ super.stop(context);
+ }
+
+ /**
+ * Returns the shared instance.
+ */
+ public static EditorPlugin getDefault() {
+ return plugin;
+ }
+
+ /**
+ * Returns the string from the plugin's resource bundle, or 'key' if not
+ * found.
+ */
+ public static String getResourceString(String key) {
+ ResourceBundle bundle = EditorPlugin.getDefault().getResourceBundle();
+ try {
+ return (bundle != null) ? bundle.getString(key) : key;
+ } catch (MissingResourceException e) {
+ return key;
+ }
+ }
+
+ /**
+ * Returns the plugin's resource bundle,
+ */
+ public ResourceBundle getResourceBundle() {
+ return resourceBundle;
+ }
+
+ public void log(Throwable t) {
+ if (t instanceof CoreException)
+ getLog().log(((CoreException) t).getStatus());
+ else
+ getLog().log(
+ new Status(Status.ERROR, getBundle().getSymbolicName(), 0,
+ "An unexpected error occurred.", t));
+ }
+
+ public synchronized ISharedDataGraph subscribe(String path,
+ IUpdateConsumer consumer) throws ECFException {
+ initialize();
+ SDOPlugin.getDefault().setDebug(true);
+ ID id = IDFactory.makeStringID(path);
+ WaitableSubscriptionCallback mutex = new WaitableSubscriptionCallback();
+ ISharedDataGraph result = SDOPlugin.getDefault().getDataGraphSharing(
+ container).subscribe(id, new EMFUpdateProvider(), consumer,
+ mutex);
+ ID containerID = null;
+ try {
+ containerID = mutex.waitForSubscription(5000);
+ } catch (InterruptedException e) {
+ throw new ECFException(e);
+ }
+
+ if (containerID == null)
+ throw new ECFException("Subscription timed out.");
+
+ tracker.add(id);
+ return result;
+ }
+
+ public synchronized ISharedDataGraph publish(String path,
+ DataGraph dataGraph, IUpdateConsumer consumer) throws ECFException {
+ initialize();
+ SDOPlugin.getDefault().setDebug(true);
+ ID id = IDFactory.makeStringID(path);
+ WaitablePublicationCallback mutex = new WaitablePublicationCallback();
+ ISharedDataGraph result = SDOPlugin.getDefault().getDataGraphSharing(
+ container).publish(dataGraph, id, new EMFUpdateProvider(),
+ consumer, mutex);
+ try {
+ if (!mutex.waitForPublication(5000))
+ throw new ECFException("Publication timed out.");
+ } catch (InterruptedException e) {
+ throw new ECFException(e);
+ }
+
+ tracker.add(id);
+ return result;
+ }
+
+ public synchronized boolean isPublished(String path) throws ECFException {
+ initialize();
+ return tracker.isPublished(IDFactory.makeStringID(path));
+ }
+
+ public synchronized void checkConnected() throws ECFException {
+ initialize();
+ }
+
+ private void initialize() throws ECFException {
+ if (tracker == null) {
+ Client client;
+ try {
+ client = new Client();
+ } catch (Exception e) {
+ throw new ECFException(e);
+ }
+
+ container = client.getContainer();
+ if (container == null)
+ throw new ECFException("Not connected.");
+
+ ID id = IDFactory.makeStringID(PublishedGraphTracker.class
+ .getName());
+ PublishedGraphTracker tracker = (PublishedGraphTracker) container
+ .getSharedObjectManager().getSharedObject(id);
+ if (tracker == null) {
+ tracker = new PublishedGraphTracker();
+ container.getSharedObjectManager().addSharedObject(id, tracker,
+ null, null);
+ }
+
+ this.tracker = tracker;
+ container.getSharedObjectManager()
+ .addSharedObject(IDFactory.makeStringID("debug"),
+ new EventSpy(), null, null);
+ }
+ }
} \ No newline at end of file
diff --git a/examples/bundles/org.eclipse.ecf.example.sdo.editor/src/org/eclipse/ecf/example/sdo/editor/PublishedGraphTracker.java b/examples/bundles/org.eclipse.ecf.example.sdo.editor/src/org/eclipse/ecf/example/sdo/editor/PublishedGraphTracker.java
index e48d8c6b7..ba19e9581 100644
--- a/examples/bundles/org.eclipse.ecf.example.sdo.editor/src/org/eclipse/ecf/example/sdo/editor/PublishedGraphTracker.java
+++ b/examples/bundles/org.eclipse.ecf.example.sdo.editor/src/org/eclipse/ecf/example/sdo/editor/PublishedGraphTracker.java
@@ -11,14 +11,16 @@
package org.eclipse.ecf.example.sdo.editor;
import java.io.IOException;
-import java.util.Arrays;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
+import java.util.Map;
-import org.eclipse.core.runtime.PlatformObject;
import org.eclipse.ecf.core.ISharedObject;
import org.eclipse.ecf.core.ISharedObjectConfig;
+import org.eclipse.ecf.core.ISharedObjectContext;
+import org.eclipse.ecf.core.SharedObjectDescription;
import org.eclipse.ecf.core.SharedObjectInitException;
import org.eclipse.ecf.core.events.ISharedObjectActivatedEvent;
import org.eclipse.ecf.core.events.ISharedObjectContainerDepartedEvent;
@@ -30,254 +32,370 @@ import org.eclipse.ecf.core.util.ECFException;
import org.eclipse.ecf.core.util.Event;
/**
+ * <p>
+ * Tracks explicit data graph publication (or any shared object presence,
+ * really) across all containers in a connected group using the server replica
+ * to bootstrap new members.
+ * </p>
+ * <p>
+ * It works something like this:
+ * </p>
+ * <ul>
+ * <li>The client should first check if an instance of this shared object
+ * already exists in their container. If not, create one and add it.</li>
+ * <li>The client should call {@link #add(ID) add()}once published/subscribed
+ * to a data graph. The method will block until this object activates (if it
+ * hasn't already).</li>
+ * <li>Upon activation, the primary instance replicates everywhere. This is to
+ * assure that there is a server replica (and a replica in the initial set of
+ * connected containers).</li>
+ * <li>When a new container joins the group, the server will create a replica
+ * in it, initialized with its current graph location table. This is to assure
+ * that new members are properly bootstrapped.</li>
+ * <li>All replicas broadcast additions/removals of their local data graphs and
+ * listen to remote additions/removals in order to keep track of what is
+ * published and where.</li>
+ * <li>When a container leaves the group, all replicas note it and update their
+ * graph location tables. Likewise, when a replica deactivates, it broadcasts
+ * its departure so others may update their tables.</li>
+ * </ul>
+ * <p>
+ * It is assumed that the container implementation used with this class is
+ * server-centric. That is, there is a server that is always connected before
+ * any other container may connect. When the server disconnects, everyone else
+ * in effect disconnects.
+ * </p>
+ *
* @author pnehrer
*/
-class PublishedGraphTracker extends PlatformObject implements ISharedObject {
-
- private static final ID[] NO_GRAPHS = {};
-
- private static final int JOIN = 0;
-
- private static final int LEAVE = 1;
-
- private static final int ADD = 2;
-
- private static final int REMOVE = 3;
-
- private class Table {
-
- private final Hashtable graphs = new Hashtable();
-
- private final Hashtable containers = new Hashtable();
-
- public synchronized void add(ID containerID, ID[] graphs) {
- HashSet list = (HashSet) this.graphs.get(containerID);
- if (list == null) {
- list = new HashSet();
- this.graphs.put(containerID, list);
- }
-
- list.addAll(Arrays.asList(graphs));
- for (int i = 0; i < graphs.length; ++i) {
- list = (HashSet) containers.get(graphs[i]);
- if (list == null) {
- list = new HashSet();
- containers.put(graphs[i], list);
- }
-
- list.add(containerID);
- }
- }
-
- public synchronized void remove(ID containerID, ID graph) {
- HashSet list = (HashSet) graphs.get(containerID);
- if (list != null) {
- list.remove(graph);
- if (list.isEmpty())
- graphs.remove(containerID);
- }
-
- list = (HashSet) containers.get(graph);
- if (list != null) {
- list.remove(containerID);
- if (list.isEmpty())
- containers.remove(graph);
- }
- }
-
- public synchronized void remove(ID containerID) {
- HashSet list = (HashSet) graphs.get(containerID);
- if (list != null) {
- for (Iterator i = list.iterator(); i.hasNext();) {
- ID graph = (ID) i.next();
- list = (HashSet) containers.get(graph);
- if (list != null) {
- list.remove(containerID);
- if (list.isEmpty())
- containers.remove(graph);
- }
- }
- }
- }
-
- public synchronized boolean contains(ID graph) {
- return containers.containsKey(graph);
- }
-
- public synchronized ID[] getGraphs(ID containerID) {
- HashSet list = (HashSet) graphs.get(containerID);
- return list == null ? NO_GRAPHS : (ID[]) list.toArray(new ID[list
- .size()]);
- }
- }
-
- private final Table table = new Table();
-
- private ISharedObjectConfig config;
-
- public synchronized void add(ID graph) throws ECFException {
- if (config == null)
- throw new ECFException("Not connected.");
-
- ID[] graphs = new ID[] { graph };
- try {
- config.getContext().sendMessage(null,
- new Object[] { new Integer(ADD), graphs });
- } catch (IOException e) {
- throw new ECFException(e);
- }
-
- handleAdd(config.getContext().getLocalContainerID(), graphs);
- }
-
- public synchronized boolean isPublished(ID graph) {
- return table.contains(graph);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.eclipse.ecf.core.ISharedObject#init(org.eclipse.ecf.core.ISharedObjectConfig)
- */
- public synchronized void init(ISharedObjectConfig initData)
- throws SharedObjectInitException {
- if (config == null)
- config = initData;
- else
- throw new SharedObjectInitException("Already initialized.");
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.eclipse.ecf.core.ISharedObject#handleEvent(org.eclipse.ecf.core.util.Event)
- */
- public void handleEvent(Event event) {
- if (event instanceof ISharedObjectMessageEvent) {
- ISharedObjectMessageEvent e = (ISharedObjectMessageEvent) event;
- Object[] data = (Object[]) e.getData();
- Integer type = (Integer) data[0];
- switch (type.intValue()) {
- case JOIN:
- handleJoin(e.getRemoteContainerID(),
- data.length > 1 ? (ID[]) data[1] : null);
- break;
-
- case LEAVE:
- handleLeave(e.getRemoteContainerID());
- break;
-
- case ADD:
- handleAdd(e.getRemoteContainerID(), (ID[]) data[1]);
- break;
-
- case REMOVE:
- handleRemove(e.getRemoteContainerID(), (ID) data[1]);
- }
- } else if (event instanceof ISharedObjectContainerJoinedEvent) {
- if (((ISharedObjectContainerJoinedEvent) event)
- .getJoinedContainerID().equals(
- config.getContext().getLocalContainerID()))
- handleJoined();
- } else if (event instanceof ISharedObjectContainerDepartedEvent) {
- ISharedObjectContainerDepartedEvent e = (ISharedObjectContainerDepartedEvent) event;
- if (!e.getDepartedContainerID().equals(
- config.getContext().getLocalContainerID()))
- handleLeave(e.getDepartedContainerID());
- } else if (event instanceof ISharedObjectActivatedEvent) {
- ISharedObjectActivatedEvent e = (ISharedObjectActivatedEvent) event;
- if (e.getActivatedID().equals(config.getSharedObjectID()))
- handleJoined();
- } else if (event instanceof ISharedObjectDeactivatedEvent) {
- ISharedObjectDeactivatedEvent e = (ISharedObjectDeactivatedEvent) event;
- if (e.getDeactivatedID().equals(config.getSharedObjectID()))
- handleDeactivated();
- else if (table.contains(e.getDeactivatedID()))
- handleRemoved(e.getDeactivatedID());
- }
- }
-
- private void handleJoin(ID containerID, ID[] graphs) {
- if (graphs != null)
- table.add(containerID, graphs);
-
- graphs = table.getGraphs(config.getContext().getLocalContainerID());
- if (graphs.length > 0)
- try {
- config.getContext().sendMessage(containerID,
- new Object[] { new Integer(ADD), graphs });
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
-
- private void handleLeave(ID containerID) {
- table.remove(containerID);
- }
-
- private void handleAdd(ID containerID, ID[] graphs) {
- table.add(containerID, graphs);
- }
-
- private void handleRemove(ID containerID, ID graph) {
- table.remove(containerID, graph);
- }
-
- private void handleJoined() {
- ID[] graphs = table
- .getGraphs(config.getContext().getLocalContainerID());
- Object[] data = graphs.length == 0 ? new Object[] { new Integer(JOIN) }
- : new Object[] { new Integer(JOIN), graphs };
- try {
- config.getContext().sendMessage(null, data);
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
-
- private void handleDeactivated() {
- try {
- config.getContext().sendMessage(null,
- new Object[] { new Integer(LEAVE) });
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
-
- private void handleRemoved(ID graph) {
- try {
- config.getContext().sendMessage(null,
- new Object[] { new Integer(REMOVE), graph });
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
-
- handleRemove(config.getContext().getLocalContainerID(), graph);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.eclipse.ecf.core.ISharedObject#handleEvents(org.eclipse.ecf.core.util.Event[])
- */
- public void handleEvents(Event[] events) {
- for (int i = 0; i < events.length; ++i)
- handleEvent(events[i]);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.eclipse.ecf.core.ISharedObject#dispose(org.eclipse.ecf.core.identity.ID)
- */
- public synchronized void dispose(ID containerID) {
- if (config != null
- && config.getContext().getLocalContainerID()
- .equals(containerID))
- config = null;
- }
+public class PublishedGraphTracker implements ISharedObject {
+
+ private static final ID[] NO_GRAPHS = {};
+
+ private static final int ADD = 0;
+
+ private static final int REMOVE = 1;
+
+ private static final int LEAVE = 2;
+
+ private static final String ARG_TABLE = "table";
+
+ private class Table {
+
+ private final Hashtable graphs = new Hashtable();
+
+ private final Hashtable containers = new Hashtable();
+
+ public synchronized void add(ID containerID, ID graphID) {
+ HashSet list = (HashSet) graphs.get(containerID);
+ if (list == null) {
+ list = new HashSet();
+ graphs.put(containerID, list);
+ }
+
+ list.add(graphID);
+ list = (HashSet) containers.get(containerID);
+ if (list == null) {
+ list = new HashSet();
+ containers.put(graphID, list);
+ }
+
+ list.add(containerID);
+ }
+
+ public synchronized void remove(ID containerID, ID graphID) {
+ HashSet list = (HashSet) graphs.get(containerID);
+ if (list != null) {
+ list.remove(graphID);
+ if (list.isEmpty())
+ graphs.remove(containerID);
+ }
+
+ list = (HashSet) containers.get(graphID);
+ if (list != null) {
+ list.remove(containerID);
+ if (list.isEmpty())
+ containers.remove(graphID);
+ }
+ }
+
+ public synchronized void remove(ID containerID) {
+ HashSet list = (HashSet) graphs.get(containerID);
+ if (list != null) {
+ for (Iterator i = list.iterator(); i.hasNext();) {
+ ID graphID = (ID) i.next();
+ list = (HashSet) containers.get(graphID);
+ if (list != null) {
+ list.remove(containerID);
+ if (list.isEmpty())
+ containers.remove(graphID);
+ }
+ }
+ }
+ }
+
+ public synchronized boolean contains(ID graphID) {
+ return containers.containsKey(graphID);
+ }
+
+ public synchronized ID[] getGraphs(ID containerID) {
+ HashSet list = (HashSet) graphs.get(containerID);
+ return list == null ? NO_GRAPHS : (ID[]) list.toArray(new ID[list
+ .size()]);
+ }
+
+ public synchronized Object createMemento() {
+ return new Hashtable[] { graphs, containers };
+ }
+
+ public synchronized void load(Object memento) {
+ Hashtable[] tables = (Hashtable[]) memento;
+ graphs.putAll(tables[0]);
+ containers.putAll(tables[1]);
+ }
+ }
+
+ private final Table table = new Table();
+
+ private ISharedObjectConfig config;
+
+ private ISharedObjectContext context;
+
+ private final Object activationMutex = new Object();
+
+ private boolean activated;
+
+ /**
+ * Adds a graph to the list of published graphs.
+ *
+ * @param graphID
+ * identifier of the graph that was published
+ * @throws ECFException
+ */
+ public synchronized void add(ID graphID) throws ECFException {
+ if (config == null)
+ throw new ECFException("Not initialized.");
+
+ // wait to be activated before proceeding
+ synchronized (activationMutex) {
+ if (!activated)
+ try {
+ activationMutex.wait(1000);
+ } catch (InterruptedException e) {
+ throw new ECFException(e);
+ }
+
+ if (!activated)
+ throw new ECFException("Not activated.");
+ }
+
+ // tell everyone a graph was published
+ try {
+ getContext().sendMessage(null,
+ new Object[] { new Integer(ADD), graphID });
+ } catch (IOException e) {
+ throw new ECFException(e);
+ }
+
+ // track it yourself
+ handleAdd(getContext().getLocalContainerID(), graphID);
+ }
+
+ /**
+ * Answers whether a graph is published (at the time of invocation).
+ *
+ * @param graphID
+ * identifier of the graph whose publishing status to return
+ * @return <code>true</code> if the graph is published
+ */
+ public synchronized boolean isPublished(ID graphID) {
+ return table.contains(graphID);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ecf.core.ISharedObject#init(org.eclipse.ecf.core.ISharedObjectConfig)
+ */
+ public synchronized void init(ISharedObjectConfig initData)
+ throws SharedObjectInitException {
+ if (config == null)
+ config = initData;
+ else
+ throw new SharedObjectInitException("Already initialized.");
+
+ Map props = (Map) config.getProperties();
+ if (props != null) {
+ Object memento = props.get(ARG_TABLE);
+ if (memento != null)
+ table.load(memento);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ecf.core.ISharedObject#handleEvent(org.eclipse.ecf.core.util.Event)
+ */
+ public void handleEvent(Event event) {
+ if (event instanceof ISharedObjectMessageEvent) {
+ // track graph additions/removals and peer departures
+ // (deactivations)
+ ISharedObjectMessageEvent e = (ISharedObjectMessageEvent) event;
+ Object[] data = (Object[]) e.getData();
+ Integer type = (Integer) data[0];
+ switch (type.intValue()) {
+ case ADD:
+ handleAdd(e.getRemoteContainerID(), (ID) data[1]);
+ break;
+
+ case REMOVE:
+ handleRemove(e.getRemoteContainerID(), (ID) data[1]);
+ break;
+
+ case LEAVE:
+ handleLeave(e.getRemoteContainerID());
+ break;
+ }
+ } else if (event instanceof ISharedObjectContainerJoinedEvent) {
+ ISharedObjectContainerJoinedEvent e = (ISharedObjectContainerJoinedEvent) event;
+ if (e.getJoinedContainerID().equals(
+ getContext().getLocalContainerID()))
+ // this container joined
+ handleJoined();
+ else if (getContext().isGroupServer())
+ // some other container joined and we're the server
+ handleJoined(e.getJoinedContainerID());
+ } else if (event instanceof ISharedObjectContainerDepartedEvent) {
+ ISharedObjectContainerDepartedEvent e = (ISharedObjectContainerDepartedEvent) event;
+ // some other container departed -- same as peer deactivation
+ if (!e.getDepartedContainerID().equals(
+ getContext().getLocalContainerID()))
+ handleLeave(e.getDepartedContainerID());
+ } else if (event instanceof ISharedObjectActivatedEvent) {
+ ISharedObjectActivatedEvent e = (ISharedObjectActivatedEvent) event;
+ if (e.getActivatedID().equals(config.getSharedObjectID()))
+ // we're being activated
+ handleActivated();
+ } else if (event instanceof ISharedObjectDeactivatedEvent) {
+ ISharedObjectDeactivatedEvent e = (ISharedObjectDeactivatedEvent) event;
+ if (e.getDeactivatedID().equals(config.getSharedObjectID()))
+ // we're being deactivated
+ handleDeactivated();
+ else if (table.contains(e.getDeactivatedID()))
+ // a local graph we track is being deactivated
+ handleRemoved(e.getDeactivatedID());
+ }
+ }
+
+ private void handleAdd(ID containerID, ID graphID) {
+ table.add(containerID, graphID);
+ }
+
+ private void handleRemove(ID containerID, ID graphID) {
+ table.remove(containerID, graphID);
+ }
+
+ private void handleLeave(ID containerID) {
+ table.remove(containerID);
+ }
+
+ private void handleJoined() {
+ if (config.getHomeContainerID().equals(
+ getContext().getLocalContainerID())) {
+ // we're the primary copy -- replicate everywhere
+ try {
+ getContext().sendCreate(
+ null,
+ new SharedObjectDescription(config.getSharedObjectID(),
+ getClass()));
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ }
+
+ private void handleJoined(ID containerID) {
+ Map props = new HashMap(1);
+ props.put(ARG_TABLE, table.createMemento());
+ try {
+ getContext().sendCreate(
+ containerID,
+ new SharedObjectDescription(config.getSharedObjectID(),
+ getClass(), props));
+ } catch (IOException ex) {
+ // TODO Auto-generated catch block
+ ex.printStackTrace();
+ }
+ }
+
+ private void handleActivated() {
+ handleJoined();
+ synchronized (activationMutex) {
+ activated = true;
+ activationMutex.notifyAll();
+ }
+ }
+
+ private void handleDeactivated() {
+ try {
+ getContext().sendMessage(null, new Object[] { new Integer(LEAVE) });
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ synchronized (activationMutex) {
+ activated = false;
+ activationMutex.notifyAll();
+ }
+ }
+
+ private void handleRemoved(ID graphID) {
+ try {
+ getContext().sendMessage(null,
+ new Object[] { new Integer(REMOVE), graphID });
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ handleRemove(getContext().getLocalContainerID(), graphID);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ecf.core.ISharedObject#handleEvents(org.eclipse.ecf.core.util.Event[])
+ */
+ public void handleEvents(Event[] events) {
+ for (int i = 0; i < events.length; ++i)
+ handleEvent(events[i]);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ecf.core.ISharedObject#dispose(org.eclipse.ecf.core.identity.ID)
+ */
+ public synchronized void dispose(ID containerID) {
+ config = null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.core.runtime.PlatformObject#getAdapter(java.lang.Class)
+ */
+ public Object getAdapter(Class adapter) {
+ return null;
+ }
+
+ private ISharedObjectContext getContext() {
+ if (context == null)
+ context = config.getContext();
+
+ return context;
+ }
}
diff --git a/examples/bundles/org.eclipse.ecf.example.sdo.editor/src/org/eclipse/ecf/example/sdo/editor/SharedSDOEditor.java b/examples/bundles/org.eclipse.ecf.example.sdo.editor/src/org/eclipse/ecf/example/sdo/editor/SharedSDOEditor.java
index e5758874a..67e1e1804 100644
--- a/examples/bundles/org.eclipse.ecf.example.sdo.editor/src/org/eclipse/ecf/example/sdo/editor/SharedSDOEditor.java
+++ b/examples/bundles/org.eclipse.ecf.example.sdo.editor/src/org/eclipse/ecf/example/sdo/editor/SharedSDOEditor.java
@@ -17,7 +17,6 @@ import org.eclipse.ecf.core.identity.ID;
import org.eclipse.ecf.core.util.ECFException;
import org.eclipse.ecf.sdo.ISharedDataGraph;
import org.eclipse.ecf.sdo.IUpdateConsumer;
-import org.eclipse.ecf.sdo.WaitableSubscriptionCallback;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.sdo.EDataGraph;
@@ -32,104 +31,86 @@ import commonj.sdo.DataGraph;
*/
public class SharedSDOEditor extends SDOEditor {
- private class UpdateConsumer implements IUpdateConsumer {
- public boolean consumeUpdate(ISharedDataGraph graph, ID containerID) {
- ChangeSummary changeSummary = graph.getDataGraph()
- .getChangeSummary();
- changeSummary.endLogging();
- SharedSDOEditor.super.doSave(null);
- changeSummary.beginLogging();
- return true;
- }
+ private class UpdateConsumer implements IUpdateConsumer {
+ public boolean consumeUpdate(ISharedDataGraph graph, ID containerID) {
+ ChangeSummary changeSummary = graph.getDataGraph()
+ .getChangeSummary();
+ changeSummary.endLogging();
+ SharedSDOEditor.super.doSave(null);
+ changeSummary.beginLogging();
+ return true;
+ }
- public void updateFailed(ISharedDataGraph graph, ID containerID,
- Throwable cause) {
- EditorPlugin.getDefault().log(
- new CoreException(new Status(Status.ERROR, EditorPlugin
- .getDefault().getBundle().getSymbolicName(), 0,
- "Data graph upate failed.", cause)));
- }
- }
+ public void updateFailed(ISharedDataGraph graph, ID containerID,
+ Throwable cause) {
+ EditorPlugin.getDefault().log(
+ new CoreException(new Status(Status.ERROR, EditorPlugin
+ .getDefault().getBundle().getSymbolicName(), 0,
+ "Data graph upate failed.", cause)));
+ }
+ }
- private ISharedDataGraph sharedDataGraph;
+ private ISharedDataGraph sharedDataGraph;
- /*
- * (non-Javadoc)
- *
- * @see org.eclipse.emf.ecore.sdo.presentation.SDOEditor#createModel()
- */
- public void createModel() {
- try {
- IFileEditorInput modelFile = (IFileEditorInput) getEditorInput();
- String path = modelFile.getFile().getFullPath().toString();
- URI uri = URI.createPlatformResourceURI(modelFile.getFile()
- .getFullPath().toString());
- if (EditorPlugin.getDefault().isPublished(path)) {
- WaitableSubscriptionCallback mutex = new WaitableSubscriptionCallback();
- sharedDataGraph = EditorPlugin.getDefault().subscribe(path,
- mutex, new UpdateConsumer());
- ID containerID = null;
- Throwable cause = null;
- try {
- containerID = mutex.waitForSubscription(10000);
- } catch (InterruptedException e) {
- cause = e;
- }
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.emf.ecore.sdo.presentation.SDOEditor#createModel()
+ */
+ public void createModel() {
+ try {
+ IFileEditorInput modelFile = (IFileEditorInput) getEditorInput();
+ String path = modelFile.getFile().getFullPath().toString();
+ URI uri = URI.createPlatformResourceURI(modelFile.getFile()
+ .getFullPath().toString());
+ if (EditorPlugin.getDefault().isPublished(path)) {
+ sharedDataGraph = EditorPlugin.getDefault().subscribe(path,
+ new UpdateConsumer());
+ EDataGraph dataGraph = (EDataGraph) sharedDataGraph
+ .getDataGraph();
+ dataGraph.getDataGraphResource().setURI(uri);
+ editingDomain.getResourceSet().getResources().addAll(
+ dataGraph.getResourceSet().getResources());
+ dataGraph.setResourceSet(editingDomain.getResourceSet());
+ } else {
+ Resource resource = editingDomain.loadResource(uri.toString());
+ DataGraph dataGraph = (DataGraph) resource.getContents().get(0);
+ sharedDataGraph = EditorPlugin.getDefault().publish(path,
+ dataGraph, new UpdateConsumer());
+ }
+ } catch (ECFException e) {
+ EditorPlugin.getDefault().log(e);
+ if (sharedDataGraph != null) {
+ sharedDataGraph.dispose();
+ sharedDataGraph = null;
+ }
+ }
+ }
- if (containerID == null) {
- EditorPlugin.getDefault().log(
- new CoreException(new Status(Status.ERROR,
- EditorPlugin.getDefault().getBundle()
- .getSymbolicName(), 0,
- "Failed to subscribe.", cause)));
- return;
- }
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.emf.ecore.sdo.presentation.SDOEditor#doSave(org.eclipse.core.runtime.IProgressMonitor)
+ */
+ public void doSave(IProgressMonitor progressMonitor) {
+ super.doSave(progressMonitor);
+ if (sharedDataGraph != null)
+ try {
+ sharedDataGraph.commit();
+ } catch (ECFException e) {
+ EditorPlugin.getDefault().log(e);
+ }
+ }
- EDataGraph dataGraph = (EDataGraph) sharedDataGraph
- .getDataGraph();
- dataGraph.getDataGraphResource().setURI(uri);
- editingDomain.getResourceSet().getResources().addAll(
- dataGraph.getResourceSet().getResources());
- dataGraph.setResourceSet(editingDomain.getResourceSet());
- } else {
- Resource resource = editingDomain.loadResource(uri.toString());
- DataGraph dataGraph = (DataGraph) resource.getContents().get(0);
- sharedDataGraph = EditorPlugin.getDefault().publish(path,
- dataGraph, new UpdateConsumer());
- }
- } catch (ECFException e) {
- EditorPlugin.getDefault().log(e);
- if (sharedDataGraph != null) {
- sharedDataGraph.dispose();
- sharedDataGraph = null;
- }
- }
- }
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.emf.ecore.sdo.presentation.SDOEditor#dispose()
+ */
+ public void dispose() {
+ if (sharedDataGraph != null)
+ sharedDataGraph.dispose();
- /*
- * (non-Javadoc)
- *
- * @see org.eclipse.emf.ecore.sdo.presentation.SDOEditor#doSave(org.eclipse.core.runtime.IProgressMonitor)
- */
- public void doSave(IProgressMonitor progressMonitor) {
- super.doSave(progressMonitor);
- if (sharedDataGraph != null)
- try {
- sharedDataGraph.commit();
- } catch (ECFException e) {
- EditorPlugin.getDefault().log(e);
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.eclipse.emf.ecore.sdo.presentation.SDOEditor#dispose()
- */
- public void dispose() {
- if (sharedDataGraph != null)
- sharedDataGraph.dispose();
-
- super.dispose();
- }
+ super.dispose();
+ }
} \ No newline at end of file
diff --git a/examples/bundles/org.eclipse.ecf.sdo/src/org/eclipse/ecf/internal/sdo/DataGraphSharing.java b/examples/bundles/org.eclipse.ecf.sdo/src/org/eclipse/ecf/internal/sdo/DataGraphSharing.java
index fadf0cd58..d1dcf55c5 100644
--- a/examples/bundles/org.eclipse.ecf.sdo/src/org/eclipse/ecf/internal/sdo/DataGraphSharing.java
+++ b/examples/bundles/org.eclipse.ecf.sdo/src/org/eclipse/ecf/internal/sdo/DataGraphSharing.java
@@ -19,6 +19,7 @@ import org.eclipse.ecf.core.identity.ID;
import org.eclipse.ecf.core.util.ECFException;
import org.eclipse.ecf.core.util.Event;
import org.eclipse.ecf.sdo.IDataGraphSharing;
+import org.eclipse.ecf.sdo.IPublicationCallback;
import org.eclipse.ecf.sdo.ISharedDataGraph;
import org.eclipse.ecf.sdo.ISubscriptionCallback;
import org.eclipse.ecf.sdo.IUpdateConsumer;
@@ -45,11 +46,12 @@ public class DataGraphSharing extends PlatformObject implements
* @see org.eclipse.ecf.sdo.IDataGraphSharing#publish(commonj.sdo.DataGraph,
* org.eclipse.ecf.core.identity.ID,
* org.eclipse.ecf.sdo.IUpdateProvider,
- * org.eclipse.ecf.sdo.IUpdateConsumer)
+ * org.eclipse.ecf.sdo.IUpdateConsumer,
+ * org.eclipse.ecf.sdo.IPublicationCallback)
*/
public synchronized ISharedDataGraph publish(DataGraph dataGraph, ID id,
- IUpdateProvider provider, IUpdateConsumer consumer)
- throws ECFException {
+ IUpdateProvider provider, IUpdateConsumer consumer,
+ IPublicationCallback callback) throws ECFException {
if (config == null)
throw new ECFException("Not initialized.");
@@ -57,7 +59,7 @@ public class DataGraphSharing extends PlatformObject implements
// create local object
ISharedObjectManager mgr = config.getContext().getSharedObjectManager();
SharedDataGraph sdg = new SharedDataGraph(dataGraph, provider,
- consumer, null);
+ consumer, callback, null);
sdg.setDebug(debug);
mgr.addSharedObject(id, sdg, null, null);
@@ -73,8 +75,8 @@ public class DataGraphSharing extends PlatformObject implements
* org.eclipse.ecf.sdo.IUpdateConsumer)
*/
public synchronized ISharedDataGraph subscribe(ID id,
- ISubscriptionCallback callback, IUpdateProvider provider,
- IUpdateConsumer consumer) throws ECFException {
+ IUpdateProvider provider, IUpdateConsumer consumer,
+ ISubscriptionCallback callback) throws ECFException {
if (config == null)
throw new ECFException("Not initialized.");
@@ -82,7 +84,7 @@ public class DataGraphSharing extends PlatformObject implements
// create local object
ISharedObjectManager mgr = config.getContext().getSharedObjectManager();
SharedDataGraph sdg = new SharedDataGraph(null, provider, consumer,
- callback);
+ null, callback);
sdg.setDebug(debug);
mgr.addSharedObject(id, sdg, null, null);
diff --git a/examples/bundles/org.eclipse.ecf.sdo/src/org/eclipse/ecf/internal/sdo/SharedDataGraph.java b/examples/bundles/org.eclipse.ecf.sdo/src/org/eclipse/ecf/internal/sdo/SharedDataGraph.java
index 6f50b5bd6..870c0ea9b 100644
--- a/examples/bundles/org.eclipse.ecf.sdo/src/org/eclipse/ecf/internal/sdo/SharedDataGraph.java
+++ b/examples/bundles/org.eclipse.ecf.sdo/src/org/eclipse/ecf/internal/sdo/SharedDataGraph.java
@@ -22,6 +22,7 @@ import org.eclipse.ecf.core.events.ISharedObjectMessageEvent;
import org.eclipse.ecf.core.identity.ID;
import org.eclipse.ecf.core.util.ECFException;
import org.eclipse.ecf.core.util.Event;
+import org.eclipse.ecf.sdo.IPublicationCallback;
import org.eclipse.ecf.sdo.ISharedDataGraph;
import org.eclipse.ecf.sdo.ISubscriptionCallback;
import org.eclipse.ecf.sdo.IUpdateConsumer;
@@ -40,6 +41,8 @@ public class SharedDataGraph extends PlatformObject implements ISharedObject,
private final ISubscriptionCallback subscriptionCallback;
+ private final IPublicationCallback publicationCallback;
+
private final IUpdateProvider updateProvider;
private ISharedObjectConfig config;
@@ -52,6 +55,7 @@ public class SharedDataGraph extends PlatformObject implements ISharedObject,
SharedDataGraph(DataGraph dataGraph, IUpdateProvider updateProvider,
IUpdateConsumer updateConsumer,
+ IPublicationCallback publicationCallback,
ISubscriptionCallback subscriptionCallback) {
if (updateProvider == null)
throw new IllegalArgumentException("updateProvider");
@@ -62,6 +66,7 @@ public class SharedDataGraph extends PlatformObject implements ISharedObject,
this.dataGraph = dataGraph;
this.updateProvider = updateProvider;
this.updateConsumer = updateConsumer;
+ this.publicationCallback = publicationCallback;
this.subscriptionCallback = subscriptionCallback;
}
@@ -138,6 +143,12 @@ public class SharedDataGraph extends PlatformObject implements ISharedObject,
config = initData;
else
throw new SharedObjectInitException("Already initialized.");
+
+ if (version == null)
+ version = new Version(config.getSharedObjectID());
+
+ if (dataGraph != null)
+ dataGraph.getChangeSummary().beginLogging();
}
/*
@@ -158,12 +169,8 @@ public class SharedDataGraph extends PlatformObject implements ISharedObject,
if (subscriptionCallback != null)
subscriptionCallback.subscriptionFailed(this, e);
}
- } else {
- if (version == null)
- version = new Version(config.getSharedObjectID());
-
- dataGraph.getChangeSummary().beginLogging();
- }
+ } else if (publicationCallback != null)
+ publicationCallback.dataGraphPublished(this);
}
} else if (event instanceof ISharedObjectDeactivatedEvent
&& ((ISharedObjectDeactivatedEvent) event).getDeactivatedID()
diff --git a/examples/bundles/org.eclipse.ecf.sdo/src/org/eclipse/ecf/sdo/IDataGraphSharing.java b/examples/bundles/org.eclipse.ecf.sdo/src/org/eclipse/ecf/sdo/IDataGraphSharing.java
index 451fb7a52..8fe8faa69 100644
--- a/examples/bundles/org.eclipse.ecf.sdo/src/org/eclipse/ecf/sdo/IDataGraphSharing.java
+++ b/examples/bundles/org.eclipse.ecf.sdo/src/org/eclipse/ecf/sdo/IDataGraphSharing.java
@@ -36,31 +36,35 @@ public interface IDataGraphSharing {
* implementation
* @param consumer
* application-specific update consumer
+ * @param callback
+ * optional callback used to notify the caller about publication
+ * status
* @return shared data graph
* @throws ECFException
*/
ISharedDataGraph publish(DataGraph dataGraph, ID id,
- IUpdateProvider provider, IUpdateConsumer consumer)
- throws ECFException;
+ IUpdateProvider provider, IUpdateConsumer consumer,
+ IPublicationCallback callback) throws ECFException;
/**
* Subscribes to a data graph with the given id.
*
* @param id
* identifier of a previously-published data graph
- * @param callback
- * optional callback used to notify the caller about subscription
- * status
* @param provider
* update provider compatible with the given data graph's
* implementation
* @param consumer
* application-specific update consumer
+ * @param callback
+ * optional callback used to notify the caller about subscription
+ * status
+ *
* @return shared data graph
* @throws ECFException
*/
- ISharedDataGraph subscribe(ID id, ISubscriptionCallback callback,
- IUpdateProvider provider, IUpdateConsumer consumer)
+ ISharedDataGraph subscribe(ID id, IUpdateProvider provider,
+ IUpdateConsumer consumer, ISubscriptionCallback callback)
throws ECFException;
/**
diff --git a/examples/bundles/org.eclipse.ecf.sdo/src/org/eclipse/ecf/sdo/IPublicationCallback.java b/examples/bundles/org.eclipse.ecf.sdo/src/org/eclipse/ecf/sdo/IPublicationCallback.java
new file mode 100644
index 000000000..6c3068c56
--- /dev/null
+++ b/examples/bundles/org.eclipse.ecf.sdo/src/org/eclipse/ecf/sdo/IPublicationCallback.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2004 Peter Nehrer and Composent, Inc.
+ * 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:
+ * Peter Nehrer - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ecf.sdo;
+
+/**
+ * Interface used by service implementations to notify publishing applications
+ * of the publication status.
+ *
+ * @author pnehrer
+ */
+public interface IPublicationCallback {
+
+ /**
+ * Notifies implementor that the give data graph has been successfully
+ * published.
+ *
+ * @param graph
+ * data graph that has been published
+ */
+ void dataGraphPublished(ISharedDataGraph graph);
+}
diff --git a/examples/bundles/org.eclipse.ecf.sdo/src/org/eclipse/ecf/sdo/WaitablePublicationCallback.java b/examples/bundles/org.eclipse.ecf.sdo/src/org/eclipse/ecf/sdo/WaitablePublicationCallback.java
new file mode 100644
index 000000000..5c9d0a7c5
--- /dev/null
+++ b/examples/bundles/org.eclipse.ecf.sdo/src/org/eclipse/ecf/sdo/WaitablePublicationCallback.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2004 Peter Nehrer and Composent, Inc.
+ * 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:
+ * Peter Nehrer - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ecf.sdo;
+
+/**
+ * Convenience callback implementation that can be used to block the calling
+ * thread until the data graph is published.
+ *
+ * @author pnehrer
+ */
+public class WaitablePublicationCallback implements IPublicationCallback {
+
+ private boolean published;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ecf.sdo.IPublicationCallback#dataGraphPublished(org.eclipse.ecf.sdo.ISharedDataGraph)
+ */
+ public synchronized void dataGraphPublished(ISharedDataGraph graph) {
+ published = true;
+ notifyAll();
+ }
+
+ /**
+ * Blocks the calling thread until the data graph is published.
+ *
+ * @param timeout
+ * period, in milliseconds, to wait for publication
+ * @throws InterruptedException
+ * if interrupted while waiting for notification
+ */
+ public synchronized boolean waitForPublication(long timeout)
+ throws InterruptedException {
+ if (!published)
+ wait(timeout);
+
+ return published;
+ }
+}

Back to the top