Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--framework/bundles/org.eclipse.ecf.datashare/src/org/eclipse/ecf/internal/datashare/Agent.java294
-rw-r--r--framework/bundles/org.eclipse.ecf.datashare/src/org/eclipse/ecf/internal/datashare/EagerElectionBootstrap.java201
-rw-r--r--framework/bundles/org.eclipse.ecf.datashare/src/org/eclipse/ecf/internal/datashare/Election.java51
-rw-r--r--framework/bundles/org.eclipse.ecf.datashare/src/org/eclipse/ecf/internal/datashare/IBootstrap.java18
-rw-r--r--framework/bundles/org.eclipse.ecf.datashare/src/org/eclipse/ecf/internal/datashare/LazyElectionBootstrap.java160
-rw-r--r--framework/bundles/org.eclipse.ecf.datashare/src/org/eclipse/ecf/internal/datashare/Ping.java23
-rw-r--r--framework/bundles/org.eclipse.ecf.datashare/src/org/eclipse/ecf/internal/datashare/ServerBootstrap.java69
7 files changed, 624 insertions, 192 deletions
diff --git a/framework/bundles/org.eclipse.ecf.datashare/src/org/eclipse/ecf/internal/datashare/Agent.java b/framework/bundles/org.eclipse.ecf.datashare/src/org/eclipse/ecf/internal/datashare/Agent.java
index 9b81dc1e5..7321bcec8 100644
--- a/framework/bundles/org.eclipse.ecf.datashare/src/org/eclipse/ecf/internal/datashare/Agent.java
+++ b/framework/bundles/org.eclipse.ecf.datashare/src/org/eclipse/ecf/internal/datashare/Agent.java
@@ -11,20 +11,13 @@
package org.eclipse.ecf.internal.datashare;
import java.io.IOException;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
import java.util.Map;
-import java.util.Random;
import org.eclipse.ecf.core.ISharedObject;
import org.eclipse.ecf.core.ISharedObjectConfig;
+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;
-import org.eclipse.ecf.core.events.ISharedObjectContainerJoinedEvent;
-import org.eclipse.ecf.core.events.ISharedObjectMessageEvent;
import org.eclipse.ecf.core.identity.ID;
import org.eclipse.ecf.core.util.Event;
@@ -33,188 +26,105 @@ import org.eclipse.ecf.core.util.Event;
*/
public class Agent implements ISharedObject {
- private final Random random = new Random();
-
- private Object sharedData;
-
- private ISharedObjectConfig config;
-
- private final HashMap elections = new HashMap();
-
- public Agent() {
- }
-
- public Agent(Object sharedData) {
- this.sharedData = sharedData;
- }
-
- public Object getSharedData() {
- return sharedData;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.eclipse.ecf.core.ISharedObject#init(org.eclipse.ecf.core.ISharedObjectConfig)
- */
- public synchronized void init(ISharedObjectConfig config)
- throws SharedObjectInitException {
- this.config = config;
- Map params = config.getProperties();
- if (params != null)
- sharedData = params.get("sharedData");
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.eclipse.ecf.core.ISharedObject#handleEvent(org.eclipse.ecf.core.util.Event)
- */
- public void handleEvent(Event event) {
- if (event instanceof ISharedObjectActivatedEvent) {
- ISharedObjectActivatedEvent e = (ISharedObjectActivatedEvent) event;
- if (e.getActivatedID().equals(config.getSharedObjectID()))
- handleActivated();
- } else if (event instanceof ISharedObjectContainerJoinedEvent) {
- ISharedObjectContainerJoinedEvent e = (ISharedObjectContainerJoinedEvent) event;
- handleJoined(e.getJoinedContainerID());
- } else if (event instanceof ISharedObjectContainerDepartedEvent) {
- ISharedObjectContainerDepartedEvent e = (ISharedObjectContainerDepartedEvent) event;
- handleDeparted(e.getDepartedContainerID());
- } else if (event instanceof ISharedObjectMessageEvent) {
- ISharedObjectMessageEvent e = (ISharedObjectMessageEvent) event;
- if (e.getData() instanceof Vote)
- handleVote((Vote) e.getData(), e.getRemoteContainerID());
- else if (e.getData() instanceof Elected)
- handleElected((Elected) e.getData());
- }
- }
-
- private void handleActivated() {
- // tell client we're ready
- }
-
- private void handleJoined(ID containerID) {
- long ticket = random.nextLong();
- Election election = new Election(ticket, config.getContext()
- .getGroupMemberIDs());
- synchronized (elections) {
- elections.put(containerID, election);
- }
-
- try {
- config.getContext()
- .sendMessage(null, new Vote(ticket, containerID));
- } catch (IOException e) {
- handleError(e);
- }
- }
-
- private void handleVote(Vote msg, ID containerID) {
- synchronized (elections) {
- Election election = (Election) elections.get(msg.getElectionID());
- if (election != null) {
- switch (election.processVote(msg.getTicket(), containerID)) {
- case Election.WON:
- processVictory(msg.getElectionID());
- case Election.LOST:
- elections.remove(msg.getElectionID());
- }
- }
- }
- }
-
- private void handleElected(Elected msg) {
- synchronized (elections) {
- elections.remove(msg.getElectionID());
- }
- }
-
- private void handleDeparted(ID containerID) {
- synchronized (elections) {
- for (Iterator i = elections.entrySet().iterator(); i.hasNext();) {
- Map.Entry entry = (Map.Entry) i.next();
- Election election = (Election) entry.getValue();
- switch (election.disqualify(containerID)) {
- case Election.WON:
- processVictory((ID) entry.getKey());
- case Election.LOST:
- i.remove();
- break;
- }
- }
- }
- }
-
- private void processVictory(ID electionID) {
- try {
- config.getContext().sendMessage(null, new Elected(electionID));
- } catch (IOException e) {
- handleError(e);
- }
- }
-
- private void handleError(Throwable t) {
- t.printStackTrace();
- }
-
- /*
- * (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.ecf.core.ISharedObject#getAdapter(java.lang.Class)
- */
- public Object getAdapter(Class clazz) {
- return null;
- }
-
- private class Election {
-
- public static final short LOST = 0;
-
- public static final short WON = 1;
-
- public static final short UNKNOWN = 2;
-
- private final long ticket;
-
- private final HashSet members;
-
- public Election(long ticket, ID[] members) {
- this.ticket = ticket;
- this.members = new HashSet(Arrays.asList(members));
- }
-
- public short processVote(long ticket, ID containerID) {
- if (this.ticket < ticket)
- return LOST;
- else {
- members.remove(containerID);
- return members.isEmpty() ? WON : UNKNOWN;
- }
- }
-
- public short disqualify(ID containerID) {
- members.remove(containerID);
- return members.isEmpty() ? WON : UNKNOWN;
- }
- }
+ private Object sharedData;
+
+ private ISharedObjectConfig config;
+
+ private IBootstrap bootstrap;
+
+ public Agent() {
+ }
+
+ public Agent(Object sharedData) {
+ this.sharedData = sharedData;
+ }
+
+ public Object getSharedData() {
+ return sharedData;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ecf.core.ISharedObject#init(org.eclipse.ecf.core.ISharedObjectConfig)
+ */
+ public synchronized void init(ISharedObjectConfig config)
+ throws SharedObjectInitException {
+ this.config = config;
+ Map params = config.getProperties();
+ if (params != null)
+ sharedData = params.get("sharedData");
+
+ bootstrap = new LazyElectionBootstrap();
+ bootstrap.setAgent(this);
+ bootstrap.init(config);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ecf.core.ISharedObject#handleEvent(org.eclipse.ecf.core.util.Event)
+ */
+ public void handleEvent(Event event) {
+ if (event instanceof ISharedObjectActivatedEvent) {
+ ISharedObjectActivatedEvent e = (ISharedObjectActivatedEvent) event;
+ if (e.getActivatedID().equals(config.getSharedObjectID()))
+ handleActivated();
+ }
+
+ bootstrap.handleEvent(event);
+ }
+
+ private void handleActivated() {
+ if (config.getHomeContainerID().equals(
+ config.getContext().getLocalContainerID()))
+ try {
+ config.getContext().sendCreate(
+ null,
+ new SharedObjectDescription(config.getSharedObjectID(),
+ getClass()));
+ } catch (IOException e) {
+ handleError(e);
+ }
+
+ // TODO tell client we're ready
+ }
+
+ public void doBootstrap(ID containerID) {
+ // TODO bootstrap the new member
+ }
+
+ private void handleError(Throwable t) {
+ t.printStackTrace();
+ }
+
+ /*
+ * (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) {
+ bootstrap.dispose(containerID);
+ bootstrap = null;
+ config = null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ecf.core.ISharedObject#getAdapter(java.lang.Class)
+ */
+ public Object getAdapter(Class clazz) {
+ return null;
+ }
}
diff --git a/framework/bundles/org.eclipse.ecf.datashare/src/org/eclipse/ecf/internal/datashare/EagerElectionBootstrap.java b/framework/bundles/org.eclipse.ecf.datashare/src/org/eclipse/ecf/internal/datashare/EagerElectionBootstrap.java
new file mode 100644
index 000000000..1a425401a
--- /dev/null
+++ b/framework/bundles/org.eclipse.ecf.datashare/src/org/eclipse/ecf/internal/datashare/EagerElectionBootstrap.java
@@ -0,0 +1,201 @@
+/*******************************************************************************
+ * Copyright (c) 2005 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.internal.datashare;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Random;
+import java.util.Timer;
+import java.util.TimerTask;
+
+import org.eclipse.ecf.core.ISharedObjectConfig;
+import org.eclipse.ecf.core.SharedObjectInitException;
+import org.eclipse.ecf.core.events.ISharedObjectActivatedEvent;
+import org.eclipse.ecf.core.events.ISharedObjectContainerDepartedEvent;
+import org.eclipse.ecf.core.events.ISharedObjectContainerJoinedEvent;
+import org.eclipse.ecf.core.events.ISharedObjectMessageEvent;
+import org.eclipse.ecf.core.identity.ID;
+import org.eclipse.ecf.core.util.Event;
+
+/**
+ * @author pnehrer
+ */
+public class EagerElectionBootstrap implements IBootstrap {
+
+ private final Random random = new Random();
+
+ private Agent agent;
+
+ private ISharedObjectConfig config;
+
+ private ID coordinatorID;
+
+ private Election election;
+
+ private final Timer timer = new Timer();
+
+ private TimerTask task;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ecf.internal.datashare.IBootstrap#setAgent(org.eclipse.ecf.internal.datashare.Agent)
+ */
+ public void setAgent(Agent agent) {
+ this.agent = agent;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ecf.internal.datashare.IBootstrap#init(org.eclipse.ecf.core.ISharedObjectConfig)
+ */
+ public void init(ISharedObjectConfig config)
+ throws SharedObjectInitException {
+ this.config = config;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ecf.internal.datashare.IBootstrap#handleEvent(org.eclipse.ecf.core.util.Event)
+ */
+ public void handleEvent(Event event) {
+ if (event instanceof ISharedObjectActivatedEvent) {
+ ISharedObjectActivatedEvent e = (ISharedObjectActivatedEvent) event;
+ if (e.getActivatedID().equals(config.getSharedObjectID()))
+ handleActivated();
+ } else if (event instanceof ISharedObjectContainerJoinedEvent) {
+ ISharedObjectContainerJoinedEvent e = (ISharedObjectContainerJoinedEvent) event;
+ if (!e.getJoinedContainerID().equals(e.getLocalContainerID()))
+ handleJoined(e.getJoinedContainerID());
+ } else if (event instanceof ISharedObjectContainerDepartedEvent) {
+ ISharedObjectContainerDepartedEvent e = (ISharedObjectContainerDepartedEvent) event;
+ if (!e.getDepartedContainerID().equals(e.getLocalContainerID()))
+ handleDeparted(e.getDepartedContainerID());
+ } else if (event instanceof ISharedObjectMessageEvent) {
+ ISharedObjectMessageEvent e = (ISharedObjectMessageEvent) event;
+ if (e.getData() instanceof Vote)
+ handleVote((Vote) e.getData(), e.getRemoteContainerID());
+ else if (e.getData() instanceof Elected)
+ handleElected(e.getRemoteContainerID());
+ else if (e.getData() instanceof Ping)
+ handlePing();
+ }
+ }
+
+ private synchronized void handleActivated() {
+ if (config.getHomeContainerID().equals(
+ config.getContext().getLocalContainerID())) {
+ coordinatorID = config.getContext().getLocalContainerID();
+ timer.schedule(task = new Pinger(), 1000, 1000); // TODO make configurable
+ } else {
+ timer.schedule(task = new PingWatch(), 2000); // TODO make configurable
+ }
+ }
+
+ private synchronized void handleJoined(ID containerID) {
+ // TODO what if election is pending?
+ if (config.getContext().getLocalContainerID().equals(coordinatorID))
+ agent.doBootstrap(containerID);
+ }
+
+ private synchronized void handleVote(Vote msg, ID containerID) {
+ if (election != null) {
+ switch (election.processVote(msg.getTicket(), containerID)) {
+ case Election.WON:
+ processVictory();
+ case Election.LOST:
+ election = null;
+ }
+ }
+ }
+
+ private synchronized void handleElected(ID containerID) {
+ election = null;
+ coordinatorID = containerID;
+ timer.schedule(task = new PingWatch(), 2000);
+ }
+
+ private synchronized void handleDeparted(ID containerID) {
+ if (containerID.equals(coordinatorID))
+ startElection();
+ }
+
+ private void handlePing() {
+ if (task != null)
+ task.cancel();
+
+ timer.schedule(task = new PingWatch(), 2000);
+ }
+
+ private synchronized void startElection() {
+ if (task != null)
+ task.cancel();
+
+ List members = Arrays.asList(config.getContext().getGroupMemberIDs());
+ members.remove(config.getContext().getLocalContainerID());
+ if (members.isEmpty())
+ processVictory();
+ else {
+ long ticket = random.nextLong(); // TODO strategize this
+ election = new Election(ticket, members);
+ try {
+ config.getContext().sendMessage(null, new Vote(ticket, null));
+ } catch (IOException e) {
+ handleError(e);
+ }
+ }
+ }
+
+ private void processVictory() {
+ try {
+ config.getContext().sendMessage(null, new Elected(null));
+ coordinatorID = config.getContext().getLocalContainerID();
+ timer.schedule(task = new Pinger(), 1000, 1000);
+ } catch (IOException e) {
+ handleError(e);
+ }
+ }
+
+ private void handleError(Throwable t) {
+ t.printStackTrace();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ecf.internal.datashare.IBootstrap#dispose(org.eclipse.ecf.core.identity.ID)
+ */
+ public void dispose(ID containerID) {
+ timer.cancel();
+ config = null;
+ }
+
+ private class Pinger extends TimerTask {
+
+ public void run() {
+ try {
+ config.getContext().sendMessage(null, new Ping());
+ } catch (IOException e) {
+ handleError(e);
+ }
+ }
+ }
+
+ private class PingWatch extends TimerTask {
+
+ public void run() {
+ startElection();
+ }
+ }
+}
diff --git a/framework/bundles/org.eclipse.ecf.datashare/src/org/eclipse/ecf/internal/datashare/Election.java b/framework/bundles/org.eclipse.ecf.datashare/src/org/eclipse/ecf/internal/datashare/Election.java
new file mode 100644
index 000000000..cd8c74466
--- /dev/null
+++ b/framework/bundles/org.eclipse.ecf.datashare/src/org/eclipse/ecf/internal/datashare/Election.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2005 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.internal.datashare;
+
+import java.util.Collection;
+import java.util.HashSet;
+
+import org.eclipse.ecf.core.identity.ID;
+
+/**
+ * @author pnehrer
+ */
+public class Election {
+
+ public static final short LOST = 0;
+
+ public static final short WON = 1;
+
+ public static final short UNKNOWN = 2;
+
+ private final long ticket;
+
+ private final HashSet members;
+
+ public Election(long ticket, Collection members) {
+ this.ticket = ticket;
+ this.members = new HashSet(members);
+ }
+
+ public synchronized short processVote(long ticket, ID containerID) {
+ if (this.ticket < ticket)
+ return LOST;
+ else {
+ members.remove(containerID);
+ return members.isEmpty() ? WON : UNKNOWN;
+ }
+ }
+
+ public synchronized short disqualify(ID containerID) {
+ members.remove(containerID);
+ return members.isEmpty() ? WON : UNKNOWN;
+ }
+} \ No newline at end of file
diff --git a/framework/bundles/org.eclipse.ecf.datashare/src/org/eclipse/ecf/internal/datashare/IBootstrap.java b/framework/bundles/org.eclipse.ecf.datashare/src/org/eclipse/ecf/internal/datashare/IBootstrap.java
new file mode 100644
index 000000000..bab96abc3
--- /dev/null
+++ b/framework/bundles/org.eclipse.ecf.datashare/src/org/eclipse/ecf/internal/datashare/IBootstrap.java
@@ -0,0 +1,18 @@
+package org.eclipse.ecf.internal.datashare;
+
+import org.eclipse.ecf.core.ISharedObjectConfig;
+import org.eclipse.ecf.core.SharedObjectInitException;
+import org.eclipse.ecf.core.identity.ID;
+import org.eclipse.ecf.core.util.Event;
+
+public interface IBootstrap {
+
+ void setAgent(Agent agent);
+
+ void init(ISharedObjectConfig config) throws SharedObjectInitException;
+
+ void handleEvent(Event event);
+
+ void dispose(ID containerID);
+
+} \ No newline at end of file
diff --git a/framework/bundles/org.eclipse.ecf.datashare/src/org/eclipse/ecf/internal/datashare/LazyElectionBootstrap.java b/framework/bundles/org.eclipse.ecf.datashare/src/org/eclipse/ecf/internal/datashare/LazyElectionBootstrap.java
new file mode 100644
index 000000000..7a9c52769
--- /dev/null
+++ b/framework/bundles/org.eclipse.ecf.datashare/src/org/eclipse/ecf/internal/datashare/LazyElectionBootstrap.java
@@ -0,0 +1,160 @@
+/*******************************************************************************
+ * Copyright (c) 2005 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.internal.datashare;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+
+import org.eclipse.ecf.core.ISharedObjectConfig;
+import org.eclipse.ecf.core.SharedObjectInitException;
+import org.eclipse.ecf.core.events.ISharedObjectContainerDepartedEvent;
+import org.eclipse.ecf.core.events.ISharedObjectContainerJoinedEvent;
+import org.eclipse.ecf.core.events.ISharedObjectMessageEvent;
+import org.eclipse.ecf.core.identity.ID;
+import org.eclipse.ecf.core.util.Event;
+
+/**
+ * @author pnehrer
+ */
+public class LazyElectionBootstrap implements IBootstrap {
+
+ private final Random random = new Random();
+
+ private Agent agent;
+
+ private ISharedObjectConfig config;
+
+ private final HashMap elections = new HashMap();
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ecf.internal.datashare.IBootstrap#setAgent(org.eclipse.ecf.internal.datashare.Agent)
+ */
+ public void setAgent(Agent agent) {
+ this.agent = agent;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ecf.internal.datashare.IBootstrap#init(org.eclipse.ecf.core.ISharedObjectConfig)
+ */
+ public void init(ISharedObjectConfig config)
+ throws SharedObjectInitException {
+ this.config = config;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ecf.internal.datashare.IBootstrap#handleEvent(org.eclipse.ecf.core.util.Event)
+ */
+ public void handleEvent(Event event) {
+ if (event instanceof ISharedObjectContainerJoinedEvent) {
+ ISharedObjectContainerJoinedEvent e = (ISharedObjectContainerJoinedEvent) event;
+ if (!e.getJoinedContainerID().equals(e.getLocalContainerID()))
+ handleJoined(e.getJoinedContainerID());
+ } else if (event instanceof ISharedObjectContainerDepartedEvent) {
+ ISharedObjectContainerDepartedEvent e = (ISharedObjectContainerDepartedEvent) event;
+ if (!e.getDepartedContainerID().equals(e.getLocalContainerID()))
+ handleDeparted(e.getDepartedContainerID());
+ } else if (event instanceof ISharedObjectMessageEvent) {
+ ISharedObjectMessageEvent e = (ISharedObjectMessageEvent) event;
+ if (e.getData() instanceof Vote)
+ handleVote((Vote) e.getData(), e.getRemoteContainerID());
+ else if (e.getData() instanceof Elected)
+ handleElected((Elected) e.getData());
+ }
+ }
+
+ private void handleJoined(ID containerID) {
+ List members = Arrays.asList(config.getContext().getGroupMemberIDs());
+ members.remove(containerID);
+ members.remove(config.getContext().getLocalContainerID());
+ if (members.isEmpty())
+ processVictory(containerID);
+ else {
+ long ticket = random.nextLong(); // TODO strategize this
+ Election election = new Election(ticket, members);
+ synchronized (elections) {
+ elections.put(containerID, election);
+ }
+
+ try {
+ config.getContext().sendMessage(null,
+ new Vote(ticket, containerID));
+ } catch (IOException e) {
+ handleError(e);
+ }
+ }
+ }
+
+ private void handleVote(Vote msg, ID containerID) {
+ synchronized (elections) {
+ Election election = (Election) elections.get(msg.getElectionID());
+ if (election != null) {
+ switch (election.processVote(msg.getTicket(), containerID)) {
+ case Election.WON:
+ processVictory(msg.getElectionID());
+ case Election.LOST:
+ elections.remove(msg.getElectionID());
+ }
+ }
+ }
+ }
+
+ private void handleElected(Elected msg) {
+ synchronized (elections) {
+ elections.remove(msg.getElectionID());
+ }
+ }
+
+ private void handleDeparted(ID containerID) {
+ synchronized (elections) {
+ for (Iterator i = elections.entrySet().iterator(); i.hasNext();) {
+ Map.Entry entry = (Map.Entry) i.next();
+ ID electionID = (ID) entry.getKey();
+ if (containerID.equals(electionID))
+ i.remove();
+ else {
+ Election election = (Election) entry.getValue();
+ switch (election.disqualify(containerID)) {
+ case Election.WON:
+ processVictory(electionID);
+ case Election.LOST:
+ i.remove();
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ private void processVictory(ID electionID) {
+ try {
+ config.getContext().sendMessage(null, new Elected(electionID));
+ agent.doBootstrap(electionID);
+ } catch (IOException e) {
+ handleError(e);
+ }
+ }
+
+ private void handleError(Throwable t) {
+ t.printStackTrace();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ecf.internal.datashare.IBootstrap#dispose(org.eclipse.ecf.core.identity.ID)
+ */
+ public void dispose(ID containerID) {
+ config = null;
+ }
+}
diff --git a/framework/bundles/org.eclipse.ecf.datashare/src/org/eclipse/ecf/internal/datashare/Ping.java b/framework/bundles/org.eclipse.ecf.datashare/src/org/eclipse/ecf/internal/datashare/Ping.java
new file mode 100644
index 000000000..7759a0ac3
--- /dev/null
+++ b/framework/bundles/org.eclipse.ecf.datashare/src/org/eclipse/ecf/internal/datashare/Ping.java
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * Copyright (c) 2005 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.internal.datashare;
+
+import java.io.Serializable;
+
+/**
+ * @author pnehrer
+ *
+ */
+public class Ping implements Serializable {
+
+ private static final long serialVersionUID = 3258131340921812018L;
+
+}
diff --git a/framework/bundles/org.eclipse.ecf.datashare/src/org/eclipse/ecf/internal/datashare/ServerBootstrap.java b/framework/bundles/org.eclipse.ecf.datashare/src/org/eclipse/ecf/internal/datashare/ServerBootstrap.java
new file mode 100644
index 000000000..5dca4a0ca
--- /dev/null
+++ b/framework/bundles/org.eclipse.ecf.datashare/src/org/eclipse/ecf/internal/datashare/ServerBootstrap.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (c) 2005 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.internal.datashare;
+
+import org.eclipse.ecf.core.ISharedObjectConfig;
+import org.eclipse.ecf.core.SharedObjectInitException;
+import org.eclipse.ecf.core.events.ISharedObjectContainerJoinedEvent;
+import org.eclipse.ecf.core.identity.ID;
+import org.eclipse.ecf.core.util.Event;
+
+/**
+ * @author pnehrer
+ */
+public class ServerBootstrap implements IBootstrap {
+
+ private Agent agent;
+
+ private ISharedObjectConfig config;
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ecf.internal.datashare.IBootstrap#setAgent(org.eclipse.ecf.internal.datashare.Agent)
+ */
+ public void setAgent(Agent agent) {
+ this.agent = agent;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ecf.internal.datashare.IBootstrap#init(org.eclipse.ecf.core.ISharedObjectConfig)
+ */
+ public void init(ISharedObjectConfig config)
+ throws SharedObjectInitException {
+ this.config = config;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ecf.internal.datashare.IBootstrap#handleEvent(org.eclipse.ecf.core.util.Event)
+ */
+ public void handleEvent(Event event) {
+ if (event instanceof ISharedObjectContainerJoinedEvent) {
+ ISharedObjectContainerJoinedEvent e = (ISharedObjectContainerJoinedEvent) event;
+ if (!e.getJoinedContainerID().equals(e.getLocalContainerID()))
+ handleJoined(e.getJoinedContainerID());
+ }
+ }
+
+ private void handleJoined(ID containerID) {
+ if (config.getContext().isGroupServer()) // TODO how about isGroupManager()?
+ agent.doBootstrap(containerID);
+ }
+
+ private void handleError(Throwable t) {
+ t.printStackTrace();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ecf.internal.datashare.IBootstrap#dispose(org.eclipse.ecf.core.identity.ID)
+ */
+ public void dispose(ID containerID) {
+ config = null;
+ }
+}

Back to the top