Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpnehrer2006-07-05 02:11:18 +0000
committerpnehrer2006-07-05 02:11:18 +0000
commitac7782c0e2e05c8e41ba662c98fe5cd88cc9f612 (patch)
tree5645f0b7fe00af876a782a67c4ad6c173064439f /examples/bundles/org.eclipse.ecf.example.pubsub
parentb7547bc2af999d6982bab3fc0ab91dfa07499f87 (diff)
downloadorg.eclipse.ecf-ac7782c0e2e05c8e41ba662c98fe5cd88cc9f612.tar.gz
org.eclipse.ecf-ac7782c0e2e05c8e41ba662c98fe5cd88cc9f612.tar.xz
org.eclipse.ecf-ac7782c0e2e05c8e41ba662c98fe5cd88cc9f612.zip
Initial check-in.
Diffstat (limited to 'examples/bundles/org.eclipse.ecf.example.pubsub')
-rw-r--r--examples/bundles/org.eclipse.ecf.example.pubsub/.classpath7
-rw-r--r--examples/bundles/org.eclipse.ecf.example.pubsub/.project28
-rw-r--r--examples/bundles/org.eclipse.ecf.example.pubsub/.settings/org.eclipse.jdt.core.prefs7
-rw-r--r--examples/bundles/org.eclipse.ecf.example.pubsub/META-INF/MANIFEST.MF18
-rw-r--r--examples/bundles/org.eclipse.ecf.example.pubsub/build.properties5
-rw-r--r--examples/bundles/org.eclipse.ecf.example.pubsub/plugin.xml33
-rw-r--r--examples/bundles/org.eclipse.ecf.example.pubsub/schema/modelUpdater.exsd117
-rw-r--r--examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/example/pubsub/Activator.java60
-rw-r--r--examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/example/pubsub/AppendableList.java75
-rw-r--r--examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/example/pubsub/IAppendableListListener.java16
-rw-r--r--examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/example/pubsub/ListAppender.java22
-rw-r--r--examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/example/pubsub/PubSubView.java270
-rw-r--r--examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/example/pubsub/SubscriptionView.java81
-rw-r--r--examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/IPublishedService.java25
-rw-r--r--examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/IPublishedServiceDirectory.java18
-rw-r--r--examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/IPublishedServiceDirectoryListener.java16
-rw-r--r--examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/IPublishedServiceRequestor.java18
-rw-r--r--examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/ISubscription.java21
-rw-r--r--examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/ISubscriptionCallback.java18
-rw-r--r--examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/PublishedServiceDescriptor.java75
-rw-r--r--examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/PublishedServiceDirectoryChangeEvent.java67
-rw-r--r--examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/impl/DiscoveryAgent.java227
-rw-r--r--examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/impl/DiscoveryMessage.java67
-rw-r--r--examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/impl/PubSubAdapterFactory.java78
-rw-r--r--examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/impl/PublishedServiceDirectory.java189
-rw-r--r--examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/impl/ReplicatedServiceDiscoveryEvent.java71
-rw-r--r--examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/impl/ServiceRequestor.java60
-rw-r--r--examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/impl/SubscriptionAgent.java213
-rw-r--r--examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/model/IMasterModel.java20
-rw-r--r--examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/model/IModelUpdater.java16
-rw-r--r--examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/model/IReplicaModel.java16
-rw-r--r--examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/model/SharedModelFactory.java90
-rw-r--r--examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/model/impl/AgentBase.java158
-rw-r--r--examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/model/impl/LocalAgent.java65
-rw-r--r--examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/model/impl/RemoteAgent.java34
35 files changed, 2301 insertions, 0 deletions
diff --git a/examples/bundles/org.eclipse.ecf.example.pubsub/.classpath b/examples/bundles/org.eclipse.ecf.example.pubsub/.classpath
new file mode 100644
index 000000000..ce7393340
--- /dev/null
+++ b/examples/bundles/org.eclipse.ecf.example.pubsub/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.4"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/examples/bundles/org.eclipse.ecf.example.pubsub/.project b/examples/bundles/org.eclipse.ecf.example.pubsub/.project
new file mode 100644
index 000000000..66b4c8d19
--- /dev/null
+++ b/examples/bundles/org.eclipse.ecf.example.pubsub/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.ecf.example.pubsub</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/examples/bundles/org.eclipse.ecf.example.pubsub/.settings/org.eclipse.jdt.core.prefs b/examples/bundles/org.eclipse.ecf.example.pubsub/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 000000000..c330295c3
--- /dev/null
+++ b/examples/bundles/org.eclipse.ecf.example.pubsub/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+#Tue Jul 04 17:05:21 EDT 2006
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.2
+org.eclipse.jdt.core.compiler.compliance=1.4
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=warning
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=warning
+org.eclipse.jdt.core.compiler.source=1.3
diff --git a/examples/bundles/org.eclipse.ecf.example.pubsub/META-INF/MANIFEST.MF b/examples/bundles/org.eclipse.ecf.example.pubsub/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..b538315b3
--- /dev/null
+++ b/examples/bundles/org.eclipse.ecf.example.pubsub/META-INF/MANIFEST.MF
@@ -0,0 +1,18 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: ECF Publish/Subscribe Example Plug-in
+Bundle-SymbolicName: org.eclipse.ecf.example.pubsub;singleton:=true
+Bundle-Version: 1.0.0
+Bundle-Activator: org.eclipse.ecf.example.pubsub.Activator
+Bundle-Vendor: Eclipse.org
+Bundle-Localization: plugin
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.core.runtime,
+ org.eclipse.ecf;visibility:=reexport
+Eclipse-AutoStart: true
+Bundle-RequiredExecutionEnvironment: J2SE-1.4
+Export-Package: org.eclipse.ecf.example.pubsub,
+ org.eclipse.ecf.pubsub,
+ org.eclipse.ecf.pubsub.impl,
+ org.eclipse.ecf.pubsub.model,
+ org.eclipse.ecf.pubsub.model.impl
diff --git a/examples/bundles/org.eclipse.ecf.example.pubsub/build.properties b/examples/bundles/org.eclipse.ecf.example.pubsub/build.properties
new file mode 100644
index 000000000..e9863e281
--- /dev/null
+++ b/examples/bundles/org.eclipse.ecf.example.pubsub/build.properties
@@ -0,0 +1,5 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.xml
diff --git a/examples/bundles/org.eclipse.ecf.example.pubsub/plugin.xml b/examples/bundles/org.eclipse.ecf.example.pubsub/plugin.xml
new file mode 100644
index 000000000..4cc481889
--- /dev/null
+++ b/examples/bundles/org.eclipse.ecf.example.pubsub/plugin.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.2"?>
+<plugin>
+ <extension-point id="modelUpdater" name="Shared Model Updater" schema="schema/modelUpdater.exsd"/>
+ <extension
+ point="org.eclipse.core.runtime.adapters">
+ <factory
+ adaptableType="org.eclipse.ecf.core.ISharedObjectContainer"
+ class="org.eclipse.ecf.pubsub.impl.PubSubAdapterFactory">
+ <adapter type="org.eclipse.ecf.pubsub.IPublishedServiceDirectory"/>
+ <adapter type="org.eclipse.ecf.pubsub.IPublishedServiceRequestor"/>
+ </factory>
+ </extension>
+ <extension
+ point="org.eclipse.ui.views">
+ <view
+ class="org.eclipse.ecf.example.pubsub.PubSubView"
+ id="org.eclipse.ecf.example.pubsub.publications"
+ name="Published Services"/>
+ <view
+ allowMultiple="true"
+ class="org.eclipse.ecf.example.pubsub.SubscriptionView"
+ id="org.eclipse.ecf.example.pubsub.subscription"
+ name="Subscription"/>
+ </extension>
+ <extension
+ point="org.eclipse.ecf.example.pubsub.modelUpdater">
+ <modelUpdater
+ class="org.eclipse.ecf.example.pubsub.ListAppender"
+ id="org.eclipse.ecf.example.pubsub.ListAppender"/>
+ </extension>
+
+</plugin>
diff --git a/examples/bundles/org.eclipse.ecf.example.pubsub/schema/modelUpdater.exsd b/examples/bundles/org.eclipse.ecf.example.pubsub/schema/modelUpdater.exsd
new file mode 100644
index 000000000..73a13909a
--- /dev/null
+++ b/examples/bundles/org.eclipse.ecf.example.pubsub/schema/modelUpdater.exsd
@@ -0,0 +1,117 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.ecf.example.pubsub">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.ecf.example.pubsub" id="modelUpdater" name="Shared Model Updater"/>
+ </appInfo>
+ <documentation>
+ [Enter description of this extension point.]
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <complexType>
+ <sequence>
+ <element ref="modelUpdater" minOccurs="1" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="modelUpdater">
+ <annotation>
+ <appInfo>
+ <meta.element labelAttribute="id"/>
+ </appInfo>
+ </annotation>
+ <complexType>
+ <attribute name="id" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn="org.eclipse.ecf.example.pubsub.IModelUpdater"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ [Enter the first release in which this extension point appears.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ [Enter extension point usage example here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiInfo"/>
+ </appInfo>
+ <documentation>
+ [Enter API information here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ [Enter information about supplied implementation of this extension point.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/example/pubsub/Activator.java b/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/example/pubsub/Activator.java
new file mode 100644
index 000000000..643da6e8d
--- /dev/null
+++ b/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/example/pubsub/Activator.java
@@ -0,0 +1,60 @@
+/**
+ * Copyright (c) 2006 Ecliptical Software 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:
+ * Ecliptical Software Inc. - initial API and implementation
+ */
+package org.eclipse.ecf.example.pubsub;
+
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class Activator extends AbstractUIPlugin {
+
+ // The plug-in ID
+ public static final String PLUGIN_ID = "org.eclipse.ecf.example.pubsub";
+
+ // The shared instance
+ private static Activator plugin;
+
+ /**
+ * The constructor
+ */
+ public Activator() {
+ plugin = this;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+ */
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+ */
+ public void stop(BundleContext context) throws Exception {
+ plugin = null;
+ super.stop(context);
+ }
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static Activator getDefault() {
+ return plugin;
+ }
+
+}
diff --git a/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/example/pubsub/AppendableList.java b/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/example/pubsub/AppendableList.java
new file mode 100644
index 000000000..b164487c7
--- /dev/null
+++ b/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/example/pubsub/AppendableList.java
@@ -0,0 +1,75 @@
+/**
+ * Copyright (c) 2006 Ecliptical Software 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:
+ * Ecliptical Software Inc. - initial API and implementation
+ */
+package org.eclipse.ecf.example.pubsub;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.ISafeRunnable;
+import org.eclipse.core.runtime.ListenerList;
+import org.eclipse.core.runtime.SafeRunner;
+
+public class AppendableList implements Serializable {
+
+ private static final long serialVersionUID = -5447897626712251185L;
+
+ private transient ListenerList listeners;
+
+ protected final List values = new ArrayList();
+
+ public void addListener(IAppendableListListener listener) {
+ getListenerList().add(listener);
+ }
+
+ public void removeListener(IAppendableListListener listener) {
+ getListenerList().remove(listener);
+ }
+
+ protected void fireAppended(final Object value) {
+ Object[] l = getListenerList().getListeners();
+ for (int i = 0; i < l.length; ++i) {
+ final IAppendableListListener listener = (IAppendableListListener) l[i];
+ SafeRunner.run(new ISafeRunnable() {
+
+ public void run() throws Exception {
+ listener.appended(AppendableList.this, value);
+ }
+
+ public void handleException(Throwable exception) {
+ // TODO Auto-generated method stub
+
+ }
+ });
+ }
+ }
+
+ protected synchronized ListenerList getListenerList() {
+ if (listeners == null)
+ listeners = new ListenerList();
+
+ return listeners;
+ }
+
+ public synchronized Object[] getValues() {
+ return values.toArray();
+ }
+
+ public synchronized boolean add(Object value) {
+ boolean result = values.add(value);
+ fireAppended(value);
+ return result;
+ }
+
+ public String toString() {
+ return values.toString();
+ }
+}
diff --git a/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/example/pubsub/IAppendableListListener.java b/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/example/pubsub/IAppendableListListener.java
new file mode 100644
index 000000000..57b21e99a
--- /dev/null
+++ b/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/example/pubsub/IAppendableListListener.java
@@ -0,0 +1,16 @@
+/**
+ * Copyright (c) 2006 Ecliptical Software 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:
+ * Ecliptical Software Inc. - initial API and implementation
+ */
+package org.eclipse.ecf.example.pubsub;
+
+public interface IAppendableListListener {
+
+ void appended(AppendableList list, Object value);
+}
diff --git a/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/example/pubsub/ListAppender.java b/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/example/pubsub/ListAppender.java
new file mode 100644
index 000000000..b4f6c6bd0
--- /dev/null
+++ b/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/example/pubsub/ListAppender.java
@@ -0,0 +1,22 @@
+/**
+ * Copyright (c) 2006 Ecliptical Software 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:
+ * Ecliptical Software Inc. - initial API and implementation
+ */
+package org.eclipse.ecf.example.pubsub;
+
+import org.eclipse.ecf.pubsub.model.IModelUpdater;
+
+public class ListAppender implements IModelUpdater {
+
+ public static final String ID = "org.eclipse.ecf.example.pubsub.ListAppender";
+
+ public void update(Object data, Object update) {
+ ((AppendableList) data).add(update);
+ }
+}
diff --git a/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/example/pubsub/PubSubView.java b/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/example/pubsub/PubSubView.java
new file mode 100644
index 000000000..d4e9f9ab2
--- /dev/null
+++ b/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/example/pubsub/PubSubView.java
@@ -0,0 +1,270 @@
+/**
+ * Copyright (c) 2006 Ecliptical Software 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:
+ * Ecliptical Software Inc. - initial API and implementation
+ */
+package org.eclipse.ecf.example.pubsub;
+
+import java.io.IOException;
+import java.util.Vector;
+
+import org.eclipse.ecf.core.ISharedObjectContainer;
+import org.eclipse.ecf.core.SharedObjectContainerFactory;
+import org.eclipse.ecf.core.SharedObjectCreateException;
+import org.eclipse.ecf.core.identity.IDFactory;
+import org.eclipse.ecf.core.identity.IDInstantiationException;
+import org.eclipse.ecf.core.util.ECFException;
+import org.eclipse.ecf.pubsub.IPublishedServiceDirectory;
+import org.eclipse.ecf.pubsub.IPublishedServiceDirectoryListener;
+import org.eclipse.ecf.pubsub.IPublishedServiceRequestor;
+import org.eclipse.ecf.pubsub.ISubscription;
+import org.eclipse.ecf.pubsub.ISubscriptionCallback;
+import org.eclipse.ecf.pubsub.PublishedServiceDescriptor;
+import org.eclipse.ecf.pubsub.PublishedServiceDirectoryChangeEvent;
+import org.eclipse.ecf.pubsub.model.IMasterModel;
+import org.eclipse.ecf.pubsub.model.SharedModelFactory;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.dialogs.InputDialog;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.viewers.ArrayContentProvider;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerSorter;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.ui.IViewSite;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.actions.BaseSelectionListenerAction;
+import org.eclipse.ui.part.ViewPart;
+
+public class PubSubView extends ViewPart {
+
+ protected TableViewer viewer;
+
+ protected MenuManager menuManager;
+
+ protected ISharedObjectContainer container;
+
+ private BaseSelectionListenerAction subscribeAction;
+
+ protected TableViewer sharedListViewer;
+
+ protected MenuManager sharedListMenuManager;
+
+ private BaseSelectionListenerAction appendAction;
+
+ protected final Vector sharedLists = new Vector();
+
+ public void init(IViewSite site) throws PartInitException {
+ super.init(site);
+
+ final Action shareSomethingAction = new Action("Share something...") {
+ public void run() {
+ try {
+ IMasterModel sds = SharedModelFactory.getInstance().createSharedDataSource(container, IDFactory.getDefault().createGUID(), new AppendableList(), ListAppender.ID);
+ if (sds == null)
+ MessageDialog.openError(getSite().getShell(), "Error", "Could not share anything.");
+ else {
+ sharedLists.add(sds);
+ sharedListViewer.add(sds);
+ }
+ } catch (SharedObjectCreateException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (IDInstantiationException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ };
+
+ shareSomethingAction.setEnabled(false);
+
+ IMenuManager mgr = site.getActionBars().getMenuManager();
+ mgr.add(new Action("Connect") {
+ public void run() {
+ try {
+ container = SharedObjectContainerFactory.getDefault().createSharedObjectContainer("ecf.generic.client");
+ container.connect(IDFactory.getDefault().createStringID("ecftcp://localhost:3282/server"), null);
+ IPublishedServiceDirectory directory = (IPublishedServiceDirectory) container.getAdapter(IPublishedServiceDirectory.class);
+ viewer.setInput(directory);
+ setEnabled(false);
+ shareSomethingAction.setEnabled(true);
+ } catch (ECFException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ });
+
+ mgr.add(shareSomethingAction);
+
+ menuManager = new MenuManager();
+ subscribeAction = new BaseSelectionListenerAction("Subscribe") {
+
+ public void run() {
+ PublishedServiceDescriptor desc = (PublishedServiceDescriptor) getStructuredSelection().getFirstElement();
+ IPublishedServiceRequestor requestor = (IPublishedServiceRequestor) container.getAdapter(IPublishedServiceRequestor.class);
+ requestor.subscribe(desc.getContainerID(), desc.getSharedObjectID(), new SubscriptionViewOpener());
+ }
+
+ protected boolean updateSelection(IStructuredSelection selection) {
+ return !selection.isEmpty();
+ }
+ };
+
+ subscribeAction.setEnabled(false);
+ menuManager.add(subscribeAction);
+
+ sharedListMenuManager = new MenuManager();
+ appendAction = new BaseSelectionListenerAction("Append...") {
+
+ public void run() {
+ InputDialog dlg = new InputDialog(getSite().getShell(), "Append to Shared List", "Enter element to append:", null, null);
+ dlg.open();
+ String value = dlg.getValue();
+ if (value != null) {
+ IMasterModel list = (IMasterModel) getStructuredSelection().getFirstElement();
+ try {
+ list.update(value);
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ }
+
+ protected boolean updateSelection(IStructuredSelection selection) {
+ return !selection.isEmpty();
+ }
+ };
+
+ appendAction.setEnabled(false);
+ sharedListMenuManager.add(appendAction);
+ }
+
+ public void createPartControl(Composite parent) {
+ Composite composite = new Composite(parent, SWT.NONE);
+ composite.setLayout(new GridLayout(2, true));
+
+ Label label = new Label(composite, SWT.NONE);
+ label.setText("Remote Shared Services");
+
+ label = new Label(composite, SWT.NONE);
+ label.setText("Local Shared Sample Lists");
+
+ viewer = new TableViewer(composite);
+ viewer.getTable().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ viewer.setUseHashlookup(true);
+ viewer.setLabelProvider(new LabelProvider());
+ viewer.setContentProvider(new ContentProvider());
+ viewer.setSorter(new ViewerSorter());
+ viewer.addSelectionChangedListener(subscribeAction);
+ viewer.getControl().setMenu(menuManager.createContextMenu(viewer.getControl()));
+
+ sharedListViewer = new TableViewer(composite);
+ sharedListViewer.getTable().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ sharedListViewer.setUseHashlookup(true);
+ sharedListViewer.setLabelProvider(new LabelProvider());
+ sharedListViewer.setContentProvider(new ArrayContentProvider());
+ sharedListViewer.addSelectionChangedListener(appendAction);
+ sharedListViewer.getControl().setMenu(sharedListMenuManager.createContextMenu(sharedListViewer.getControl()));
+ }
+
+ public void setFocus() {
+ viewer.getControl().setFocus();
+ }
+
+ public void dispose() {
+ menuManager.dispose();
+
+ if (container != null)
+ container.disconnect();
+
+ super.dispose();
+ }
+
+ protected class ContentProvider implements IStructuredContentProvider, IPublishedServiceDirectoryListener {
+
+ private Viewer viewer;
+
+ public Object[] getElements(Object inputElement) {
+ return new Object[0];
+ }
+
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ this.viewer = viewer;
+
+ if (oldInput instanceof IPublishedServiceDirectory)
+ ((IPublishedServiceDirectory) oldInput).removeReplicatedServiceListener(this);
+
+ if (newInput instanceof IPublishedServiceDirectory)
+ ((IPublishedServiceDirectory) newInput).addReplicatedServiceListener(this);
+ }
+
+ public void dispose() {
+ viewer = null;
+ }
+
+ public void publishedServiceDirectoryChanged(final PublishedServiceDirectoryChangeEvent event) {
+ if (viewer instanceof TableViewer) {
+ Control ctrl = viewer == null ? null : viewer.getControl();
+ if (ctrl != null && !ctrl.isDisposed())
+ ctrl.getDisplay().asyncExec(new Runnable() {
+ public void run() {
+ TableViewer tableViewer = (TableViewer) viewer;
+ if (event.getKind() == PublishedServiceDirectoryChangeEvent.ADDED)
+ tableViewer.add(event.getReplicatedServices());
+ else
+ tableViewer.remove(event.getReplicatedServices());
+ }
+ });
+ }
+ }
+ }
+
+ protected class SubscriptionViewOpener implements ISubscriptionCallback {
+
+ public void subscribed(final ISubscription subscription) {
+ Display.getDefault().asyncExec(new Runnable() {
+ public void run() {
+ SubscriptionView view;
+ try {
+ view = (SubscriptionView) PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().showView(SubscriptionView.VIEW_ID, subscription.getID().getName(), IWorkbenchPage.VIEW_ACTIVATE);
+ } catch (PartInitException e) {
+ ErrorDialog.openError(getSite().getShell(), "Subscription Error", "Could not create subscription view.", e.getStatus());
+ return;
+ }
+
+ view.setSubscription(container, subscription);
+ }
+ });
+ }
+
+ public void subscriptionFailed(final Throwable t) {
+ Display.getDefault().asyncExec(new Runnable() {
+ public void run() {
+ MessageDialog.openError(getSite().getShell(), "Subscription Error", t.getLocalizedMessage());
+ }
+ });
+ }
+ }
+}
diff --git a/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/example/pubsub/SubscriptionView.java b/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/example/pubsub/SubscriptionView.java
new file mode 100644
index 000000000..653a3e22f
--- /dev/null
+++ b/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/example/pubsub/SubscriptionView.java
@@ -0,0 +1,81 @@
+/**
+ * Copyright (c) 2006 Ecliptical Software 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:
+ * Ecliptical Software Inc. - initial API and implementation
+ */
+package org.eclipse.ecf.example.pubsub;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+import org.eclipse.ecf.core.ISharedObjectContainer;
+import org.eclipse.ecf.pubsub.ISubscription;
+import org.eclipse.ecf.pubsub.model.IReplicaModel;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.part.ViewPart;
+
+public class SubscriptionView extends ViewPart implements IAppendableListListener {
+
+ public static final String VIEW_ID = "org.eclipse.ecf.example.pubsub.subscription";
+
+ protected ISubscription subscription;
+
+ protected AppendableList model;
+
+ protected Text text;
+
+ public synchronized void setSubscription(ISharedObjectContainer container, ISubscription subscription) {
+ this.subscription = subscription;
+ setPartName("Subscription: " + subscription.getID());
+ Object object = container.getSharedObjectManager().getSharedObject(subscription.getID());
+ if (object instanceof IReplicaModel) {
+ Object data = ((IReplicaModel) object).getData();
+ if (data instanceof AppendableList) {
+ model = (AppendableList) data;
+ model.addListener(this);
+ Object[] values = model.getValues();
+ StringWriter buf = new StringWriter();
+ PrintWriter writer = new PrintWriter(buf);
+ for (int i = 0; i < values.length; ++i)
+ writer.println(values[i]);
+
+ writer.close();
+ text.setText(buf.toString());
+ }
+ }
+ }
+
+ public void createPartControl(Composite parent) {
+ text = new Text(parent, SWT.WRAP | SWT.READ_ONLY);
+ }
+
+ public void setFocus() {
+ text.setFocus();
+ }
+
+ public void dispose() {
+ if (model != null)
+ model.removeListener(this);
+
+ if (subscription != null)
+ subscription.dispose();
+
+ super.dispose();
+ }
+
+ public synchronized void appended(AppendableList list, final Object value) {
+ Display.getDefault().asyncExec(new Runnable() {
+ public void run() {
+ text.append(String.valueOf(value) + System.getProperty("line.separator"));
+ }
+ });
+ }
+}
diff --git a/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/IPublishedService.java b/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/IPublishedService.java
new file mode 100644
index 000000000..3c24eae9d
--- /dev/null
+++ b/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/IPublishedService.java
@@ -0,0 +1,25 @@
+/**
+ * Copyright (c) 2006 Ecliptical Software 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:
+ * Ecliptical Software Inc. - initial API and implementation
+ */
+package org.eclipse.ecf.pubsub;
+
+import java.util.Map;
+
+import org.eclipse.ecf.core.IIdentifiable;
+import org.eclipse.ecf.core.identity.ID;
+
+public interface IPublishedService extends IIdentifiable {
+
+ Map getProperties();
+
+ void subscribe(ID containerID);
+
+ void unsubscribe(ID containerID);
+}
diff --git a/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/IPublishedServiceDirectory.java b/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/IPublishedServiceDirectory.java
new file mode 100644
index 000000000..b9d68a723
--- /dev/null
+++ b/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/IPublishedServiceDirectory.java
@@ -0,0 +1,18 @@
+/**
+ * Copyright (c) 2006 Ecliptical Software 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:
+ * Ecliptical Software Inc. - initial API and implementation
+ */
+package org.eclipse.ecf.pubsub;
+
+public interface IPublishedServiceDirectory {
+
+ void addReplicatedServiceListener(IPublishedServiceDirectoryListener listener);
+
+ void removeReplicatedServiceListener(IPublishedServiceDirectoryListener listener);
+}
diff --git a/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/IPublishedServiceDirectoryListener.java b/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/IPublishedServiceDirectoryListener.java
new file mode 100644
index 000000000..e4194b154
--- /dev/null
+++ b/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/IPublishedServiceDirectoryListener.java
@@ -0,0 +1,16 @@
+/**
+ * Copyright (c) 2006 Ecliptical Software 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:
+ * Ecliptical Software Inc. - initial API and implementation
+ */
+package org.eclipse.ecf.pubsub;
+
+public interface IPublishedServiceDirectoryListener {
+
+ void publishedServiceDirectoryChanged(PublishedServiceDirectoryChangeEvent event);
+}
diff --git a/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/IPublishedServiceRequestor.java b/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/IPublishedServiceRequestor.java
new file mode 100644
index 000000000..6d5c95a39
--- /dev/null
+++ b/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/IPublishedServiceRequestor.java
@@ -0,0 +1,18 @@
+/**
+ * Copyright (c) 2006 Ecliptical Software 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:
+ * Ecliptical Software Inc. - initial API and implementation
+ */
+package org.eclipse.ecf.pubsub;
+
+import org.eclipse.ecf.core.identity.ID;
+
+public interface IPublishedServiceRequestor {
+
+ void subscribe(ID containerID, ID sharedObjectID, ISubscriptionCallback callback);
+}
diff --git a/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/ISubscription.java b/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/ISubscription.java
new file mode 100644
index 000000000..25c3abb1e
--- /dev/null
+++ b/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/ISubscription.java
@@ -0,0 +1,21 @@
+/**
+ * Copyright (c) 2006 Ecliptical Software 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:
+ * Ecliptical Software Inc. - initial API and implementation
+ */
+package org.eclipse.ecf.pubsub;
+
+import org.eclipse.ecf.core.IIdentifiable;
+import org.eclipse.ecf.core.identity.ID;
+
+public interface ISubscription extends IIdentifiable {
+
+ ID getHomeContainerID();
+
+ void dispose();
+}
diff --git a/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/ISubscriptionCallback.java b/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/ISubscriptionCallback.java
new file mode 100644
index 000000000..7cedc6a35
--- /dev/null
+++ b/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/ISubscriptionCallback.java
@@ -0,0 +1,18 @@
+/**
+ * Copyright (c) 2006 Ecliptical Software 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:
+ * Ecliptical Software Inc. - initial API and implementation
+ */
+package org.eclipse.ecf.pubsub;
+
+public interface ISubscriptionCallback {
+
+ void subscribed(ISubscription subscription);
+
+ void subscriptionFailed(Throwable t);
+}
diff --git a/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/PublishedServiceDescriptor.java b/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/PublishedServiceDescriptor.java
new file mode 100644
index 000000000..010680a23
--- /dev/null
+++ b/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/PublishedServiceDescriptor.java
@@ -0,0 +1,75 @@
+/**
+ * Copyright (c) 2006 Ecliptical Software 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:
+ * Ecliptical Software Inc. - initial API and implementation
+ */
+package org.eclipse.ecf.pubsub;
+
+import java.io.Serializable;
+import java.util.Map;
+
+import org.eclipse.ecf.core.identity.ID;
+
+public class PublishedServiceDescriptor implements Serializable {
+
+ private static final long serialVersionUID = -3152226289167000325L;
+
+ private final ID containerID;
+
+ private final ID sharedObjectID;
+
+ private final Map properties;
+
+ public PublishedServiceDescriptor(ID containerID, ID sharedObjectID, Map properties) {
+ this.containerID = containerID;
+ this.sharedObjectID = sharedObjectID;
+ this.properties = properties;
+ }
+
+ public ID getContainerID() {
+ return containerID;
+ }
+
+ public ID getSharedObjectID() {
+ return sharedObjectID;
+ }
+
+ public Map getProperties() {
+ return properties;
+ }
+
+ public int hashCode() {
+ int c = 17;
+ c = 37 * c + containerID.hashCode();
+ c = 37 * c + sharedObjectID.hashCode();
+ c = 37 * c + properties.hashCode();
+ return c;
+ }
+
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+
+ if (obj == null)
+ return false;
+
+ if (getClass() != obj.getClass())
+ return false;
+
+ PublishedServiceDescriptor other = (PublishedServiceDescriptor) obj;
+ return containerID.equals(other.containerID) && sharedObjectID.equals(other.sharedObjectID) && properties.equals(other.properties);
+ }
+
+ public String toString() {
+ StringBuffer buf = new StringBuffer("PublishedServiceDescriptor[");
+ buf.append("containerID=").append(containerID).append(';');
+ buf.append("sharedObjectID=").append(sharedObjectID).append(';');
+ buf.append("properties=").append(properties).append(']');
+ return buf.toString();
+ }
+}
diff --git a/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/PublishedServiceDirectoryChangeEvent.java b/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/PublishedServiceDirectoryChangeEvent.java
new file mode 100644
index 000000000..720f7f400
--- /dev/null
+++ b/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/PublishedServiceDirectoryChangeEvent.java
@@ -0,0 +1,67 @@
+/**
+ * Copyright (c) 2006 Ecliptical Software 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:
+ * Ecliptical Software Inc. - initial API and implementation
+ */
+package org.eclipse.ecf.pubsub;
+
+import java.util.Arrays;
+import java.util.EventObject;
+
+public class PublishedServiceDirectoryChangeEvent extends EventObject {
+
+ private static final long serialVersionUID = 5748843360974872790L;
+
+ public static final int ADDED = 0;
+
+ public static final int REMOVED = 1;
+
+ private final int kind;
+
+ private final PublishedServiceDescriptor[] services;
+
+ public PublishedServiceDirectoryChangeEvent(IPublishedServiceDirectory manager, int kind, PublishedServiceDescriptor[] services) {
+ super(manager);
+ this.kind = kind;
+ this.services = services;
+ }
+
+ public IPublishedServiceDirectory getManager() {
+ return (IPublishedServiceDirectory) source;
+ }
+
+ public int getKind() {
+ return kind;
+ }
+
+ public PublishedServiceDescriptor[] getReplicatedServices() {
+ return services;
+ }
+
+ public int hashCode() {
+ int c = 17;
+ c = 37 * c + source.hashCode();
+ c = 37 * c + kind;
+ c = 37 * c + services[0].hashCode();
+ return c;
+ }
+
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+
+ if (obj == null)
+ return false;
+
+ if (getClass() != obj.getClass())
+ return false;
+
+ PublishedServiceDirectoryChangeEvent other = (PublishedServiceDirectoryChangeEvent) obj;
+ return source.equals(other.source) && kind == other.kind && Arrays.equals(services, other.services);
+ }
+}
diff --git a/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/impl/DiscoveryAgent.java b/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/impl/DiscoveryAgent.java
new file mode 100644
index 000000000..1b642d106
--- /dev/null
+++ b/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/impl/DiscoveryAgent.java
@@ -0,0 +1,227 @@
+/**
+ * Copyright (c) 2006 Ecliptical Software 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:
+ * Ecliptical Software Inc. - initial API and implementation
+ */
+package org.eclipse.ecf.pubsub.impl;
+
+import java.io.IOException;
+import java.util.ArrayList;
+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.ISharedObjectConnector;
+import org.eclipse.ecf.core.ISharedObjectContext;
+import org.eclipse.ecf.core.ISharedObjectManager;
+import org.eclipse.ecf.core.ReplicaSharedObjectDescription;
+import org.eclipse.ecf.core.SharedObjectConnectException;
+import org.eclipse.ecf.core.SharedObjectDisconnectException;
+import org.eclipse.ecf.core.SharedObjectInitException;
+import org.eclipse.ecf.core.events.IContainerConnectedEvent;
+import org.eclipse.ecf.core.events.IContainerDisconnectedEvent;
+import org.eclipse.ecf.core.events.ISharedObjectActivatedEvent;
+import org.eclipse.ecf.core.events.ISharedObjectDeactivatedEvent;
+import org.eclipse.ecf.core.events.ISharedObjectMessageEvent;
+import org.eclipse.ecf.core.identity.ID;
+import org.eclipse.ecf.core.identity.IDFactory;
+import org.eclipse.ecf.core.identity.IDInstantiationException;
+import org.eclipse.ecf.core.util.Event;
+import org.eclipse.ecf.core.util.QueueException;
+import org.eclipse.ecf.pubsub.IPublishedService;
+import org.eclipse.ecf.pubsub.PublishedServiceDescriptor;
+
+public class DiscoveryAgent extends PlatformObject implements ISharedObject {
+
+ protected ISharedObjectConfig config;
+
+ public void init(ISharedObjectConfig config) throws SharedObjectInitException {
+ this.config = config;
+ }
+
+ public void handleEvent(Event event) {
+ if (event instanceof ISharedObjectActivatedEvent) {
+ ISharedObjectActivatedEvent e = (ISharedObjectActivatedEvent) event;
+ if (e.getActivatedID().equals(config.getSharedObjectID()))
+ activated();
+ else
+ activated(e.getActivatedID());
+ } else if (event instanceof ISharedObjectDeactivatedEvent) {
+ ISharedObjectDeactivatedEvent e = (ISharedObjectDeactivatedEvent) event;
+ if (e.getDeactivatedID().equals(config.getSharedObjectID()))
+ deactivated();
+ else
+ deactivated(e.getDeactivatedID());
+ } else if (event instanceof IContainerConnectedEvent) {
+ IContainerConnectedEvent e = (IContainerConnectedEvent) event;
+ if (e.getTargetID().equals(e.getLocalContainerID()))
+ connected();
+ else
+ connected(e.getTargetID());
+ } else if (event instanceof IContainerDisconnectedEvent) {
+ IContainerDisconnectedEvent e = (IContainerDisconnectedEvent) event;
+ if (e.getTargetID().equals(e.getLocalContainerID()))
+ disconnected();
+ else
+ disconnected(e.getTargetID());
+ } else if (event instanceof ISharedObjectMessageEvent)
+ received((ISharedObjectMessageEvent) event);
+ }
+
+ protected boolean isConnected() {
+ return config.getContext().getConnectedID() != null;
+ }
+
+ protected boolean isPrimary() {
+ return config.getContext().getLocalContainerID().equals(config.getHomeContainerID());
+ }
+
+ protected void activated(ID sharedObjectID) {
+ if (isPrimary())
+ return;
+
+ ISharedObjectContext ctx = config.getContext();
+ Object object = ctx.getSharedObjectManager().getSharedObject(sharedObjectID);
+ if (object instanceof IPublishedService) {
+ IPublishedService svc = (IPublishedService) object;
+ Map props = svc.getProperties();
+ PublishedServiceDescriptor desc = new PublishedServiceDescriptor(ctx.getLocalContainerID(), sharedObjectID, props);
+ try {
+ ctx.sendMessage(config.getHomeContainerID(), new DiscoveryMessage(DiscoveryMessage.ADDED, desc));
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ }
+
+ protected void activated() {
+ if (isConnected())
+ connected();
+ }
+
+ protected void deactivated(ID sharedObjectID) {
+ if (isPrimary())
+ return;
+
+ ISharedObjectContext ctx = config.getContext();
+ Object object = ctx.getSharedObjectManager().getSharedObject(sharedObjectID);
+ if (object instanceof IPublishedService) {
+ IPublishedService svc = (IPublishedService) object;
+ Map props = svc.getProperties();
+ PublishedServiceDescriptor desc = new PublishedServiceDescriptor(ctx.getLocalContainerID(), sharedObjectID, props);
+ try {
+ ctx.sendMessage(config.getHomeContainerID(), new DiscoveryMessage(DiscoveryMessage.REMOVED, desc));
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ }
+
+ protected void deactivated() {
+ if (isPrimary() && isConnected())
+ try {
+ config.getContext().sendDispose(null);
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ protected void connected(ID containerID) {
+ if (isPrimary())
+ try {
+ config.getContext().sendCreate(containerID, new ReplicaSharedObjectDescription(getClass(), config.getSharedObjectID()));
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ protected void connected() {
+ if (isPrimary()) {
+ try {
+ config.getContext().sendCreate(null, new ReplicaSharedObjectDescription(getClass(), config.getSharedObjectID()));
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ } else {
+ ArrayList published = new ArrayList();
+ ISharedObjectContext ctx = config.getContext();
+ ISharedObjectManager mgr = ctx.getSharedObjectManager();
+ ID[] ids = mgr.getSharedObjectIDs();
+ ID containerID = ctx.getLocalContainerID();
+ for (int i = 0; i < ids.length; ++i) {
+ Object object = mgr.getSharedObject(ids[i]);
+ if (object instanceof IPublishedService) {
+ IPublishedService svc = (IPublishedService) object;
+ Map props = svc.getProperties();
+ published.add(new PublishedServiceDescriptor(containerID, ids[i], props));
+ }
+ }
+
+ if (published.isEmpty())
+ return;
+
+ PublishedServiceDescriptor[] descriptors = new PublishedServiceDescriptor[published.size()];
+ published.toArray(descriptors);
+ try {
+ ctx.sendMessage(config.getHomeContainerID(), new DiscoveryMessage(DiscoveryMessage.ADDED, descriptors));
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ }
+
+ protected void disconnected(ID containerID) {
+ if (containerID.equals(config.getHomeContainerID()))
+ config.getContext().getSharedObjectManager().removeSharedObject(config.getSharedObjectID());
+ }
+
+ protected void disconnected() {
+ config.getContext().getSharedObjectManager().removeSharedObject(config.getSharedObjectID());
+ }
+
+ protected void received(ISharedObjectMessageEvent event) {
+ if (!(event.getData() instanceof DiscoveryMessage))
+ return;
+
+ try {
+ ID directoryID = IDFactory.getDefault().createStringID(PublishedServiceDirectory.SHARED_OBJECT_ID);
+ ISharedObjectManager mgr = config.getContext().getSharedObjectManager();
+ ISharedObjectConnector conn = mgr.connectSharedObjects(config.getSharedObjectID(), new ID[] { directoryID });
+ conn.enqueue(event);
+ mgr.disconnectSharedObjects(conn);
+ } catch (IDInstantiationException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (SharedObjectConnectException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (QueueException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (SharedObjectDisconnectException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ public void handleEvents(Event[] events) {
+ for (int i = 0; i < events.length; ++i)
+ handleEvent(events[i]);
+ }
+
+ public void dispose(ID containerID) {
+ config = null;
+ }
+}
diff --git a/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/impl/DiscoveryMessage.java b/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/impl/DiscoveryMessage.java
new file mode 100644
index 000000000..b226f7f51
--- /dev/null
+++ b/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/impl/DiscoveryMessage.java
@@ -0,0 +1,67 @@
+/**
+ * Copyright (c) 2006 Ecliptical Software 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:
+ * Ecliptical Software Inc. - initial API and implementation
+ */
+package org.eclipse.ecf.pubsub.impl;
+
+import java.io.Serializable;
+import java.util.Arrays;
+
+import org.eclipse.ecf.pubsub.PublishedServiceDescriptor;
+
+public class DiscoveryMessage implements Serializable {
+
+ private static final long serialVersionUID = 2321101436711728754L;
+
+ public static final int ADDED = 0;
+
+ public static final int REMOVED = 1;
+
+ private final int kind;
+
+ private final PublishedServiceDescriptor[] descriptors;
+
+ public DiscoveryMessage(int kind, PublishedServiceDescriptor[] descriptors) {
+ this.kind = kind;
+ this.descriptors = descriptors;
+ }
+
+ public DiscoveryMessage(int kind, PublishedServiceDescriptor descriptor) {
+ this(kind, new PublishedServiceDescriptor[] { descriptor });
+ }
+
+ public int getKind() {
+ return kind;
+ }
+
+ public PublishedServiceDescriptor[] getDescriptors() {
+ return descriptors;
+ }
+
+ public int hashCode() {
+ int c = 17;
+ c = 37 * c + kind;
+ c = 37 * c + descriptors[0].hashCode();
+ return c;
+ }
+
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+
+ if (obj == null)
+ return false;
+
+ if (getClass() != obj.getClass())
+ return false;
+
+ DiscoveryMessage other = (DiscoveryMessage) obj;
+ return kind == other.kind && Arrays.equals(descriptors, other.descriptors);
+ }
+} \ No newline at end of file
diff --git a/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/impl/PubSubAdapterFactory.java b/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/impl/PubSubAdapterFactory.java
new file mode 100644
index 000000000..88b965b88
--- /dev/null
+++ b/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/impl/PubSubAdapterFactory.java
@@ -0,0 +1,78 @@
+/**
+ * Copyright (c) 2006 Ecliptical Software 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:
+ * Ecliptical Software Inc. - initial API and implementation
+ */
+package org.eclipse.ecf.pubsub.impl;
+
+import org.eclipse.core.runtime.IAdapterFactory;
+import org.eclipse.ecf.core.ISharedObjectContainer;
+import org.eclipse.ecf.core.ISharedObjectManager;
+import org.eclipse.ecf.core.SharedObjectCreateException;
+import org.eclipse.ecf.core.SharedObjectDescription;
+import org.eclipse.ecf.core.identity.ID;
+import org.eclipse.ecf.core.identity.IDFactory;
+import org.eclipse.ecf.core.identity.IDInstantiationException;
+import org.eclipse.ecf.pubsub.IPublishedServiceDirectory;
+import org.eclipse.ecf.pubsub.IPublishedServiceRequestor;
+
+public class PubSubAdapterFactory implements IAdapterFactory {
+
+ private static final Class[] ADAPTERS = { IPublishedServiceDirectory.class, IPublishedServiceRequestor.class };
+
+ public Object getAdapter(Object adaptableObject, Class adapterType) {
+ if (!(adaptableObject instanceof ISharedObjectContainer))
+ return null;
+
+ if (IPublishedServiceDirectory.class.isAssignableFrom(adapterType))
+ return getDirectory((ISharedObjectContainer) adaptableObject);
+
+ if (IPublishedServiceRequestor.class.isAssignableFrom(adapterType))
+ return getRequestor((ISharedObjectContainer) adaptableObject);
+
+ return null;
+ }
+
+ protected IPublishedServiceDirectory getDirectory(ISharedObjectContainer container) {
+ ID directoryID;
+ try {
+ directoryID = IDFactory.getDefault().createStringID(PublishedServiceDirectory.SHARED_OBJECT_ID);
+ } catch (IDInstantiationException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ return null;
+ }
+
+ final ISharedObjectManager mgr = container.getSharedObjectManager();
+ IPublishedServiceDirectory directory = (IPublishedServiceDirectory) mgr.getSharedObject(directoryID);
+ if (directory != null)
+ return directory;
+
+ try {
+ SharedObjectDescription desc = createDirectoryDescription(directoryID);
+ mgr.createSharedObject(desc);
+ return (IPublishedServiceDirectory) mgr.getSharedObject(directoryID);
+ } catch (SharedObjectCreateException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ protected SharedObjectDescription createDirectoryDescription(ID directoryID) {
+ return new SharedObjectDescription(PublishedServiceDirectory.class, directoryID, null);
+ }
+
+ protected IPublishedServiceRequestor getRequestor(ISharedObjectContainer container) {
+ return new ServiceRequestor(container.getSharedObjectManager());
+ }
+
+ public Class[] getAdapterList() {
+ return ADAPTERS;
+ }
+}
diff --git a/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/impl/PublishedServiceDirectory.java b/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/impl/PublishedServiceDirectory.java
new file mode 100644
index 000000000..ed28700ab
--- /dev/null
+++ b/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/impl/PublishedServiceDirectory.java
@@ -0,0 +1,189 @@
+/**
+ * Copyright (c) 2006 Ecliptical Software 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:
+ * Ecliptical Software Inc. - initial API and implementation
+ */
+package org.eclipse.ecf.pubsub.impl;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+
+import org.eclipse.core.runtime.ISafeRunnable;
+import org.eclipse.core.runtime.ListenerList;
+import org.eclipse.core.runtime.PlatformObject;
+import org.eclipse.core.runtime.SafeRunner;
+import org.eclipse.ecf.core.ISharedObject;
+import org.eclipse.ecf.core.ISharedObjectConfig;
+import org.eclipse.ecf.core.ISharedObjectManager;
+import org.eclipse.ecf.core.SharedObjectDescription;
+import org.eclipse.ecf.core.SharedObjectInitException;
+import org.eclipse.ecf.core.events.IContainerDisconnectedEvent;
+import org.eclipse.ecf.core.events.ISharedObjectActivatedEvent;
+import org.eclipse.ecf.core.events.ISharedObjectDeactivatedEvent;
+import org.eclipse.ecf.core.events.ISharedObjectMessageEvent;
+import org.eclipse.ecf.core.identity.ID;
+import org.eclipse.ecf.core.identity.IDFactory;
+import org.eclipse.ecf.core.util.ECFException;
+import org.eclipse.ecf.core.util.Event;
+import org.eclipse.ecf.pubsub.IPublishedServiceDirectory;
+import org.eclipse.ecf.pubsub.IPublishedServiceDirectoryListener;
+import org.eclipse.ecf.pubsub.PublishedServiceDescriptor;
+import org.eclipse.ecf.pubsub.PublishedServiceDirectoryChangeEvent;
+
+public class PublishedServiceDirectory extends PlatformObject implements ISharedObject, IPublishedServiceDirectory {
+
+ protected static final String SHARED_OBJECT_ID = IPublishedServiceDirectory.class.getName();
+
+ protected ISharedObjectConfig config;
+
+ private final ListenerList listeners = new ListenerList();
+
+ private final Map services = new HashMap();
+
+ private ID discoveryAgentID;
+
+ public synchronized void addReplicatedServiceListener(final IPublishedServiceDirectoryListener listener) {
+ listeners.add(listener);
+ PublishedServiceDescriptor[] buf = new PublishedServiceDescriptor[services.values().size()];
+ services.values().toArray(buf);
+ final PublishedServiceDirectoryChangeEvent event = new PublishedServiceDirectoryChangeEvent(this, PublishedServiceDirectoryChangeEvent.ADDED, buf);
+ SafeRunner.run(new ISafeRunnable() {
+
+ public void run() throws Exception {
+ listener.publishedServiceDirectoryChanged(event);
+ }
+
+ public void handleException(Throwable exception) {
+ // TODO Auto-generated method stub
+
+ }
+ });
+ }
+
+ public void removeReplicatedServiceListener(IPublishedServiceDirectoryListener listener) {
+ listeners.remove(listener);
+ }
+
+ protected void fireServiceChangedEvent(final PublishedServiceDirectoryChangeEvent event) {
+ Object[] l = listeners.getListeners();
+ for (int i = 0; i < l.length; ++i) {
+ final IPublishedServiceDirectoryListener listener = (IPublishedServiceDirectoryListener) l[i];
+ SafeRunner.run(new ISafeRunnable() {
+
+ public void run() throws Exception {
+ listener.publishedServiceDirectoryChanged(event);
+ }
+
+ public void handleException(Throwable exception) {
+ // TODO Auto-generated method stub
+
+ }
+ });
+ }
+ }
+
+ public void init(ISharedObjectConfig config) throws SharedObjectInitException {
+ this.config = config;
+ }
+
+ public void handleEvent(Event event) {
+ if (event instanceof ISharedObjectActivatedEvent)
+ activated(((ISharedObjectActivatedEvent) event).getActivatedID());
+ else if (event instanceof ISharedObjectDeactivatedEvent)
+ deactivated(((ISharedObjectDeactivatedEvent) event).getDeactivatedID());
+ else if (event instanceof ISharedObjectMessageEvent)
+ received((ISharedObjectMessageEvent) event);
+ else if (event instanceof IContainerDisconnectedEvent)
+ disconnected((IContainerDisconnectedEvent) event);
+ }
+
+ protected void activated(final ID sharedObjectID) {
+ if (sharedObjectID.equals(config.getSharedObjectID())) {
+ ISharedObjectManager mgr = config.getContext().getSharedObjectManager();
+ if (discoveryAgentID == null) {
+ try {
+ discoveryAgentID = IDFactory.getDefault().createGUID();
+ mgr.createSharedObject(new SharedObjectDescription(DiscoveryAgent.class, discoveryAgentID, null));
+ } catch (ECFException e) {
+ // TODO Log me!
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
+ protected void deactivated(ID sharedObjectID) {
+ if (sharedObjectID.equals(config.getSharedObjectID())) {
+ if (discoveryAgentID != null) {
+ config.getContext().getSharedObjectManager().removeSharedObject(discoveryAgentID);
+ discoveryAgentID = null;
+ }
+ }
+ }
+
+ protected void disconnected(IContainerDisconnectedEvent event) {
+ ID containerID = event.getTargetID();
+ if (!containerID.equals(event.getLocalContainerID())) {
+ synchronized (this) {
+ Collection values = (Collection) services.remove(event.getTargetID());
+ if (values != null) {
+ PublishedServiceDescriptor[] buf = new PublishedServiceDescriptor[values.size()];
+ values.toArray(buf);
+ fireServiceChangedEvent(new PublishedServiceDirectoryChangeEvent(this, PublishedServiceDirectoryChangeEvent.REMOVED, buf));
+ }
+ }
+ }
+ }
+
+ protected void received(ISharedObjectMessageEvent event) {
+ Object data = event.getData();
+ if (!(data instanceof DiscoveryMessage))
+ return;
+
+ DiscoveryMessage msg = (DiscoveryMessage) event.getData();
+ PublishedServiceDescriptor[] descriptors = msg.getDescriptors();
+
+ synchronized (this) {
+ ID containerID = event.getRemoteContainerID();
+ Collection values = (Collection) services.get(containerID);
+ if (values == null) {
+ values = new HashSet();
+ services.put(containerID, values);
+ }
+
+ if (msg.getKind() == DiscoveryMessage.ADDED) {
+ values.addAll(Arrays.asList(descriptors));
+ } else {
+ values.removeAll(Arrays.asList(descriptors));
+ if (values.isEmpty())
+ services.remove(containerID);
+ }
+
+ int kind = msg.getKind() == DiscoveryMessage.ADDED ? PublishedServiceDirectoryChangeEvent.ADDED : PublishedServiceDirectoryChangeEvent.REMOVED;
+ fireServiceChangedEvent(new PublishedServiceDirectoryChangeEvent(this, kind, descriptors));
+ }
+ }
+
+ public void handleEvents(Event[] events) {
+ for (int i = 0; i < events.length; ++i)
+ handleEvent(events[i]);
+ }
+
+ public void dispose(ID containerID) {
+ listeners.clear();
+
+ synchronized (this) {
+ services.clear();
+ }
+
+ config = null;
+ }
+}
diff --git a/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/impl/ReplicatedServiceDiscoveryEvent.java b/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/impl/ReplicatedServiceDiscoveryEvent.java
new file mode 100644
index 000000000..ad454981f
--- /dev/null
+++ b/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/impl/ReplicatedServiceDiscoveryEvent.java
@@ -0,0 +1,71 @@
+/**
+ * Copyright (c) 2006 Ecliptical Software 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:
+ * Ecliptical Software Inc. - initial API and implementation
+ */
+package org.eclipse.ecf.pubsub.impl;
+
+import java.util.Arrays;
+
+import org.eclipse.ecf.core.identity.ID;
+import org.eclipse.ecf.core.util.Event;
+
+public class ReplicatedServiceDiscoveryEvent implements Event {
+
+ private static final long serialVersionUID = 1848459358595071814L;
+
+ public static final int ADDED = 0;
+
+ public static final int REMOVED = 1;
+
+ private final int kind;
+
+ private final ID containerID;
+
+ private final ID[] sharedObjectIDs;
+
+ public ReplicatedServiceDiscoveryEvent(int kind, ID containerID, ID[] sharedObjectIDs) {
+ this.kind = kind;
+ this.containerID = containerID;
+ this.sharedObjectIDs = sharedObjectIDs;
+ }
+
+ public int getKind() {
+ return kind;
+ }
+
+ public ID getContainerID() {
+ return containerID;
+ }
+
+ public ID[] getSharedObjectIDs() {
+ return sharedObjectIDs;
+ }
+
+ public int hashCode() {
+ int c = 17;
+ c = 37 * c + kind;
+ c = 37 * c + containerID.hashCode();
+ c = 37 * c + sharedObjectIDs[0].hashCode();
+ return c;
+ }
+
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+
+ if (obj == null)
+ return false;
+
+ if (getClass() != obj.getClass())
+ return false;
+
+ ReplicatedServiceDiscoveryEvent other = (ReplicatedServiceDiscoveryEvent) obj;
+ return kind == other.kind && containerID.equals(other.containerID) && Arrays.equals(sharedObjectIDs, other.sharedObjectIDs);
+ }
+}
diff --git a/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/impl/ServiceRequestor.java b/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/impl/ServiceRequestor.java
new file mode 100644
index 000000000..de0502ba0
--- /dev/null
+++ b/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/impl/ServiceRequestor.java
@@ -0,0 +1,60 @@
+/**
+ * Copyright (c) 2006 Ecliptical Software 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:
+ * Ecliptical Software Inc. - initial API and implementation
+ */
+package org.eclipse.ecf.pubsub.impl;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.ecf.core.ISharedObjectManager;
+import org.eclipse.ecf.core.SharedObjectCreateException;
+import org.eclipse.ecf.core.SharedObjectDescription;
+import org.eclipse.ecf.core.identity.ID;
+import org.eclipse.ecf.core.identity.IDFactory;
+import org.eclipse.ecf.core.identity.IDInstantiationException;
+import org.eclipse.ecf.pubsub.IPublishedServiceRequestor;
+import org.eclipse.ecf.pubsub.ISubscriptionCallback;
+
+public class ServiceRequestor implements IPublishedServiceRequestor {
+
+ protected final ISharedObjectManager mgr;
+
+ public ServiceRequestor(ISharedObjectManager mgr) {
+ this.mgr = mgr;
+ }
+
+ public void subscribe(ID containerID, ID sharedObjectID, ISubscriptionCallback callback) {
+ if (containerID == null || sharedObjectID == null || callback == null)
+ throw new IllegalArgumentException();
+
+ try {
+ mgr.createSharedObject(createSubscriptionDescription(containerID, sharedObjectID, callback));
+ } catch (SharedObjectCreateException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ protected SharedObjectDescription createSubscriptionDescription(ID containerID, ID sharedObjectID, ISubscriptionCallback callback) {
+ Map props = new HashMap(3);
+ props.put(SubscriptionAgent.CONTAINER_ID_KEY, containerID);
+ props.put(SubscriptionAgent.SHARED_OBJECT_ID_KEY, sharedObjectID);
+ props.put(SubscriptionAgent.CALLBACK_KEY, callback);
+ ID id;
+ try {
+ id = IDFactory.getDefault().createGUID();
+ } catch (IDInstantiationException e) {
+ // TODO handle this!
+ throw new RuntimeException(e);
+ }
+
+ return new SharedObjectDescription(SubscriptionAgent.class, id, props);
+ }
+}
diff --git a/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/impl/SubscriptionAgent.java b/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/impl/SubscriptionAgent.java
new file mode 100644
index 000000000..7e7902aa5
--- /dev/null
+++ b/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/impl/SubscriptionAgent.java
@@ -0,0 +1,213 @@
+/**
+ * Copyright (c) 2006 Ecliptical Software 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:
+ * Ecliptical Software Inc. - initial API and implementation
+ */
+package org.eclipse.ecf.pubsub.impl;
+
+import java.io.IOException;
+import java.util.HashMap;
+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.ISharedObjectManager;
+import org.eclipse.ecf.core.ReplicaSharedObjectDescription;
+import org.eclipse.ecf.core.SharedObjectInitException;
+import org.eclipse.ecf.core.events.IContainerDisconnectedEvent;
+import org.eclipse.ecf.core.events.ISharedObjectActivatedEvent;
+import org.eclipse.ecf.core.events.ISharedObjectCreateResponseEvent;
+import org.eclipse.ecf.core.events.ISharedObjectDeactivatedEvent;
+import org.eclipse.ecf.core.identity.ID;
+import org.eclipse.ecf.core.util.Event;
+import org.eclipse.ecf.pubsub.IPublishedService;
+import org.eclipse.ecf.pubsub.ISubscription;
+import org.eclipse.ecf.pubsub.ISubscriptionCallback;
+
+public class SubscriptionAgent extends PlatformObject implements ISharedObject {
+
+ protected static final Object CONTAINER_ID_KEY = new Integer(0);
+
+ protected static final Object SHARED_OBJECT_ID_KEY = new Integer(1);
+
+ protected static final Object CALLBACK_KEY = new Integer(2);
+
+ protected ISharedObjectConfig config;
+
+ protected ID containerID;
+
+ protected ID sharedObjectID;
+
+ protected ISubscriptionCallback callback;
+
+ protected boolean subscribed;
+
+ protected boolean disposed;
+
+ public void init(ISharedObjectConfig config) throws SharedObjectInitException {
+ this.config = config;
+ Map props = config.getProperties();
+
+ if (isPrimary()) {
+ containerID = (ID) props.get(CONTAINER_ID_KEY);
+ if (containerID == null)
+ throw new SharedObjectInitException("containerID is required");
+
+ callback = (ISubscriptionCallback) props.get(CALLBACK_KEY);
+ if (callback == null)
+ throw new SharedObjectInitException("callback is required");
+ }
+
+ sharedObjectID = (ID) props.get(SHARED_OBJECT_ID_KEY);
+ if (sharedObjectID == null)
+ throw new SharedObjectInitException("sharedObjectID is required");
+ }
+
+ public void handleEvent(Event event) {
+ if (event instanceof ISharedObjectActivatedEvent) {
+ ISharedObjectActivatedEvent e = (ISharedObjectActivatedEvent) event;
+ if (e.getActivatedID().equals(config.getSharedObjectID()))
+ activated();
+ else
+ activated(e.getActivatedID());
+ } else if (event instanceof ISharedObjectDeactivatedEvent) {
+ ISharedObjectDeactivatedEvent e = (ISharedObjectDeactivatedEvent) event;
+ if (e.getDeactivatedID().equals(config.getSharedObjectID()))
+ deactivated();
+ } else if (event instanceof IContainerDisconnectedEvent) {
+ IContainerDisconnectedEvent e = (IContainerDisconnectedEvent) event;
+ if (e.getTargetID().equals(e.getLocalContainerID()))
+ disconnected();
+ else
+ disconnected(e.getTargetID());
+ } else if (event instanceof ISharedObjectCreateResponseEvent)
+ received((ISharedObjectCreateResponseEvent) event);
+ }
+
+ protected boolean isPrimary() {
+ return config.getContext().getLocalContainerID().equals(config.getHomeContainerID());
+ }
+
+ protected void activated() {
+ ISharedObjectContext ctx = config.getContext();
+ if (isPrimary()) {
+ try {
+ ctx.sendCreate(containerID, createReplicaDescription());
+ // TODO set timer to time out if no response received within some bound
+ } catch (IOException e) {
+ callback.subscriptionFailed(e);
+ ctx.getSharedObjectManager().removeSharedObject(config.getSharedObjectID());
+ }
+
+ return;
+ }
+
+ ISharedObjectManager mgr = ctx.getSharedObjectManager();
+ ISharedObject so = mgr.getSharedObject(sharedObjectID);
+ try {
+ ID homeContainerID = config.getHomeContainerID();
+ if (so instanceof IPublishedService) {
+ IPublishedService svc = (IPublishedService) so;
+ svc.subscribe(homeContainerID);
+ subscribed = true;
+ } else {
+ ctx.sendCreateResponse(homeContainerID, new IllegalArgumentException("Not an IPublishedService."), -1);
+ }
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+
+ ctx.getSharedObjectManager().removeSharedObject(config.getSharedObjectID());
+ }
+ }
+
+ protected void activated(ID sharedObjectID) {
+ if (isPrimary() && sharedObjectID.equals(this.sharedObjectID))
+ callback.subscribed(new Subscription());
+ }
+
+ protected void deactivated() {
+ if (isPrimary()) {
+ synchronized (this) {
+ disposed = true;
+ }
+
+ return;
+ }
+
+ if (subscribed) {
+ ISharedObject so = config.getContext().getSharedObjectManager().getSharedObject(sharedObjectID);
+ if (so instanceof IPublishedService) {
+ IPublishedService svc = (IPublishedService) so;
+ svc.unsubscribe(config.getHomeContainerID());
+ subscribed = false;
+ }
+ }
+ }
+
+ protected void disconnected() {
+ config.getContext().getSharedObjectManager().removeSharedObject(config.getSharedObjectID());
+ }
+
+ protected void disconnected(ID containerID) {
+ if (containerID.equals(config.getHomeContainerID()) || containerID.equals(this.containerID))
+ config.getContext().getSharedObjectManager().removeSharedObject(config.getSharedObjectID());
+ }
+
+ protected void received(ISharedObjectCreateResponseEvent e) {
+ if (e.getRemoteContainerID().equals(containerID) && e.getSenderSharedObjectID().equals(config.getSharedObjectID()))
+ callback.subscriptionFailed(e.getException());
+ }
+
+ protected ReplicaSharedObjectDescription createReplicaDescription() {
+ Map props = new HashMap(1);
+ props.put(SHARED_OBJECT_ID_KEY, sharedObjectID);
+ return new ReplicaSharedObjectDescription(getClass(), config.getSharedObjectID(), config.getHomeContainerID(), props);
+ }
+
+ public void handleEvents(Event[] events) {
+ for (int i = 0; i < events.length; ++i)
+ handleEvent(events[i]);
+ }
+
+ public void dispose(ID containerID) {
+ config = null;
+ }
+
+ protected class Subscription implements ISubscription {
+
+ public ID getID() {
+ return sharedObjectID;
+ }
+
+ public ID getHomeContainerID() {
+ return containerID;
+ }
+
+ public void dispose() {
+ synchronized (SubscriptionAgent.this) {
+ if (disposed)
+ return;
+
+ disposed = true;
+ }
+
+ ISharedObjectContext ctx = config.getContext();
+ try {
+ ctx.sendDispose(containerID);
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ ctx.getSharedObjectManager().removeSharedObject(config.getSharedObjectID());
+ }
+ }
+}
diff --git a/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/model/IMasterModel.java b/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/model/IMasterModel.java
new file mode 100644
index 000000000..54cca81bf
--- /dev/null
+++ b/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/model/IMasterModel.java
@@ -0,0 +1,20 @@
+/**
+ * Copyright (c) 2006 Ecliptical Software 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:
+ * Ecliptical Software Inc. - initial API and implementation
+ */
+package org.eclipse.ecf.pubsub.model;
+
+import java.io.IOException;
+
+import org.eclipse.ecf.pubsub.IPublishedService;
+
+public interface IMasterModel extends IPublishedService {
+
+ void update(Object data) throws IOException;
+}
diff --git a/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/model/IModelUpdater.java b/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/model/IModelUpdater.java
new file mode 100644
index 000000000..b984cb5cc
--- /dev/null
+++ b/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/model/IModelUpdater.java
@@ -0,0 +1,16 @@
+/**
+ * Copyright (c) 2006 Ecliptical Software 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:
+ * Ecliptical Software Inc. - initial API and implementation
+ */
+package org.eclipse.ecf.pubsub.model;
+
+public interface IModelUpdater {
+
+ void update(Object data, Object update);
+}
diff --git a/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/model/IReplicaModel.java b/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/model/IReplicaModel.java
new file mode 100644
index 000000000..af2130077
--- /dev/null
+++ b/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/model/IReplicaModel.java
@@ -0,0 +1,16 @@
+/**
+ * Copyright (c) 2006 Ecliptical Software 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:
+ * Ecliptical Software Inc. - initial API and implementation
+ */
+package org.eclipse.ecf.pubsub.model;
+
+public interface IReplicaModel {
+
+ Object getData();
+}
diff --git a/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/model/SharedModelFactory.java b/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/model/SharedModelFactory.java
new file mode 100644
index 000000000..bce726cd6
--- /dev/null
+++ b/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/model/SharedModelFactory.java
@@ -0,0 +1,90 @@
+/**
+ * Copyright (c) 2006 Ecliptical Software 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:
+ * Ecliptical Software Inc. - initial API and implementation
+ */
+package org.eclipse.ecf.pubsub.model;
+
+import java.util.HashMap;
+
+import org.eclipse.ecf.core.IContainerListener;
+import org.eclipse.ecf.core.ISharedObjectContainer;
+import org.eclipse.ecf.core.ISharedObjectManager;
+import org.eclipse.ecf.core.ReplicaSharedObjectDescription;
+import org.eclipse.ecf.core.SharedObjectCreateException;
+import org.eclipse.ecf.core.SharedObjectDescription;
+import org.eclipse.ecf.core.events.IContainerEvent;
+import org.eclipse.ecf.core.events.ISharedObjectActivatedEvent;
+import org.eclipse.ecf.core.identity.ID;
+import org.eclipse.ecf.pubsub.model.impl.AgentBase;
+import org.eclipse.ecf.pubsub.model.impl.LocalAgent;
+
+public class SharedModelFactory {
+
+ protected static final Object INITIAL_DATA_KEY = AgentBase.INITIAL_DATA_KEY;
+
+ protected static final Object MODEL_UPDATER_KEY = AgentBase.MODEL_UPDATER_KEY;
+
+ protected static final long DEFAULT_CREATION_TIMEOUT = 5000;
+
+ private static final SharedModelFactory INSTANCE = new SharedModelFactory();
+
+ private SharedModelFactory() {
+ // no public instantiation
+ }
+
+ public static SharedModelFactory getInstance() {
+ return INSTANCE;
+ }
+
+ public IMasterModel createSharedDataSource(ISharedObjectContainer container, final ID id, Object data, String updaterID) throws SharedObjectCreateException {
+ final ISharedObjectManager mgr = container.getSharedObjectManager();
+ final Object[] result = new Object[1];
+ final Object monitor = new Object();
+ IContainerListener listener = new IContainerListener() {
+ public void handleEvent(IContainerEvent event) {
+ if (event instanceof ISharedObjectActivatedEvent) {
+ ISharedObjectActivatedEvent e = (ISharedObjectActivatedEvent) event;
+ if (e.getActivatedID().equals(id)) {
+ result[0] = mgr.getSharedObject(id);
+ synchronized (monitor) {
+ monitor.notify();
+ }
+ }
+ }
+ }
+ };
+
+ try {
+ container.addListener(listener, null);
+ SharedObjectDescription desc = createLocalAgentDescription(id, container.getID(), data, updaterID);
+ synchronized (monitor) {
+ mgr.createSharedObject(desc);
+ if (result[0] == null)
+ monitor.wait(getCreationTimeout());
+ }
+ } catch (InterruptedException e) {
+ throw new SharedObjectCreateException(e);
+ } finally {
+ container.removeListener(listener);
+ }
+
+ return (IMasterModel) result[0];
+ }
+
+ protected long getCreationTimeout() {
+ return DEFAULT_CREATION_TIMEOUT;
+ }
+
+ protected SharedObjectDescription createLocalAgentDescription(ID sharedObjectID, ID homeContainerID, Object data, String updaterID) {
+ HashMap props = new HashMap(2);
+ props.put(INITIAL_DATA_KEY, data);
+ props.put(MODEL_UPDATER_KEY, updaterID);
+ return new ReplicaSharedObjectDescription(LocalAgent.class, sharedObjectID, homeContainerID, props);
+ }
+}
diff --git a/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/model/impl/AgentBase.java b/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/model/impl/AgentBase.java
new file mode 100644
index 000000000..85d86e319
--- /dev/null
+++ b/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/model/impl/AgentBase.java
@@ -0,0 +1,158 @@
+/**
+ * Copyright (c) 2006 Ecliptical Software 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:
+ * Ecliptical Software Inc. - initial API and implementation
+ */
+package org.eclipse.ecf.pubsub.model.impl;
+
+import java.util.Map;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.PlatformObject;
+import org.eclipse.ecf.core.IIdentifiable;
+import org.eclipse.ecf.core.ISharedObject;
+import org.eclipse.ecf.core.ISharedObjectConfig;
+import org.eclipse.ecf.core.SharedObjectInitException;
+import org.eclipse.ecf.core.events.IContainerConnectedEvent;
+import org.eclipse.ecf.core.events.IContainerDisconnectedEvent;
+import org.eclipse.ecf.core.events.ISharedObjectActivatedEvent;
+import org.eclipse.ecf.core.events.ISharedObjectDeactivatedEvent;
+import org.eclipse.ecf.core.events.ISharedObjectMessageEvent;
+import org.eclipse.ecf.core.identity.ID;
+import org.eclipse.ecf.core.util.Event;
+import org.eclipse.ecf.pubsub.model.IModelUpdater;
+
+public abstract class AgentBase extends PlatformObject implements ISharedObject, IIdentifiable {
+
+ public static final Object INITIAL_DATA_KEY = new Integer(0);
+
+ public static final Object MODEL_UPDATER_KEY = new Integer(1);
+
+ protected ISharedObjectConfig config;
+
+ protected Object data;
+
+ protected String updaterID;
+
+ protected IModelUpdater updater;
+
+ public void init(ISharedObjectConfig config) throws SharedObjectInitException {
+ this.config = config;
+ Map props = config.getProperties();
+ data = props.get(INITIAL_DATA_KEY);
+ updaterID = (String) props.get(MODEL_UPDATER_KEY);
+ if (updaterID == null)
+ throw new SharedObjectInitException("Model Updater is required.");
+
+ IExtensionRegistry registry = Platform.getExtensionRegistry();
+ if (registry == null)
+ throw new SharedObjectInitException("No Platform Extension Registry.");
+
+ IConfigurationElement[] elements = registry.getConfigurationElementsFor("org.eclipse.ecf.example.pubsub.modelUpdater");
+ for (int i = 0; i < elements.length; ++i) {
+ if (updaterID.equals(elements[i].getAttribute("id"))) {
+ try {
+ updater = (IModelUpdater) elements[i].createExecutableExtension("class");
+ } catch (CoreException e) {
+ throw new SharedObjectInitException(e);
+ } catch (ClassCastException e) {
+ throw new SharedObjectInitException(e);
+ }
+
+ break;
+ }
+ }
+
+ if (updater == null)
+ throw new SharedObjectInitException("Could not find specified Model Updater.");
+ }
+
+ public void handleEvent(Event event) {
+ if (event instanceof ISharedObjectActivatedEvent) {
+ ISharedObjectActivatedEvent e = (ISharedObjectActivatedEvent) event;
+ if (e.getActivatedID().equals(config.getSharedObjectID()))
+ activated();
+ else
+ activated(e.getActivatedID());
+ } else if (event instanceof ISharedObjectDeactivatedEvent) {
+ ISharedObjectDeactivatedEvent e = (ISharedObjectDeactivatedEvent) event;
+ if (e.getDeactivatedID().equals(config.getSharedObjectID()))
+ deactivated();
+ else
+ deactivated(e.getDeactivatedID());
+ } else if (event instanceof IContainerConnectedEvent) {
+ IContainerConnectedEvent e = (IContainerConnectedEvent) event;
+ if (e.getTargetID().equals(e.getLocalContainerID()))
+ connected();
+ else
+ connected(e.getTargetID());
+ } else if (event instanceof IContainerDisconnectedEvent) {
+ IContainerDisconnectedEvent e = (IContainerDisconnectedEvent) event;
+ if (e.getTargetID().equals(e.getLocalContainerID()))
+ disconnected();
+ else
+ disconnected(e.getTargetID());
+ } else if (event instanceof ISharedObjectMessageEvent) {
+ ISharedObjectMessageEvent e = (ISharedObjectMessageEvent) event;
+ received(e.getRemoteContainerID(), e.getData());
+ }
+ }
+
+ protected boolean isConnected() {
+ return config.getContext().getConnectedID() != null;
+ }
+
+ protected void activated(ID sharedObjectID) {
+ }
+
+ protected void activated() {
+ }
+
+ protected void deactivated(ID sharedObjectID) {
+ }
+
+ protected void deactivated() {
+ }
+
+ protected void connected(ID containerID) {
+ }
+
+ protected void connected() {
+ }
+
+ protected void disconnected(ID containerID) {
+ }
+
+ protected void disconnected() {
+ }
+
+ protected void received(ID containerID, Object data) {
+ }
+
+ protected void apply(Object data) {
+ updater.update(this.data, data);
+ }
+
+ public void handleEvents(Event[] events) {
+ for (int i = 0; i < events.length; ++i)
+ handleEvent(events[i]);
+ }
+
+ public ID getID() {
+ return config.getSharedObjectID();
+ }
+
+ public void dispose(ID containerID) {
+ config = null;
+ data = null;
+ updater = null;
+ }
+}
diff --git a/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/model/impl/LocalAgent.java b/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/model/impl/LocalAgent.java
new file mode 100644
index 000000000..252975c38
--- /dev/null
+++ b/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/model/impl/LocalAgent.java
@@ -0,0 +1,65 @@
+/**
+ * Copyright (c) 2006 Ecliptical Software 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:
+ * Ecliptical Software Inc. - initial API and implementation
+ */
+package org.eclipse.ecf.pubsub.model.impl;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.ecf.core.ISharedObjectContext;
+import org.eclipse.ecf.core.ReplicaSharedObjectDescription;
+import org.eclipse.ecf.core.identity.ID;
+import org.eclipse.ecf.pubsub.model.IMasterModel;
+
+public class LocalAgent extends AgentBase implements IMasterModel {
+
+ public synchronized void update(Object data) throws IOException {
+ apply(data);
+ config.getContext().sendMessage(null, data);
+ }
+
+ public Map getProperties() {
+ return Collections.EMPTY_MAP;
+ }
+
+ public void subscribe(ID containerID) {
+ ISharedObjectContext ctx = config.getContext();
+ try {
+ ctx.sendCreate(containerID, createRemoteAgentDescription());
+ } catch (IOException e) {
+ // TODO Log me!
+ e.printStackTrace();
+ }
+ }
+
+ public void unsubscribe(ID containerID) {
+ // TODO Auto-generated method stub
+
+ }
+
+ protected void deactivated() {
+ if (isConnected())
+ try {
+ config.getContext().sendDispose(null);
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ protected ReplicaSharedObjectDescription createRemoteAgentDescription() {
+ Map props = new HashMap(2);
+ props.put(INITIAL_DATA_KEY, data);
+ props.put(MODEL_UPDATER_KEY, updaterID);
+ return new ReplicaSharedObjectDescription(RemoteAgent.class, config.getSharedObjectID(), config.getHomeContainerID(), props);
+ }
+}
diff --git a/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/model/impl/RemoteAgent.java b/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/model/impl/RemoteAgent.java
new file mode 100644
index 000000000..076c42452
--- /dev/null
+++ b/examples/bundles/org.eclipse.ecf.example.pubsub/src/org/eclipse/ecf/pubsub/model/impl/RemoteAgent.java
@@ -0,0 +1,34 @@
+/**
+ * Copyright (c) 2006 Ecliptical Software 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:
+ * Ecliptical Software Inc. - initial API and implementation
+ */
+package org.eclipse.ecf.pubsub.model.impl;
+
+import org.eclipse.ecf.core.identity.ID;
+import org.eclipse.ecf.pubsub.model.IReplicaModel;
+
+public class RemoteAgent extends AgentBase implements IReplicaModel {
+
+ public Object getData() {
+ return data;
+ }
+
+ protected void disconnected() {
+ config.getContext().getSharedObjectManager().removeSharedObject(config.getSharedObjectID());
+ }
+
+ protected void disconnected(ID containerID) {
+ if (containerID.equals(config.getHomeContainerID()))
+ disconnected();
+ }
+
+ protected void received(ID containerID, Object data) {
+ apply(data);
+ }
+}

Back to the top