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/After.java | 9 ++- src/BindType.java | 7 +- src/Domain.java | 177 ++++++++++++++++++++++++++++++++++++++++++++++ src/Ivy.java | 188 +++++++++++++++++-------------------------------- src/IvyClient.java | 4 +- src/IvyDaemon.java | 5 +- src/IvyWatcher.java | 63 +---------------- src/Probe.java | 35 ++++----- src/Protocol.java | 4 +- src/ProxyClient.java | 12 ++-- src/ProxyMaster.java | 20 +++--- src/SelfIvyClient.java | 1 - src/WaitFor.java | 55 +++++++++++++++ src/Waiter.java | 50 +++---------- src/WaiterClient.java | 65 ++++++----------- 15 files changed, 379 insertions(+), 316 deletions(-) create mode 100644 src/Domain.java create mode 100644 src/WaitFor.java (limited to 'src') diff --git a/src/After.java b/src/After.java index 7b5af07..ea164fb 100644 --- a/src/After.java +++ b/src/After.java @@ -1,11 +1,14 @@ /** - * an utility waiting for a message to come, then exiting + * an utility waiting for a message to come, then exiting. + * * the typical use is to stop a script execution flow until a message has been * received in a shell script the following way * - * echo "waiting for Toto" + *
+ * echo "waiting for Toto" * java -classpath ivy-java.jar fr.dgac.ivy.tools.After -b 224.5.6.7:8910 "Toto READY" * echo "Toto is here, continuing". + * * * @author Yannick Jestin * @author http://www.tls.cena.fr/products/ivy/ @@ -31,7 +34,7 @@ public class After extends IvyApplicationAdapter implements IvyMessageListener { public static void main(String[] args) throws IvyException { Getopt opt = new Getopt("After",args,"b:t:"); int c; - String domain=Ivy.getDomain(null); + String domain=null; String name="AFTER"; int timeout = DEFAULTTIMEOUT; while ((c = opt.getopt()) != -1) switch (c) { diff --git a/src/BindType.java b/src/BindType.java index 6784725..428bbd5 100644 --- a/src/BindType.java +++ b/src/BindType.java @@ -1,8 +1,7 @@ /** - * Ivy software bus package Enum helper utility, used to choose whether the - * callbacks will be performed in the same thread of the ivy protocol - * handling, or in the the Swing Thread, or in a newly created thread. - * @see Ivy.bindAsyncMsg + * Ivy software bus package Enum helper utility, used from {@link Ivy.bindAsyncMsg} to choose whether the + * callbacks will be performed either in the same thread of the ivy protocol * handling, or in the the Swing Thread, or in a newly created thread. + * * * @author Yannick Jestin yannick.jestin&enac.fr diff --git a/src/Domain.java b/src/Domain.java new file mode 100644 index 0000000..1d13e25 --- /dev/null +++ b/src/Domain.java @@ -0,0 +1,177 @@ +/** + * Intern representation of a domain, plus a set of helper static methods to + * parse strings like 127:2010,224.5.6.7:8910. + * + * Usually, you don't have to use this, and just rely on {@link bus.start} + * with a null parameter. However, if you want to parse a command line + * parameter, or output the result of Ivy libary guessing order, then you can + * use those methods. + * + * @author Yannick Jestin yannick.jestin&enac.fr + * @since 1.2.16 + */ +package fr.dgac.ivy; + +import java.util.regex.*; +import java.util.Collections; +import java.util.Collection; +import java.util.List; +import java.util.ArrayList; +import gnu.getopt.Getopt; + +public class Domain { + + /** + * the port for the UDP rendez vous, if none is supplied. + */ + public static final int DEFAULT_PORT = 2010; + + /** + * the domain for the UDP rendez vous. + */ + public static final String DEFAULT_DOMAIN = "127.255.255.255:" + DEFAULT_PORT; + + // private fields + private String domainaddr; + private int port; + private static Pattern numbersPoint, exp; + + public Domain(String ddomainaddr , int dport) { this.domainaddr = ddomainaddr;this.port = dport; } + + @Override public String toString() { return domainaddr + ":" + port; } + + // accessors + public String getDomainaddr() { return domainaddr; } + public int getPort() { return port; } + + + static { + try { + numbersPoint = Pattern.compile("([0-9]|\\.)+"); + exp = Pattern.compile( "^(\\d+\\.\\d+\\.\\d+\\.\\d+).*"); + } catch (PatternSyntaxException res) { + res.printStackTrace(); + System.out.println("Regular Expression bug in Ivy source code ... bailing out"); + throw new RuntimeException(); + } + } + + + 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; + } + + /* + private boolean isInDomain( InetAddress host ){ + return true; + // TODO check if this function is useful. for now, it always returns true + // deprecated since we use Multicast. How to check when we are in UDP + // broadcast ? + // + byte rem_addr[] = host.getAddress(); + for ( int i = 0 ; i < domainaddrList.size(); i++ ) { + byte addr[] = ((InetAddress)domainaddrList.elementAt(i)).getAddress(); + int j ; + for ( j = 0 ; j < 4 ; j++ ) + if ( (addr[j] != -1) && (addr[j] != rem_addr[j]) ) break; + if ( j == 4 ) { + traceDebug( "host " + host + " is in domain\n" ); + return true; + } + } + traceDebug( "host " + host + " Not in domain\n" ); + return false; + } + */ + + private static int extractPort(String net) { // returns 0 if no port is set + int sep_index = net.lastIndexOf( ":" ); + int port= ( sep_index == -1 ) ? 0 :Integer.parseInt( net.substring( sep_index +1 )); + // System.out.println("net: ["+net+"]\nsep_index: "+sep_index+"\nport: "+port); + //System.out.println("next port: "+port); + return port; + } + + private static String expandDomain(String net) throws IvyException { + // System.out.println("debug: net=[" + net+ "]"); + int sep_index = net.lastIndexOf( ":" ); + if ( sep_index != -1 ) { net = net.substring(0,sep_index); } + try { + Matcher m = numbersPoint.matcher(net); + if (!m.matches()) { + // traceDebug("should only have numbers and point ? I won't add anything... " + net); + return "127.255.255.255"; + // return net; + } + net += ".255.255.255"; + Matcher mm= exp.matcher(net); + if (!mm.matches()) { + System.out.println("Bad broascat addr " + net); + throw new IvyException("bad broadcast addr"); + } + net=mm.group(1); + } catch ( PatternSyntaxException e ){ + e.printStackTrace(); + throw new RuntimeException(); + } + //System.out.println("next domain: "+net); + return net; + } + + /** + * 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); + } + + final static List parseDomains(final String domainbus) { + // assert(domainbus!=null); + List d = new ArrayList(); + for (String s: domainbus.split(",")) { + try { + d.add(new Domain(expandDomain(s) , extractPort(s))); + } catch (IvyException ie) { + // do nothing + ie.printStackTrace(); + } + } + // fixes the port values ... + Collections.reverse(d); + int lastport = DEFAULT_PORT; + for (Domain dom : d) { + if (dom.port == 0) dom.port = lastport; + lastport = dom.port; + } + Collections.reverse(d); + return d; + } + + + /** + * prints a human readable representation of the list of domains. + * + * @since 1.2.9 + */ + static public String domains(String toparse) { + StringBuffer s = new StringBuffer(); + if (toparse == null) toparse = getDomain(toparse); + for (Domain dd : parseDomains(toparse)) s.append(dd.getDomainaddr() + ":" + dd.getPort() + " "); + return s.toString(); + } + +} 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 +} diff --git a/src/IvyClient.java b/src/IvyClient.java index 8e20d2d..aadbd0b 100755 --- a/src/IvyClient.java +++ b/src/IvyClient.java @@ -113,7 +113,6 @@ public class IvyClient extends Thread { private static int clientSerial=0; /* an unique ID for each IvyClient */ private SortedMap PingCallbacksTable = Collections.synchronizedSortedMap(new TreeMap()); - private Ivy bus; private Socket socket; private BufferedReader in; @@ -133,7 +132,8 @@ public class IvyClient extends Thread { // int protocol; private boolean incoming; - IvyClient() { } + + IvyClient() { } // required for SelfIvyClient FIXME ?! IvyClient(Ivy bus, Socket socket,int remotePort,boolean incoming) throws IOException { synchronized(lock) { clientKey=clientSerial++; } diff --git a/src/IvyDaemon.java b/src/IvyDaemon.java index 6fc884d..f99202d 100644 --- a/src/IvyDaemon.java +++ b/src/IvyDaemon.java @@ -39,7 +39,6 @@ import gnu.getopt.Getopt; public class IvyDaemon implements Runnable { - private ServerSocket serviceSocket; private static boolean debug = (System.getProperty("IVY_DEBUG")!=null) ; private volatile Thread daemonThread;// volatile to ensure the quick communication @@ -56,7 +55,7 @@ public class IvyDaemon implements Runnable { int c; int servicePort = DEFAULT_SERVICE_PORT; boolean quiet = false; - String domain=Ivy.getDomain(null); + String domain=null; while ((c = opt.getopt()) != -1) switch (c) { case 'n': name=opt.getOptarg(); @@ -86,7 +85,7 @@ public class IvyDaemon implements Runnable { return; } bus=new Ivy(name,name+" ready",null); - if (!quiet) System.out.println("broadcasting on "+bus.domains(domain)); + if (!quiet) System.out.println("broadcasting on "+Domain.domains(domain)); bus.start(domain); if (!quiet) System.out.println("listening on "+servicePort); new IvyDaemon(bus,servicePort).doStart(); diff --git a/src/IvyWatcher.java b/src/IvyWatcher.java index f6507bb..1dcaab0 100755 --- a/src/IvyWatcher.java +++ b/src/IvyWatcher.java @@ -16,6 +16,7 @@ * CHANGELOG: * 1.2.16 * - now uses the synchronized wrappers of the Java API for all collections + * - move out the Domain related-code to the Domain class * 1.2.15 * - allows the fine tuning of the IvyClient socket buffersize using * IVY_BUFFERSIZE property @@ -102,8 +103,8 @@ class IvyWatcher extends Thread { private static int serial=0; private int myserial=serial++; private String busWatcherId = null; + private static Pattern recoucou; - private static Pattern recoucou, numbersPoint, exp; /** * creates an Ivy watcher @@ -317,72 +318,13 @@ class IvyWatcher extends Thread { } } - /* - private boolean isInDomain( InetAddress host ){ - return true; - // TODO check if this function is useful. for now, it always returns true - // deprecated since we use Multicast. How to check when we are in UDP - // broadcast ? - // - byte rem_addr[] = host.getAddress(); - for ( int i = 0 ; i < domainaddrList.size(); i++ ) { - byte addr[] = ((InetAddress)domainaddrList.elementAt(i)).getAddress(); - int j ; - for ( j = 0 ; j < 4 ; j++ ) - if ( (addr[j] != -1) && (addr[j] != rem_addr[j]) ) break; - if ( j == 4 ) { - traceDebug( "host " + host + " is in domain\n" ); - return true; - } - } - traceDebug( "host " + host + " Not in domain\n" ); - return false; - } - */ - - static String getDomain(String net) throws IvyException { - // System.out.println("debug: net=[" + net+ "]"); - int sep_index = net.lastIndexOf( ":" ); - if ( sep_index != -1 ) { net = net.substring(0,sep_index); } - try { - Matcher m = numbersPoint.matcher(net); - if (!m.matches()) { - // traceDebug("should only have numbers and point ? I won't add anything... " + net); - return "127.255.255.255"; - // return net; - } - net += ".255.255.255"; - Matcher mm= exp.matcher(net); - if (!mm.matches()) { - System.out.println("Bad broascat addr " + net); - throw new IvyException("bad broadcast addr"); - } - net=mm.group(1); - } catch ( PatternSyntaxException e ){ - e.printStackTrace(); - throw new RuntimeException(); - } - //System.out.println("next domain: "+net); - return net; - } - - static int getPort(String net) { // returns 0 if no port is set - int sep_index = net.lastIndexOf( ":" ); - int port= ( sep_index == -1 ) ? 0 :Integer.parseInt( net.substring( sep_index +1 )); - // System.out.println("net: ["+net+"]\nsep_index: "+sep_index+"\nport: "+port); - //System.out.println("next port: "+port); - return port; - } - private void traceDebug(String s){ if (debug) System.out.println("-->IvyWatcher["+myserial+","+bus.getSerial()+"]<-- "+s); } static { try { - numbersPoint = Pattern.compile("([0-9]|\\.)+"); recoucou = Pattern.compile("([0-9]+) ([0-9]+) ([^ ]*) (.*)",Pattern.DOTALL); - exp = Pattern.compile( "^(\\d+\\.\\d+\\.\\d+\\.\\d+).*"); } catch (PatternSyntaxException res) { res.printStackTrace(); System.out.println("Regular Expression bug in Ivy source code ... bailing out"); @@ -390,4 +332,5 @@ class IvyWatcher extends Thread { } } + } // class IvyWatcher diff --git a/src/Probe.java b/src/Probe.java index 6a4c75c..f362b38 100644 --- a/src/Probe.java +++ b/src/Probe.java @@ -103,7 +103,7 @@ public class Probe implements IvyApplicationListener, IvyMessageListener, IvyBin boolean timestamp=false; boolean quiet=false; boolean sendsToSelf=false; - String domain=Ivy.getDomain(null); + String domain=null; String name="JPROBE"; String[] messageClass=null; while ((c = opt.getopt()) != -1) switch (c) { @@ -113,11 +113,7 @@ public class Probe implements IvyApplicationListener, IvyMessageListener, IvyBin break; case 'b': domain=opt.getOptarg(); break; case 'c': - java.util.StringTokenizer classTok = new java.util.StringTokenizer(opt.getOptarg(),","); - messageClass=new String[classTok.countTokens()]; - System.out.println("YANNNN "+messageClass.length); - for (int i=0;classTok.hasMoreElements();) - messageClass[i++] = classTok.nextToken(); + messageClass = opt.getOptarg().split(","); break; case 'n': name=opt.getOptarg(); break; case 'q': quiet=true; break; @@ -133,7 +129,7 @@ public class Probe implements IvyApplicationListener, IvyMessageListener, IvyBin bus.sendToSelf(sendsToSelf); if (messageClass!=null) { System.out.println("using a message class filter of "+messageClass.length+" elements"); - for (String cls: messageClass) System.out.println(cls); + for (String cls: messageClass) System.out.println("\t "+cls); bus.setFilter(messageClass); } for (int i=opt.getOptind();iv=bus.getIvyClientsByName(target); + Collectionv=bus.getIvyClientsByName(target); if (v.size()==0) println("no Ivy client with the name \""+target+"\""); try { for (IvyClient ic : v) ic.sendDirectMsg(id,message); @@ -231,11 +228,10 @@ public class Probe implements IvyApplicationListener, IvyMessageListener, IvyBin println("-> not sent, the message contains incorrect characters"); } } else if (s.lastIndexOf(".dieall-yes-i-am-sure")>=0){ - Vectorv=bus.getIvyClients(); - for (IvyClient ic: v) ic.sendDie("java probe wants you to leave the bus"); + for (IvyClient ic: bus.getIvyClients()) ic.sendDie("java probe wants you to leave the bus"); } else if (s.lastIndexOf(".die ")>=0){ String target=s.substring(5); - Vectorv=bus.getIvyClientsByName(target); + Collectionv=bus.getIvyClientsByName(target); if (v.size()==0) println("no Ivy client with the name \""+target+"\""); for (IvyClient ic: v) ic.sendDie("java probe wants you to leave the bus"); } else if (s.lastIndexOf(".unbind ")>=0){ @@ -246,10 +242,9 @@ public class Probe implements IvyApplicationListener, IvyMessageListener, IvyBin println("you can't unsubscribe to " + regexp + ", your're not subscribed to it"); } } else if (s.lastIndexOf(".bound *")>=0){ - Vectorv=bus.getIvyClients(); int total=0; int boundedtotal=0; - for (IvyClient ic: v) { + for (IvyClient ic: bus.getIvyClients()) { for (String r : ic.getRegexps()) { total++; if (r.startsWith("^")) boundedtotal++; @@ -261,7 +256,7 @@ public class Probe implements IvyApplicationListener, IvyMessageListener, IvyBin int total=0; int boundedtotal=0; String target=s.substring(7); - Vectorv=bus.getIvyClientsByName(target); + Collectionv=bus.getIvyClientsByName(target); if (v.size()==0) println("no Ivy client with the name \""+target+"\""); for (IvyClient ic:v) { for (String r : ic.getRegexps()) { @@ -286,12 +281,12 @@ public class Probe implements IvyApplicationListener, IvyMessageListener, IvyBin bus.stop(); return false; } else if (s.lastIndexOf(".list")>=0) { - Vector v = bus.getIvyClients(); - println(v.size()+" clients on the bus"); - for (IvyClient ic: v) println("-> "+ic.getApplicationName()); + Collection c = bus.getIvyClients(); + println(c.size()+" clients on the bus"); + for (IvyClient ic: c) println("-> "+ic.getApplicationName()); } else if ( s.lastIndexOf(".ping ")>=0) { String target=s.substring(6); - Vectorv=bus.getIvyClientsByName(target); + Collectionv=bus.getIvyClientsByName(target); if (v.size()==0) println("no Ivy client with the name \""+target+"\""); for (IvyClient ic:v) { try { @@ -306,7 +301,7 @@ public class Probe implements IvyApplicationListener, IvyMessageListener, IvyBin } } else if ( s.lastIndexOf(".where ")>=0) { String target=s.substring(7); - Vectorv=bus.getIvyClientsByName(target); + Collectionv=bus.getIvyClientsByName(target); if (v.size()==0) println("no Ivy client with the name \""+target+"\""); for (IvyClient ic: v) println(target+" runs on "+ic.getHostName()); } else if (mtime.matches()) { diff --git a/src/Protocol.java b/src/Protocol.java index a643e39..9751661 100644 --- a/src/Protocol.java +++ b/src/Protocol.java @@ -1,5 +1,6 @@ /** - * the Protocol magic numbers and chars + * the Protocol magic numbers and chars. + * * @author Yannick Jestin * @author http://www.tls.cena.fr/products/ivy/ * @@ -30,7 +31,6 @@ enum Protocol { final static char NEWLINE = '\n'; final static int PROTOCOLVERSION = 3 ; final static int PROTOCOLMINIMUM = 3 ; - final static int MI = 3 ; private int value = -1; private Protocol(int v) {this.value = v;} diff --git a/src/ProxyClient.java b/src/ProxyClient.java index 1fd7b75..92f2c75 100644 --- a/src/ProxyClient.java +++ b/src/ProxyClient.java @@ -21,7 +21,9 @@ package fr.dgac.ivy ; import java.io.*; import java.net.*; -import java.util.* ; +import java.util.HashMap ; +import java.util.Map ; +import java.util.Properties ; import gnu.getopt.Getopt; import java.util.regex.*; @@ -32,9 +34,9 @@ class ProxyClient extends Ivy { private BufferedReader in; private static boolean debug = (System.getProperty("IVY_DEBUG")!=null) ; private volatile Thread clientThread; // volatile to ensure the quick communication - private Hashtable id=new Hashtable(); - private Hashtableghosts = new Hashtable(); - private Hashtable puppets =new Hashtable(); // key=id value=Puppet + private Map id=new HashMap(); + private Mapghosts = new HashMap(); + private Map puppets =new HashMap(); // key=id value=Puppet String domain=null; public static final int DEFAULT_SERVICE_PORT = 3456 ; @@ -48,7 +50,7 @@ class ProxyClient extends Ivy { int c; int servicePort = DEFAULT_SERVICE_PORT; boolean quiet = false; - String domain=Ivy.getDomain(null); + String domain=null; while ((c = opt.getopt()) != -1) switch (c) { case 'n': name=opt.getOptarg(); diff --git a/src/ProxyMaster.java b/src/ProxyMaster.java index 9d40ebb..8ac1d10 100644 --- a/src/ProxyMaster.java +++ b/src/ProxyMaster.java @@ -7,6 +7,8 @@ * (c) ENAC * * changelog: + * 1.2.16 + * - switches from Vector to proper collections * 1.2.14 * - throws RuntimeException instead of System.exit(), allows code reuse * - switch from gnu regexp (deprecated) to the built in java regexp @@ -19,7 +21,11 @@ package fr.dgac.ivy.tools ; // TODO go into sub tools, and build a shell/.BAT sc import fr.dgac.ivy.* ; import java.io.*; import java.net.*; -import java.util.* ; +import java.util.Map ; +import java.util.HashMap ; +import java.util.ArrayList ; +import java.util.Collection ; +import java.util.Properties ; import gnu.getopt.Getopt; import java.util.regex.*; @@ -28,8 +34,8 @@ class ProxyMaster { private ServerSocket serviceSocket; private static boolean debug=false; private boolean doRun=true; // stops running when set to false - private Vector proxyClients = new Vector(); - private Hashtable ghostFathers = new Hashtable(); // key: ghostId value: SubReader + private Collection proxyClients = new ArrayList(); + private Map ghostFathers = new HashMap(); // key: ghostId value: SubReader private static int serial=0; public static final int DEFAULT_SERVICE_PORT = 3456 ; @@ -108,7 +114,7 @@ class ProxyMaster { String busDomain=null; // I will know it from the Hello message SubReader(Socket socket) throws IOException { - proxyClients.addElement(this); + proxyClients.add(this); hostname = socket.getInetAddress().getHostName(); in=new BufferedReader(new InputStreamReader(socket.getInputStream())); out=new PrintWriter(new OutputStreamWriter(socket.getOutputStream())); @@ -136,7 +142,7 @@ class ProxyMaster { } traceDebug("Subreader Thread stopped"); System.out.println("ProxyClient on "+hostname+", bus "+busDomain+" disconnected"); - proxyClients.removeElement(this); + proxyClients.remove(this); } @@ -169,10 +175,8 @@ class ProxyMaster { sr.send(msg); } else if ((m=fwdPuppet.matcher(msg)).matches()) { System.out.println("PM forwarding ["+msg+"] to all other PCs"); - for (Enumeratione=proxyClients.elements();e.hasMoreElements();) { - SubReader sr = e.nextElement(); + for (SubReader sr: proxyClients) if (sr!=SubReader.this) sr.send(msg); - } } else { System.out.println("error unknown message "+msg); } diff --git a/src/SelfIvyClient.java b/src/SelfIvyClient.java index b5d9996..bd06ee1 100644 --- a/src/SelfIvyClient.java +++ b/src/SelfIvyClient.java @@ -207,4 +207,3 @@ public class SelfIvyClient extends IvyClient { } } -/* EOF */ diff --git a/src/WaitFor.java b/src/WaitFor.java new file mode 100644 index 0000000..04b5172 --- /dev/null +++ b/src/WaitFor.java @@ -0,0 +1,55 @@ +/** + * a helper class to implement "Wait for Message/Client" + * @author Yannick Jestin + * @author http://www.tls.cena.fr/products/ivy/ + * + * CHANGELOG: + * 1.2.16: + * - factorize code from Waiter and WaiterClient + */ + +package fr.dgac.ivy ; + +abstract class WaitFor implements Runnable { + private static final int INCREMENT = 100; + int timeout; + IvyClient received=null; + boolean forever=false; + private Thread t; + + void setName(String s) { t.setName(s); } + void interrupt() { t.interrupt(); } + + WaitFor(int timeout) { + this.timeout=timeout; + if (timeout<=0) forever=true; + t=new Thread(this); + } + + public IvyClient waitFor() { + t.start(); + try { t.join(); } catch (InterruptedException ie) { return null; } + return received; + } + + public void run() { + boolean encore=true; + // System.out.println("DEV Waiter start"); + while (encore) { + try { + if (INCREMENT>0) Thread.sleep(INCREMENT); + if (!forever) { + timeout-=INCREMENT; + if (timeout<=0) encore=false; + } + } catch (InterruptedException ie) { + break; + } + if (check()) break; + } + // System.out.println("DEV Waiter stop"); + } + + abstract boolean check(); // is called in the thread, leaves if true + +} diff --git a/src/Waiter.java b/src/Waiter.java index d625217..4679f09 100644 --- a/src/Waiter.java +++ b/src/Waiter.java @@ -1,5 +1,5 @@ /** - * a helper class to implement faitForClient, Wait for Message + * a helper class to implement "Wait for Message" in {@link Ivy.waitForMsg} * @author Yannick Jestin * @author http://www.tls.cena.fr/products/ivy/ * @@ -10,45 +10,17 @@ package fr.dgac.ivy ; -class Waiter implements Runnable, IvyMessageListener { - private static final int INCREMENT = 100; - int timeout; - private IvyClient received=null; - private boolean forever=false; - private Thread t; +class Waiter extends WaitFor implements IvyMessageListener { - public Waiter(int timeout) { - this.timeout=timeout; - if (timeout<=0) forever=true; - t=new Thread(this); - t.setName("Ivy Waiter thread, for message"); - } - - public IvyClient waitFor() { - t.start(); - try { t.join(); } catch (InterruptedException ie) { return null; } - return received; - } + public Waiter(int timeout) { + super(timeout); + setName("Ivy Waiter thread, for message"); + } - public void run() { - boolean encore=true; - // System.out.println("DEV Waiter start"); - while (encore) { - try { - if (INCREMENT>0) Thread.sleep(INCREMENT); - if (!forever) { - timeout-=INCREMENT; - if (timeout<=0) encore=false; - } - } catch (InterruptedException ie) { - break; - } - } - // System.out.println("DEV Waiter stop"); - } + boolean check() { return false; } - public void receive(IvyClient ic, String[] args) { - received=ic; - t.interrupt(); - } + public void receive(IvyClient ic, String[] args) { + received=ic; + interrupt(); } +} diff --git a/src/WaiterClient.java b/src/WaiterClient.java index f6b00b5..5f36fca 100644 --- a/src/WaiterClient.java +++ b/src/WaiterClient.java @@ -14,51 +14,28 @@ package fr.dgac.ivy ; import java.util.Map; -class WaiterClient extends IvyApplicationAdapter implements Runnable { - private static final int INCREMENT = 100; - int timeout; - private IvyClient received=null; - private boolean forever=false; - private Thread t; - String name; - private Map clients ; +class WaiterClient extends WaitFor implements IvyApplicationListener { + private String name; + private Map clients ; - WaiterClient(String n,int timeout,Map clients) { - this.timeout=timeout; - this.clients=clients; - name=n; - if (timeout<=0) forever=true; - t=new Thread(this); - t.setName("Ivy Waiter thread, for client"); - } - - IvyClient waitForClient() { - t.start(); - try { t.join(); } catch (InterruptedException ie) { return null; } - return received; - } + WaiterClient(String n,int timeout,Map clients) { + super(timeout); + this.clients=clients; + name=n; + setName("Ivy Waiter thread, for client"); + } - public void run() { - boolean encore=true; - // System.out.println("DEV WaiterClient start"); - while (encore) { - try { - if (INCREMENT>0) Thread.sleep(INCREMENT); - if (!forever) { - timeout-=INCREMENT; - if (timeout<=0) encore=false; - } - } catch (InterruptedException ie) { - break; - } - if ((received=Ivy.alreadyThere(clients,name))!=null) break; - } - // System.out.println("DEV WaiterClient stop"); - } + boolean check() { + return (received=Ivy.alreadyThere(clients,name)) != null; + } - public void connect(fr.dgac.ivy.IvyClient client) { - if (name.compareTo(client.getApplicationName())!=0) return; - received=client; - t.interrupt(); - } + public void connect(fr.dgac.ivy.IvyClient client) { + if (name.compareTo(client.getApplicationName())!=0) return; + received=client; + interrupt(); } + + public void disconnect( IvyClient client ) { } + public void die( IvyClient client, int id, String msgarg) { } + public void directMessage( IvyClient client, int id,String msgarg ) {} +} -- cgit v1.1