aboutsummaryrefslogtreecommitdiff
path: root/src/Ivy.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/Ivy.java')
-rwxr-xr-xsrc/Ivy.java66
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);