From e854a58a81ec90e419a4b3effa5a83caac05df90 Mon Sep 17 00:00:00 2001 From: jestin Date: Sun, 13 May 2012 08:54:38 +0000 Subject: Modified the tests to remove bus.getDomain(null) make Waiter and WaiterClient sons of WaitFor Added a few tests into svn --- src/Ivy.java | 188 ++++++++++++++++++++--------------------------------------- 1 file changed, 63 insertions(+), 125 deletions(-) (limited to 'src/Ivy.java') 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 @@ *
  *Ivy bus = new Ivy("Dummy agent","ready",null);
  *bus.bindMsg("(.*)",myMessageListener);
- *bus.start(getDomain(null));
+ *bus.start(null);
  *
* * 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 watchers = new Vector(); + private Collection watchers = new ArrayList(); private volatile Thread serverThread; // to ensure quick communication of the end private Map clients = Collections.synchronizedMap(new HashMap()); private Map half = Collections.synchronizedMap(new HashMap()); @@ -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 + *
Ivy bus = new Ivy("AgentName", "AgentName ready", null); + *
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. * *
  • 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 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 getIvyClients() { - Vector v = new Vector(); + public final Collection getIvyClients() { + Collection v = new ArrayList(); 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 getIvyClientsByName(final String name) { - Vector v = new Vector(); + public final Collection getIvyClientsByName(final String name) { + Collection v = new ArrayList(); 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 +} -- cgit v1.1