aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorjestin2012-05-13 08:54:38 +0000
committerjestin2012-05-13 08:54:38 +0000
commite854a58a81ec90e419a4b3effa5a83caac05df90 (patch)
tree16eb84a66b62ff38e744c8cd474df81561436b9f /src
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')
-rw-r--r--src/After.java9
-rw-r--r--src/BindType.java7
-rw-r--r--src/Domain.java177
-rwxr-xr-xsrc/Ivy.java188
-rwxr-xr-xsrc/IvyClient.java4
-rw-r--r--src/IvyDaemon.java5
-rwxr-xr-xsrc/IvyWatcher.java63
-rw-r--r--src/Probe.java35
-rw-r--r--src/Protocol.java4
-rw-r--r--src/ProxyClient.java12
-rw-r--r--src/ProxyMaster.java20
-rw-r--r--src/SelfIvyClient.java1
-rw-r--r--src/WaitFor.java55
-rw-r--r--src/Waiter.java50
-rw-r--r--src/WaiterClient.java65
15 files changed, 379 insertions, 316 deletions
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"
+ * <br>
+ * <code>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".
+ * </code>
*
* @author Yannick Jestin
* @author <a href="http://www.tls.cena.fr/products/ivy/">http://www.tls.cena.fr/products/ivy/</a>
@@ -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 <a
* href="mailto:yannick.jestin@enac.fr">yannick.jestin&enac.fr</a>
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 <a * href="mailto:yannick.jestin@enac.fr">yannick.jestin&enac.fr</a>
+ * @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<Domain> parseDomains(final String domainbus) {
+ // assert(domainbus!=null);
+ List<Domain> d = new ArrayList<Domain>();
+ 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 @@
*<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
+}
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 <Integer,PingCallbackHolder>PingCallbacksTable =
Collections.synchronizedSortedMap(new TreeMap<Integer,PingCallbackHolder>());
-
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();i<args.length;i++) {
@@ -144,7 +140,7 @@ public class Probe implements IvyApplicationListener, IvyMessageListener, IvyBin
System.out.println("you have not subscribed to " + args[i]+ ", this regexp is invalid");
}
}
- if (!quiet) System.out.println("broadcasting on "+bus.domains(domain));
+ if (!quiet) System.out.println("broadcasting on "+Domain.domains(domain));
bus.start(domain);
p.start(bus);
}
@@ -165,6 +161,7 @@ public class Probe implements IvyApplicationListener, IvyMessageListener, IvyBin
throw new RuntimeException();
}
}
+
public Probe(BufferedReader in, boolean timestamp,boolean quiet,boolean debug) {
this.in=in;
this.timestamp=timestamp;
@@ -223,7 +220,7 @@ public class Probe implements IvyApplicationListener, IvyMessageListener, IvyBin
String target = m.group(1);
int id = Integer.parseInt(m.group(2));
String message = m.group(3);
- Vector<IvyClient>v=bus.getIvyClientsByName(target);
+ Collection<IvyClient>v=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){
- Vector<IvyClient>v=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);
- Vector<IvyClient>v=bus.getIvyClientsByName(target);
+ Collection<IvyClient>v=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){
- Vector<IvyClient>v=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);
- Vector<IvyClient>v=bus.getIvyClientsByName(target);
+ Collection<IvyClient>v=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<IvyClient> v = bus.getIvyClients();
- println(v.size()+" clients on the bus");
- for (IvyClient ic: v) println("-> "+ic.getApplicationName());
+ Collection<IvyClient> 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);
- Vector<IvyClient>v=bus.getIvyClientsByName(target);
+ Collection<IvyClient>v=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);
- Vector<IvyClient>v=bus.getIvyClientsByName(target);
+ Collection<IvyClient>v=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 <a href="http://www.tls.cena.fr/products/ivy/">http://www.tls.cena.fr/products/ivy/</a>
*
@@ -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<String,String> id=new Hashtable<String,String>();
- private Hashtable<String,Ghost>ghosts = new Hashtable<String,Ghost>();
- private Hashtable<String,Puppet> puppets =new Hashtable<String,Puppet>(); // key=id value=Puppet
+ private Map<String,String> id=new HashMap<String,String>();
+ private Map<String,Ghost>ghosts = new HashMap<String,Ghost>();
+ private Map<String,Puppet> puppets =new HashMap<String,Puppet>(); // 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<SubReader> proxyClients = new Vector<SubReader>();
- private Hashtable<String,SubReader> ghostFathers = new Hashtable<String,SubReader>(); // key: ghostId value: SubReader
+ private Collection<SubReader> proxyClients = new ArrayList<SubReader>();
+ private Map<String,SubReader> ghostFathers = new HashMap<String,SubReader>(); // 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 (Enumeration<SubReader>e=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 <a href="http://www.tls.cena.fr/products/ivy/">http://www.tls.cena.fr/products/ivy/</a>
+ *
+ * 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 <a href="http://www.tls.cena.fr/products/ivy/">http://www.tls.cena.fr/products/ivy/</a>
*
@@ -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 <Integer,IvyClient>clients ;
+class WaiterClient extends WaitFor implements IvyApplicationListener {
+ private String name;
+ private Map <Integer,IvyClient>clients ;
- WaiterClient(String n,int timeout,Map <Integer,IvyClient>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 <Integer,IvyClient>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 ) {}
+}