aboutsummaryrefslogtreecommitdiff
path: root/src/SelfIvyClient.java
blob: d6e6f1e5a69dbf4986a714d2abf762f755ee26b2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/**
 * A private Class for ourself on the bus
 *
 * @author	Yannick Jestin
 * @author	<a href="http://www.tls.cena.fr/products/ivy/">http://www.tls.cena.fr/products/ivy/</a>
 * @since 1.2.4
 *
 *  CHANGELOG:
 *  1.2.5:
 *    - uses apache regexp instead of gnu regexp
 *  1.2.4:
 *    - adds a the threaded option for callbacks
 *    - Matthieu's bugreport on unBindMsg()
 */

package fr.dgac.ivy ;
import java.util.*;
/* import gnu.regexp.*; GNURETOAPACHERE */
import org.apache.regexp.*;

class SelfIvyClient extends IvyClient {
    
  private Ivy bus;
  private static int serial=0;		/* an unique ID for each regexp */
  private Hashtable callbacks=new Hashtable();
  private Hashtable threadedFlag=new Hashtable();
  private boolean massThreaded=false;

  public void sendDirectMsg(int id,String message) {
    bus.directMessage(this,id,message);
  }
  public void sendDie(String message) { bus.dieReceived(this,0,message); }

  protected SelfIvyClient(Ivy bus,String appName) {
    this.bus=bus;
    this.protocol=Ivy.PROTOCOLVERSION;
    this.appName=appName;
  }

  synchronized protected int bindMsg(String sregexp, IvyMessageListener callback, boolean threaded ) throws IvyException  {
    // creates a new binding (regexp,callback)
    try {
      RE re=new RE(sregexp);
      Integer key = new Integer(serial++);
      regexps.put(key,re);
      regexpsText.put(key,sregexp);
      callbacks.put(key,callback);
      threadedFlag.put(key,new Boolean(threaded));
      return key.intValue();
    } catch (RESyntaxException ree) {
      throw new IvyException("Invalid regexp " + sregexp);
    }
  }

  synchronized protected void unBindMsg(int id) throws IvyException {
    Integer key = new Integer(id);
    if ( ( regexps.remove(key) == null )
         || (regexpsText.remove(key) == null )
         || (callbacks.remove(key) == null )
         || (threadedFlag.remove(key) == null )
       )
    throw new IvyException("client wants to remove an unexistant regexp "+id);
  }

  synchronized protected boolean unBindMsg(String re) {
    for (Enumeration e=regexpsText.keys();e.hasMoreElements();) {
      Integer k = (Integer)e.nextElement();
      if ( ((String)regexps.get(k)).compareTo(re) == 0) {
	try {
	  bus.unBindMsg(k.intValue());
	} catch (IvyException ie) {
	  return false;
	}
	return true;
      }
    }
    return false;
  }

  protected int sendSelfMsg(String message) {
    int count = 0;
    for (Enumeration e = regexps.keys();e.hasMoreElements();) {
      Integer key = (Integer)e.nextElement();
      RE regexp = (RE)regexps.get(key);
      String sre = (String)regexpsText.get(key);
      if (!regexp.match(message)) continue;
      count++;
      callCallback(this,key,toArgs(regexp));
    }
    return count;
  }

  protected void callCallback(IvyClient client, Integer key, String[] tab) {
    IvyMessageListener callback=(IvyMessageListener)callbacks.get(key);
    boolean threaded=((Boolean)threadedFlag.get(key)).booleanValue();
    if (callback==null) {
      System.out.println("(callCallback) Not regexp matching id "+key.intValue());
      System.exit(0);
    }
    if (!threaded) {
      // runs the callback in the same thread
      callback.receive(client, tab);
    } else {
      // starts a new Thread for each callback ...
      new Runner(callback,client,tab);
    }
  }

  private String[] toArgs(RE re) {
    String[] args = new String[re.getParenCount()-1];
    for(int sub=1;sub<re.getParenCount();sub++) {
      args[sub-1]=re.getParen(sub);
      if (bus.doProtectNewlines) args[sub-1]=decode(args[sub-1]);
    }
    return args;
  }

  public String toString() { return "IvyClient (ourself)"+bus.appName+":"+appName; }

  // a class to perform the threaded execution of each new message
  // this is an experimental feature introduced in 1.2.4
  class Runner implements Runnable {
    IvyMessageListener cb;
    IvyClient c;
    String[] args;
    private Thread t;
    public Runner(IvyMessageListener cb,IvyClient c,String[] args) {
      this.cb=cb;
      this.args=args;
      this.c=c;
      t=new Thread(Runner.this);
      bus.registerThread(t);
      t.start();
      bus.unRegisterThread(t);
    }
    public void run() { cb.receive(c,args); }
  } // class Runner

  private void traceDebug(String s){
    if (debug)
    System.out.println("-->SelfIvyClient "+bus.appName+":"+appName+"<-- "+s);
  }

}
/* EOF */