aboutsummaryrefslogtreecommitdiff
path: root/src/Puppet.java
blob: e2a90eef5dab40bdac46d569ec528d861367a1be (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
package fr.dgac.ivy ;
import java.lang.Thread;
import java.net.*;
import java.io.*;
import java.util.*;
import org.apache.regexp.*;

class Puppet {

  // the mapping between Ghost regexp and local bus regexp numbers
  Hashtable bound = new Hashtable(); 	// ghostID localID
  Hashtable regexps = new Hashtable(); 	// ghostID textRegexp
  String domain;
  String appName;
  ProxyClient pc;
  String id;
  boolean started;
  PuppetIvy bus;

  Puppet(ProxyClient pc,String id,String domain) {
    this.domain=domain;
    this.pc=pc;
    this.id=id;
  }

  void sendGhost(String s) { pc.send("ForwardGhost id="+id+" buffer="+s); }

  class ForwardMessenger implements IvyMessageListener {
    String localId,ghostId;
    public ForwardMessenger(String ghostId,String re) throws IvyException {
      this.ghostId=ghostId;
      this.localId = (new Integer(bus.bindMsg(re,ForwardMessenger.this))).toString();
      bound.put(ghostId,localId);
    }
    public void receive(IvyClient ic,String args[]) {
      String tosend = IvyClient.Msg+" "+ghostId+IvyClient.StartArg;
      for (int i=0;i<args.length;i++) tosend+=args[i]+IvyClient.EndArg;
      sendGhost(tosend);
    }
  } // ForwardMessenger

  void addRegexp(String ghostId,String re) {
    regexps.put(ghostId,re);
    try {
      if (started) new ForwardMessenger(ghostId,re);
    } catch( IvyException ie) { ie.printStackTrace(); }
  }

  void removeRegexp(String ghostId) {
    try {
      bus.unBindMsg(Integer.parseInt((String)bound.remove(ghostId)));
    } catch( IvyException ie) { ie.printStackTrace(); }
  }

  void stop() {
    if (started) bus.stop();
  }

  // ivy forwarded protocol message
  static final RE ivyProto = new RE("(\\d+) (\\d+)\\02(.*)");
  void parse(String s) throws IvyException {
    if (!ivyProto.match(s)) { System.out.println("Puppet error, can't parse "+s); return; } 
    int pcode=Integer.parseInt(ivyProto.getParen(1));
    String pid=ivyProto.getParen(2);
    String args=ivyProto.getParen(3);
    trace("must parse code:"+pcode+" id:"+pid+" args:"+args);
    switch (pcode) {
      case IvyClient.AddRegexp: // the Ghost's peer subscribes to something
	addRegexp(pid,args);
      	break;
      case IvyClient.DelRegexp: // the Ghost's peer unsubscribes to something
	removeRegexp(pid);
        break;
      case IvyClient.Bye:	// the Ghost's peer disconnects gracefully
      	bus.stop();
	// TODO end of the puppet ?
      	break;
      case IvyClient.Die:
      	// the Ghost's peer wants to ... kill ProxyClient ?
      	break;
      case IvyClient.Msg:
      	// the Ghost's peer sends a message to ProxyClient, with regard to one
	// of our subscriptions
	// TODO à qui le faire passer ?
      	break;
      case IvyClient.SchizoToken:
      	appName = args;
	bus = new PuppetIvy(appName,appName+" fakeready",null);
	for (Enumeration e = regexps.keys();e.hasMoreElements();) {
	  String ghostId=(String)e.nextElement();
	  String re=(String)regexps.get(ghostId);
	  new ForwardMessenger(ghostId,re);
	}
	started=true;
	trace("starting the bus on "+domain);
	bus.start(domain);
        break;
      case IvyClient.Error:
      case IvyClient.EndRegexp:
      case IvyClient.DirectMsg:
      case IvyClient.Ping:
      case IvyClient.Pong:
      default:
    	trace("unused Ivy protocol code "+pcode);
    }
  }

  class PuppetIvy extends Ivy {
    PuppetIvy(String name,String ready,IvyApplicationListener ial){super(name,ready,ial);}
    protected IvyClient createIvyClient(Socket s,int port, boolean domachin) throws IOException {
      return new PuppetIvyClient(PuppetIvy.this,s,port,domachin);
    }
    int getAP() {return applicationPort;}
  }

  class PuppetIvyClient extends IvyClient {
    PuppetIvyClient(Ivy bus,Socket s,int port,boolean b) throws IOException  { super(bus,s,port,b); }
    protected synchronized void sendBuffer( String s ) throws IvyException {
      super.sendBuffer(s); // and to all the agents on the Ghost bus ? I'm not sure
    }
    protected boolean newParseMsg(String s) throws IvyException {
      return super.newParseMsg(s); // I'm a normal Ivy citizen
    }
  }

  void trace(String s) { System.out.println("Puppet["+id+"] "+s);}

}