aboutsummaryrefslogtreecommitdiff
path: root/src/Ivy.java
diff options
context:
space:
mode:
authorjestin2012-05-13 08:54:38 +0000
committerjestin2012-05-13 08:54:38 +0000
commite854a58a81ec90e419a4b3effa5a83caac05df90 (patch)
tree16eb84a66b62ff38e744c8cd474df81561436b9f /src/Ivy.java
parent4ffe8b84071babe544086f94c66431380d301d59 (diff)
downloadivy-java-e854a58a81ec90e419a4b3effa5a83caac05df90.zip
ivy-java-e854a58a81ec90e419a4b3effa5a83caac05df90.tar.gz
ivy-java-e854a58a81ec90e419a4b3effa5a83caac05df90.tar.bz2
ivy-java-e854a58a81ec90e419a4b3effa5a83caac05df90.tar.xz
Modified the tests to remove bus.getDomain(null)
make Waiter and WaiterClient sons of WaitFor Added a few tests into svn
Diffstat (limited to 'src/Ivy.java')
-rwxr-xr-xsrc/Ivy.java188
1 files changed, 63 insertions, 125 deletions
diff --git a/src/Ivy.java b/src/Ivy.java
index 6f00062..f894ee4 100755
--- a/src/Ivy.java
+++ b/src/Ivy.java
@@ -11,11 +11,12 @@
*<pre>
*Ivy bus = new Ivy("Dummy agent","ready",null);
*bus.bindMsg("(.*)",myMessageListener);
- *bus.start(getDomain(null));
+ *bus.start(null);
*</pre>
*
* CHANGELOG:
* 1.2.16
+ * - API break: getIvyClients now returns a Collection, instead of a Vector
* - fixes a concurent exception in the stop() method (no more
* removeClient , triggered in the SendNow test)
* - now uses the synchronized wrappers of the Java API for all collections
@@ -127,40 +128,36 @@
* fixed the printStackTrace upon closing of the ServerSocket after a close()
*/
package fr.dgac.ivy;
+
import java.net.*;
import java.io.*;
import gnu.getopt.Getopt;
import java.util.regex.*;
import java.util.Vector;
import java.util.Collections;
+import java.util.Collection;
+import java.util.List;
import java.util.Map;
import java.util.HashMap;
+import java.util.ArrayList;
import java.util.Properties;
import java.util.StringTokenizer;
public class Ivy implements Runnable {
/**
- * the port for the UDP rendez vous, if none is supplied.
- */
- public static final int DEFAULT_PORT = 2010;
-
- /**
* the default size of the IvyClients' socket buffer
* defaults to 4096, can be adjusted through the use of IVY_BUFFERSIZE JVM
* property
*/
private static final int PREFFERREDBUFFERSIZE = 4096; // in bytes
- /**
- * the domain for the UDP rendez vous.
- */
- public static final String DEFAULT_DOMAIN = "127.255.255.255:" + DEFAULT_PORT;
+
/**
* the library version, useful for development purposes only, when java is
* invoked with -DIVY_DEBUG
*/
- public static final String LIBVERSION ="1.2.16";
+ private static final String LIBVERSION ="1.2.16";
/*
* private fields
@@ -178,7 +175,7 @@ public class Ivy implements Runnable {
private Object lockApp = new Object();
private boolean debug;
private ServerSocket app;
- private Vector<IvyWatcher> watchers = new Vector<IvyWatcher>();
+ private Collection<IvyWatcher> watchers = new ArrayList<IvyWatcher>();
private volatile Thread serverThread; // to ensure quick communication of the end
private Map<Integer,IvyClient> clients = Collections.synchronizedMap(new HashMap<Integer,IvyClient>());
private Map<Integer,IvyClient> half = Collections.synchronizedMap(new HashMap<Integer,IvyClient>());
@@ -204,8 +201,10 @@ public class Ivy implements Runnable {
/**
* Readies the structures for the software bus connexion.
+ * The typical use of the constructor is the following
+ * <br><code>Ivy bus = new Ivy("AgentName", "AgentName ready", null);</code>
+ * <br>All the dirty work is done un the start() method
*
- * All the dirty work is done un the start() method
* @see #start
* @param name The name of your Ivy agent on the software bus
* @param message The hellow message you will send once ready. It can be
@@ -262,13 +261,11 @@ public class Ivy implements Runnable {
}
// first check if client with the same name is on the bus
ic = alreadyThere(clients , name);
- if (ic != null) {
- return ic;
- }
+ if (ic != null) return ic;
// if not enter the waiting loop
WaiterClient w = new WaiterClient(name , timeout , clients);
int i = addApplicationListener(w);
- ic = w.waitForClient();
+ ic = w.waitFor();
removeApplicationListener(i);
return ic;
}
@@ -286,6 +283,34 @@ public class Ivy implements Runnable {
}
/**
+ * returns the domain bus.
+ * @deprecated if needed, use bus.start(null), and it will be called
+ * automatically
+ *
+ * @param domainbus if non null, returns the argument
+ * @return It returns domainbus, if non null,
+ * otherwise it returns the IVYBUS property if non null, otherwise it
+ * returns Ivy.DEFAULT_DOMAIN
+ */
+ @Deprecated public static final String getDomain(final String domainbus) {
+ return Domain.getDomain(domainbus);
+ }
+
+ /**
+ * returns the domain bus.
+ * @deprecated if needed, use Domain.getDomainArgs
+ *
+ * @since 1.2.8
+ * @param progname The name of your program, for error message
+ * @param args the String[] of arguments passed to your main()
+ * @return returns the domain bus, ascending priority : ivy default bus, IVY_BUS
+ * property, -b domain on the command line
+ */
+ @Deprecated public static final String getDomainArgs(final String progname, final String[] args) {
+ return Domain.getDomainArgs(progname, args);
+ }
+
+ /**
* connects the Ivy bus to a domain or list of domains.
*
* <li>One thread (IvyWatcher) for each traffic rendezvous (either UDP broadcast or TCPMulticast)
@@ -310,9 +335,7 @@ public class Ivy implements Runnable {
setStarting(true); // this will remain true entil one of the PacketSenders has finished
stopped=false;
String db = domainbus;
- if (db == null) {
- db = getDomain(null);
- }
+ if (db == null) db = Domain.getDomain(null);
Properties sysProp = System.getProperties();
sysProp.put("IVYBUS" , db);
String range = (String)sysProp.get("IVYRANGE");
@@ -348,11 +371,11 @@ public class Ivy implements Runnable {
}
traceDebug("lib: " + LIBVERSION + " protocol: " + Protocol.PROTOCOLVERSION + " TCP service open on port " + applicationPort);
- Domain[] d = parseDomains(db);
- if (d.length == 0) throw new IvyException("no domain found in " + db);
+ List<Domain> d = Domain.parseDomains(db);
+ if (d.size() == 0) throw new IvyException("no domain found in " + db);
watcherId = getWBUId().replace(' ' , '*'); // no space in the watcherId
// readies the rendezvous : an IvyWatcher (thread) per domain bus
- for (Domain dom: d) watchers.addElement(new IvyWatcher(this , dom.domainaddr , dom.port));
+ for (Domain dom: d) watchers.add(new IvyWatcher(this , dom.getDomainaddr() , dom.getPort()));
serverThread = new Thread(this);
serverThread.setName("Ivy TCP server Thread");
serverThread.setDaemon(true);
@@ -361,29 +384,6 @@ public class Ivy implements Runnable {
for (IvyWatcher iw: watchers) iw.doStart();
}
- protected final Domain[] parseDomains(final String domainbus) {
- StringTokenizer st = new StringTokenizer(domainbus , ",");
- Domain[] d = new Domain[st.countTokens()];
- int index = 0;
- while ( st.hasMoreTokens()) {
- String s = st.nextToken();
- try {
- d[index++] = new Domain(IvyWatcher.getDomain(s) , IvyWatcher.getPort(s));
- } catch (IvyException ie) {
- // do nothing
- ie.printStackTrace();
- }
- }
- // fixes the port values ...
- int lastport = Ivy.DEFAULT_PORT;
- for (index--; index >= 0; index--) {
- Domain dom = d[index];
- if (dom.port == 0) dom.port = lastport;
- lastport = dom.port;
- }
- return d;
- }
-
private void waitForRemote(String s) {
try {
@@ -675,12 +675,16 @@ public class Ivy implements Runnable {
* sets the filter expression.
* @param f the extensive list of strings beginning the messages
* @since 1.2.9
+ * @throws IvyException if a filter is already set or the bus is already
+ * started
*
* once this filter is set, when a client subscribes to a regexp of the
* form "^dummystring...", there is a check against the filter list. If no
* keyword is found to match, the binding is just ignored.
*/
- public final synchronized void setFilter(final String[] f){
+ public final synchronized void setFilter(final String[] f) throws IvyException {
+ if (filter != null) throw new IvyException("only one filter can be set");
+ if (!stopped) throw new IvyException("cannot set a filter on a bus that's already started");
filter = java.util.Arrays.copyOf(f , f.length);
}
@@ -769,13 +773,13 @@ public class Ivy implements Runnable {
}
/**
- * gives the (Vectored) list of IvyClient at a given instant.
- * @return a vector of IvyClients
+ * gives a list of IvyClient at a given instant.
+ * @return a collection of IvyClients
*/
- public final Vector<IvyClient> getIvyClients() {
- Vector<IvyClient> v = new Vector<IvyClient>();
+ public final Collection<IvyClient> getIvyClients() {
+ Collection<IvyClient> v = new ArrayList<IvyClient>();
synchronized (clients) {
- for (IvyClient ic : clients.values() ) if (ic != null) v.addElement(ic);
+ for (IvyClient ic : clients.values() ) if (ic != null) v.add(ic);
}
return v;
}
@@ -786,51 +790,19 @@ public class Ivy implements Runnable {
* @param name The name of the Ivy agent you're looking for
* @return a vector of IvyClients
*/
- public final Vector<IvyClient> getIvyClientsByName(final String name) {
- Vector<IvyClient> v = new Vector<IvyClient>();
+ public final Collection<IvyClient> getIvyClientsByName(final String name) {
+ Collection<IvyClient> v = new ArrayList<IvyClient>();
String icname;
synchronized (clients) {
for (IvyClient ic : clients.values() ) {
if ( (ic == null)||((icname = ic.getApplicationName()) == null) ) break;
- if (icname.compareTo(name) == 0) v.addElement(ic);
+ if (icname.compareTo(name) == 0) v.add(ic);
}
}
return v;
}
/**
- * returns the domain bus.
- *
- * @param domainbus if non null, returns the argument
- * @return It returns domainbus, if non null,
- * otherwise it returns the IVYBUS property if non null, otherwise it
- * returns Ivy.DEFAULT_DOMAIN
- */
- public static final String getDomain(final String domainbus) {
- String db = null;
- db = domainbus;
- if ( db == null ) db = System.getProperty("IVYBUS");
- if ( db == null ) db = DEFAULT_DOMAIN;
- return db;
- }
-
- /**
- * returns the domain bus.
- *
- * @since 1.2.8
- * @param progname The name of your program, for error message
- * @param args the String[] of arguments passed to your main()
- * @return returns the domain bus, ascending priority : ivy default bus, IVY_BUS
- * property, -b domain on the command line
- */
- public static final String getDomainArgs(final String progname, final String[] args) {
- Getopt opt = new Getopt(progname , args , "b:");
- int c;
- if ( ((c = opt.getopt()) != -1) && c == 'b' ) return opt.getOptarg();
- return getDomain(null);
- }
-
- /**
* returns a "wana be unique" ID to make requests on the bus.
*
* @since 1.2.8
@@ -841,18 +813,6 @@ public class Ivy implements Runnable {
}
private synchronized long nextId() { return current++; }
-
- /**
- * prints a human readable representation of the list of domains.
- *
- * @since 1.2.9
- */
- public String domains(String toparse) {
- StringBuffer s = new StringBuffer();
- Ivy.Domain[] d = parseDomains(toparse);
- for (Ivy.Domain dd : d) s.append(dd.getDomainaddr() + ":" + dd.getPort() + " ");
- return s.toString();
- }
/////////////////////////////////////////////////////////////////:
//
// Protected methods
@@ -916,24 +876,10 @@ public class Ivy implements Runnable {
traceDebug("removed " + c + " from half: " + getClientNames(half));
}
- /*
- private synchronized boolean shouldIleave(IvyClient ic) {
- traceDebug("looking for " + ic + " in " + getClientNames(half) + " and " + getClientNames(clients));
- IvyClient peer = searchPeer(ic);
- if (peer == null) return false;
- boolean shoulda = peer.distanceTo(ic)>0;
- traceDebug(ic + " " + ic.toStringExt() + ((shoulda) ? " must leave " : " must not leave"));
- traceDebug(peer + " " + peer.toStringExt() + ((!shoulda) ? " must leave " : " must not leave"));
- return shoulda;
- }
- */
-
private synchronized IvyClient searchPeer(IvyClient ic) {
- //synchronized(lock) {
- synchronized (clients) {
- for (IvyClient peer : clients.values()) if ((peer != null)&&(peer.equals(ic))) return peer;
- }
- //}
+ synchronized (clients) {
+ for (IvyClient peer : clients.values()) if ((peer != null)&&(peer.equals(ic))) return peer;
+ }
return null;
}
@@ -1013,13 +959,5 @@ public class Ivy implements Runnable {
return s.toString();
}
- private static class Domain {
- private String domainaddr;
- private int port;
- public Domain(String ddomainaddr , int dport) { this.domainaddr = ddomainaddr;this.port = dport; }
- public String toString() { return domainaddr + ":" + port; }
- public String getDomainaddr() { return domainaddr; }
- public int getPort() { return port; }
- }
-} // class Ivy
+}