diff options
Diffstat (limited to 'src/Ivy.java')
-rwxr-xr-x | src/Ivy.java | 66 |
1 files changed, 64 insertions, 2 deletions
diff --git a/src/Ivy.java b/src/Ivy.java index e8ea0b2..4101931 100755 --- a/src/Ivy.java +++ b/src/Ivy.java @@ -13,6 +13,10 @@ *</pre> * * CHANGELOG: + * 1.2.9: + * - introducing setFilter() + * - introducing IVYRANGE in to allow the bus service socket to start on a + * specific port range ( think of firewalls ), using java -DIVYRANGE=4000-5000 e.g. * 1.2.8: * - addclient and removeclient going synchronized * - domainaddr goes protected in Domain ( gij compatibility ) @@ -83,6 +87,7 @@ import java.net.*; import java.io.*; import java.util.*; import gnu.getopt.Getopt; +import org.apache.regexp.*; public class Ivy implements Runnable { @@ -107,7 +112,7 @@ public class Ivy implements Runnable { * the library version, useful for development purposes only, when java is * invoked with -DIVY_DEBUG */ - public static final String libVersion ="1.2.8"; + public static final String libVersion ="1.2.9"; private boolean debug; private ServerSocket app; @@ -118,6 +123,7 @@ public class Ivy implements Runnable { private Vector ivyApplicationListenerList = new Vector(); private Vector ivyBindListenerList = new Vector(); private Vector sendThreads = new Vector(); + private String[] filter = null; private boolean stopped=true; protected int applicationPort; /* Application port number */ protected String ready_message = null; @@ -129,6 +135,7 @@ public class Ivy implements Runnable { private int myserial=serial++; static long current = System.currentTimeMillis(); private static java.util.Random generator = new java.util.Random(current*(serial+1)); + private String watcherId=null; /** * Readies the structures for the software bus connexion. @@ -225,16 +232,38 @@ public class Ivy implements Runnable { if (domainbus==null) domainbus=getDomain(null); Properties sysProp = System.getProperties(); sysProp.put("IVYBUS",domainbus); - try { + String range=(String)sysProp.get("IVYRANGE"); + RE rangeRE = new RE("(\\d+)-(\\d+)"); // tcp range min and max + if ((range!=null)&&rangeRE.match(range)) { + int rangeMin=Integer.parseInt(rangeRE.getParen(1)); + int rangeMax=Integer.parseInt(rangeRE.getParen(2)); + int index=rangeMin; + traceDebug("trying to allocate a TCP port between "+rangeMin+" and "+rangeMax); + boolean allocated=false; + while (!allocated) try { + if (index>rangeMax) throw new IvyException("no available port in IVYRANGE" + range ); + app = new ServerSocket(index); + app.setSoTimeout(TIMEOUTLENGTH); + applicationPort = app.getLocalPort(); + allocated=true; + } catch (BindException e) { + index++; + } catch (IOException e) { + throw new IvyException("can't open TCP service socket " + e ); + } + } + else try { app = new ServerSocket(0); app.setSoTimeout(TIMEOUTLENGTH); applicationPort = app.getLocalPort(); } catch (IOException e) { throw new IvyException("can't open TCP service socket " + e ); } + // app.getInetAddress().getHostName()) is always 0.0.0.0 traceDebug("lib: "+libVersion+" protocol: "+PROTOCOLVERSION+" TCP service open on port "+applicationPort); Domain[] d = parseDomains(domainbus); + watcherId=getWBUId().replace(' ','*'); // no space in the watcherId // readies the rendezvous : an IvyWatcher (thread) per domain bus for (int index=0;index<d.length;index++) watchers.addElement(new IvyWatcher(this,d[index].domainaddr,d[index].port)); @@ -525,6 +554,37 @@ public class Ivy implements Runnable { } } + /** + * sets the filter expression + * @param filter the extensive list of strings beginning the messages + * @since 1.2.9 + * + * 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 void setFilter(String[] filter){ this.filter=filter; } + + /** + * checks the "validity" of a regular expression if a filter has been set + * @since 1.2.9 + * @param exp a string regular expression + * must be synchronized ( RE is not threadsafe ) + */ + private static final RE bounded = new RE("^\\^([a-zA-Z0-9_-]+).*"); + public synchronized boolean CheckRegexp( String exp ) { + if (filter==null) return true; // there's no message filter + if (!bounded.match(exp)) return true; // the regexp is not bounded + //System.out.println("the regexp is bounded, "+bounded.getParen(1)); + // else the regexp is bounded. The matching string *must* be in the filter + for (int i=0;i<filter.length;i++) { + String prems = bounded.getParen(1); + // traceDebug(" classFilter ["+filter[i]+"] vs regexp ["+prems+"]"); + if (filter[i].compareTo(prems)==0) return true; + } + return false; + } + // a private class used by bindMsgOnce, to ensure that a callback will be // executed once, and only once private class Once implements IvyMessageListener { @@ -772,6 +832,8 @@ public class Ivy implements Runnable { traceDebug("service thread stopped"); // THREADDEBUG } + protected String getWatcherId() { return watcherId ; } + protected int getSerial() { return myserial ; } private void traceDebug(String s){ if (debug) System.out.println("-->Ivy["+myserial+"]<-- "+s); |