diff options
Diffstat (limited to 'src/Probe.java')
-rw-r--r-- | src/Probe.java | 178 |
1 files changed, 99 insertions, 79 deletions
diff --git a/src/Probe.java b/src/Probe.java index d560298..bd37089 100644 --- a/src/Probe.java +++ b/src/Probe.java @@ -1,15 +1,19 @@ -package fr.dgac.ivy ; -import java.io.*; -import java.util.*; -import gnu.getopt.Getopt; - /** * terminal implementation in java of the ivyprobe. + * * @author Yannick Jestin * @author <a href="http://www.tls.cena.fr/products/ivy/">http://www.tls.cena.fr/products/ivy/</a> - * + * + * (c) CENA * * Changelog: + * 1.2.3 + * - now allows directMessages with the .direct command + * - the parseMsg is being rewritten with regexps + * - now handles the IVY_DEBUG property + * - now handles the -q quiet option + * - now handles the ^D ( end of input ) in a clean fashion + * - the constructor is public, you can embed a Probe in other programs * 1.2.2 * - changes setProperty to a backward-compatible construct * - now uses the bus.domains(String domain) in order to display the domain @@ -30,47 +34,45 @@ import gnu.getopt.Getopt; * exits on end of user input * handles multiple domains - it was a IvyWatcher problem - */ -class Probe implements IvyApplicationListener, IvyMessageListener, Runnable { +package fr.dgac.ivy ; +import java.io.*; +import java.util.*; +import gnu.getopt.Getopt; +import gnu.regexp.*; + +public class Probe implements IvyApplicationListener, IvyMessageListener, Runnable { + + public static final String helpCommands = "Available commands:\n.die CLIENTNAME sends a die message\n.direct CLIENTNAME ID MESSAGE sends the direct message to the client, with a message id set to the numerical ID\n.bye quits the application\n.quit idem\n.list lists the available clients\n.ping sends a ping request if IVY_PING is enabled\n.bind REGEXP binds to a regexp at runtime\n.unbind REGEXP unbinds to a regexp at runtime"; - /** - * help message for the standalone program - */ - public static final String helpCommands = "Available commands:\n.die CLIENTNAME sends a die message\n.bye quits the application\n.quit idem\n.list lists the available clients\n.ping sends a ping request if IVY_PING is enabled\n.bind REGEXP binds to a regexp at runtime\n.unbind REGEXP unbinds to a regexp at runtime"; public static final String helpmsg = "usage: java fr.dgac.ivy.Probe [options] [regexp]\n\t-b BUS\tspecifies the Ivy bus domain\n\t-n ivyname (default JPROBE)\n\t-q\tquiet, no tty output\n\t-d\tdebug\n\t-t\ttime stamp each message\n\t-h\thelp\n\n\t regexp is a Perl5 compatible regular expression"; public static void main(String[] args) throws IvyException { - Getopt opt = new Getopt("Probe",args,"n:b:dht"); + Getopt opt = new Getopt("Probe",args,"n:b:dqht"); int c; boolean timestamp=false; + boolean quiet=false; String domain=Ivy.getDomain(null); String name="JPROBE"; while ((c = opt.getopt()) != -1) switch (c) { - case 'b': - domain=opt.getOptarg(); - break; - case 'n': - name=opt.getOptarg(); - break; - case 't': - timestamp=true; - break; case 'd': Properties sysProp = System.getProperties(); sysProp.put("IVY_DEBUG","yes"); - //System.setProperty("IVY_DEBUG","yes"); break; + case 'b': domain=opt.getOptarg(); break; + case 'n': name=opt.getOptarg(); break; + case 'q': quiet=true; break; + case 't': timestamp=true; break; case 'h': - default: - System.out.println(helpmsg); - System.exit(0); - } // getopt - Probe p = new Probe(timestamp); - Ivy bus=new Ivy(name,name+" ready",p); + default: System.out.println(helpmsg); System.exit(0); + } + Probe p = new Probe(new BufferedReader(new InputStreamReader(System.in)),timestamp,quiet,System.getProperty("IVY_DEBUG")!=null); + p.setExitOnDie(true); + Ivy bus=new Ivy(name,name+" ready",null); for (int i=opt.getOptind();i<args.length;i++) { - System.out.println("you want to subscribe to " + args[i]); + if (!quiet) System.out.println("you want to subscribe to " + args[i]); bus.bindMsg(args[i],p); } - System.out.println(bus.domains(domain)); + if (!quiet) System.out.println(bus.domains(domain)); bus.start(domain); p.start(bus); } @@ -78,75 +80,94 @@ class Probe implements IvyApplicationListener, IvyMessageListener, Runnable { private BufferedReader in; private volatile Thread looperThread; private Ivy bus; - private boolean timestamp; + private boolean timestamp,quiet,debug,exitOnDie=false; + private RE directMsgRE; - Probe(boolean timestamp) { - in = new BufferedReader(new InputStreamReader(System.in)); - looperThread=new Thread(this); + + public Probe(BufferedReader in, boolean timestamp,boolean quiet,boolean debug) { + this.in=in; this.timestamp=timestamp; + this.quiet=quiet; + this.debug = debug; + try { + directMsgRE = new RE("^\\.direct ([^ ]*) ([0-9]+) (.*)"); + } catch (REException ree) { + System.err.println("Regexp fatal error in the Probe program."); + ree.printStackTrace(); + System.exit(0); + } } - public void start(Ivy bus) { + public void start(Ivy bus) throws IvyException { + if (looperThread!=null) throw new IvyException("Probe already started"); this.bus=bus; + bus.addApplicationListener(this); + looperThread=new Thread(this); looperThread.start(); } + public void setExitOnDie(boolean b) { exitOnDie=b; } + public void run() { - // System.out.println("Probe Thread started"); // THREADDEBUG + traceDebug("Thread started"); Thread thisThread=Thread.currentThread(); String s; + // "infinite" loop on keyboard input while (looperThread==thisThread) { - // infinite loop on keyboard input try { s=in.readLine(); + if (s==null) break; parseCommand(s); } catch (NullPointerException e) { // EOF triggered by a ^D, for instance - bus.stop(); + break; } catch (IOException e) { - System.out.println("ioe ?"); - e.printStackTrace(); - bus.stop(); - } catch (InterruptedException ie) { - System.out.println("allo ?"); + // System input was closed + break; } - } //while - System.out.println("End of looping"); - // System.out.println("Probe Thread stopped"); // THREADDEBUG - System.exit(0); + } + println("End of input. Good bye !"); + bus.stop(); + traceDebug("Probe Thread stopped"); } - void parseCommand(String s) throws IOException, InterruptedException { - // System.out.println("parsing the ["+s+"] (length "+s.length()+") string"); + void parseCommand(String s) throws IOException { + REMatch result; + traceDebug("parsing the ["+s+"] (length "+s.length()+") string"); // crude parsing of the ".xyz" commands - // TODO use regexps instends of String.lastIndexOf(String) + // TODO use regexps instends of String.lastIndexOf(String). Example + // provided with .direct ! if (s.length()==0) { - System.out.println(date()+"-> Sent to " +bus.sendMsg(s)+" peers"); + println("-> Sent to " +bus.sendMsg(s)+" peers"); + } else if ((result=directMsgRE.getMatch(s))!=null) { + String target = result.toString(1); + int id = Integer.parseInt(result.toString(2)); + String message = result.toString(3); + Vector v=bus.getIvyClientsByName(target); + if (v.size()==0) println("no Ivy client with the name \""+target+"\""); + for (int i=0;i<v.size();i++) ((IvyClient)v.elementAt(i)).sendDirectMsg(id,message); + return; } else if (s.lastIndexOf(".die ")>=0){ String target=s.substring(5); Vector v=bus.getIvyClientsByName(target); - if (v.size()==0) { - System.out.println("no Ivy client with the name \""+target+"\""); - } - for (int i=0;i<v.size();i++) { - ((IvyClient)v.elementAt(i)).sendDie(); - } + if (v.size()==0) println("no Ivy client with the name \""+target+"\""); + for (int i=0;i<v.size();i++) ((IvyClient)v.elementAt(i)).sendDie(); } else if (s.lastIndexOf(".unbind ")>=0){ String regexp=s.substring(8); if (bus.unBindMsg(regexp)) { - System.out.println("you want to unsubscribe to " + regexp); + println("you want to unsubscribe to " + regexp); } else { - System.out.println("you can't unsubscribe to " + regexp + ", your're not subscribed to it"); + println("you can't unsubscribe to " + regexp + ", your're not subscribed to it"); } } else if (s.lastIndexOf(".bind ")>=0){ String regexp=s.substring(6); - System.out.println("you want to subscribe to " + regexp); + println("you want to subscribe to " + regexp); bus.bindMsg(regexp,this); } else if (s.lastIndexOf(".ping ")>=0){ String target=s.substring(6); Vector v=bus.getIvyClientsByName(target); if (v.size()==0) { - System.out.println("no Ivy client with the name \""+target+"\""); + println("no Ivy client with the name \""+target+"\""); } for (int i=0;i<v.size();i++) { ((IvyClient)v.elementAt(i)).sendPing("test"); @@ -156,49 +177,48 @@ class Probe implements IvyApplicationListener, IvyMessageListener, Runnable { System.exit(0); } else if (s.lastIndexOf(".list")>=0) { Vector v = bus.getIvyClients(); - System.out.println(v.size()+" clients on the bus"); + println(v.size()+" clients on the bus"); for (int i=0;i<v.size();i++) { - System.out.println("-> "+((IvyClient)v.elementAt(i)).getApplicationName()); + println("-> "+((IvyClient)v.elementAt(i)).getApplicationName()); } } else if ( s.lastIndexOf(".help")>=0) { - System.out.println(helpCommands); + println(helpCommands); } else if ( s.charAt(0)=='.') { - System.out.println("this command is not recognized"); - System.out.println(helpCommands); + println("this command is not recognized"); + println(helpCommands); } else { - System.out.println(date()+"-> Sent to " +bus.sendMsg(s)+" peers"); + println("-> Sent to " +bus.sendMsg(s)+" peers"); } } // parseCommand public void connect(IvyClient client) { - System.out.println(client.getApplicationName() + " connected " ); + println(client.getApplicationName() + " connected " ); for (java.util.Enumeration e=client.getRegexps();e.hasMoreElements();) - System.out.println(client.getApplicationName() + " subscribes to " - +e.nextElement() ); + println(client.getApplicationName() + " subscribes to " +e.nextElement() ); } public void disconnect(IvyClient client) { - System.out.println(client.getApplicationName() + " disconnected " ); + println(client.getApplicationName() + " disconnected " ); } public void die(IvyClient client, int id) { - System.out.println("received die msg from " + client.getApplicationName() ); - Thread t = looperThread; - looperThread = null; - t.interrupt(); // TODO does'nt work - System.exit(0); + println("received die msg from " + client.getApplicationName() +" good bye"); + /* I cannot stop the readLine(), because it is native code */ + if (exitOnDie) System.exit(0); } public void directMessage(IvyClient client, int id, String arg) { - System.out.println(client.getApplicationName() + " direct Message "+ id + arg ); + println(client.getApplicationName() + " direct Message "+ id + arg ); } public void receive(IvyClient client, String[] args) { - String s=date()+client.getApplicationName() + " sent"; + String s=client.getApplicationName() + " sent"; for (int i=0;i<args.length;i++) s+=" '"+args[i]+"'"; - System.out.println(s); + println(s); } + private void traceDebug(String s){ if (debug) System.out.println("-->Probe<-- "+s); } + private void println(String s){ if (!quiet) System.out.println(date()+s); } private String date() { if (!timestamp) return ""; Date d = new Date(); |