// // API de connexion au bus logiciel ivy // // package fr.dgac.ivy ; import java.net.*; import java.io.*; import java.util.Vector; import java.util.StringTokenizer; public class Ivy implements Runnable, IvyApplicationListener { static private boolean debug = (System.getProperty("IVY_DEBUG")!=null) ; public static final int DEFAULT_PORT = 2010 ; public static final String DEFAULT_DOMAIN = "127.255.255.255:"+DEFAULT_PORT; public String appName; private boolean ivyRunning = false; private String ready_message = null; private Vector regexp_out; private ServerSocket app; private IvyWatcher watch; private Thread server; private Vector clients; private Vector callbacks; private Vector ivyApplicationListenerList; private String messages_classes[] = null; private int myport; /* Application port number */ public synchronized boolean ivyRunning(){ return ivyRunning; } // constructeur public Ivy( String name, String message, IvyApplicationListener appcb) { appName = name; ivyApplicationListenerList = new Vector(); ready_message = message; callbacks = new Vector(); clients = new Vector(); regexp_out = new Vector(); if ( appcb != null ) ivyApplicationListenerList.addElement( appcb ); } void classes( String msg_classes[] ) { messages_classes = msg_classes; } public Vector getRegexpOut() { return regexp_out; } public String getReadyMessage() { return ready_message; } void addClient( Socket socket ) throws IOException { IvyClient client = new IvyClient( this, socket); clients.addElement( client ); } void removeClient( IvyClient client ) { clients.removeElement( client ); } void callCallback( IvyClient client, int msgid, String msgarg ) { IvyMessageListener callback; String args[]; if ( (msgid <0) || (msgid > callbacks.size()) ) { traceDebug("(callCallback) Not regexp matching id "+msgid); return; } callback = (IvyMessageListener)callbacks.elementAt(msgid); StringTokenizer st = new StringTokenizer(msgarg, IvyClient.EndArg); args = new String[st.countTokens()]; int i=0; while (st.hasMoreTokens()) { args[i++] = st.nextToken(); } callback.receive( client, args ); } public int getApplicationPort() { return myport; } public int sendMsg( String message ) { int count = 0; // envoie le message à tous les clients du bus // TODO: il faudrait mettre une Thread emission par client */ for ( int i = 0 ; i < clients.size(); i++ ) { IvyClient client = (IvyClient)clients.elementAt(i); count += client.sendMsg( message ); } return count; } public int bindMsg(String regexp, IvyMessageListener callback ) { // associe une nouvelle regexp à un nouveau callback regexp_out.addElement( regexp ); callbacks.addElement( callback ); int id = regexp_out.indexOf( regexp ); /* indique aux autres clients la nouvelle regexp */ for ( int i = 0 ; i < clients.size(); i++ ) { IvyClient client = (IvyClient)clients.elementAt(i); client.sendRegexp(id, regexp ); } return id; } public void unBindMsg(int id) { // TODO: Est ce que la suppression d'1 element // ne provoque pas le tassement // et donc la modif des autres indexes? if ( id >=0 && id < regexp_out.size() ) { regexp_out.removeElementAt( id ); callbacks.removeElementAt( id ); for ( int i = 0 ; i < clients.size(); i++ ) { IvyClient client = (IvyClient)clients.elementAt(i); client.delRegexp(id ); } } } /* gestion des applications listener et callback associe */ public int addApplicationListener(IvyApplicationListener callback){ // associe une nouvelle regexp à un nouveau callback ivyApplicationListenerList.addElement( callback ); int id = ivyApplicationListenerList.indexOf( callback ); return id; } public void removeApplicationListener( int id ) { ivyApplicationListenerList.removeElementAt(id); } public void connect(IvyClient client){ for ( int i = 0 ; i < ivyApplicationListenerList.size(); i++ ) { IvyApplicationListener listener = (IvyApplicationListener)ivyApplicationListenerList.elementAt(i); listener.connect(client); } } public void disconnect(IvyClient client){ for ( int i = 0 ; i < ivyApplicationListenerList.size(); i++ ) { IvyApplicationListener listener = (IvyApplicationListener)ivyApplicationListenerList.elementAt(i); listener.disconnect(client); } } public void die(IvyClient client, int id){ for ( int i = 0 ; i < ivyApplicationListenerList.size(); i++ ) { IvyApplicationListener listener = (IvyApplicationListener)ivyApplicationListenerList.elementAt(i); listener.die(client, id); } } public void directMessage( IvyClient client, int id,String msgarg ){ for ( int i = 0 ; i < ivyApplicationListenerList.size(); i++ ) { IvyApplicationListener listener = (IvyApplicationListener)ivyApplicationListenerList.elementAt(i); listener.directMessage(client,id, msgarg); } } public static String getDomain(String domainbus) throws IvyException { if ( domainbus == null ) domainbus = System.getProperty("IVYBUS"); if ( domainbus == null ) domainbus = DEFAULT_DOMAIN; return domainbus; } public void start(String domainbus) throws IvyException { try { app = new ServerSocket(0); myport = app.getLocalPort(); } catch (IOException e) { throw new IvyException("ne peut pas ouvrir la socket server" + e ); } /* Start watcher thread */ watch = new IvyWatcher(this); traceDebug("BUS TCP: "+myport); ivyRunning = true; server = new Thread( this); /* Start ivy server thread */ server.start(); /* Send ivy helo msg */ watch.sendStart(getDomain(domainbus)); } public void stop() { try { ivyRunning = false; watch.close(); /* Stop watcher thread */ app.close(); /* Stop ivy server thread */ for ( int i = 0 ; i < clients.size(); i++ ) { IvyClient client = (IvyClient)clients.elementAt(i); client.close("Ivy Stopping...");/* Stop client thread */ } } catch ( IOException e ) { traceDebug("ioexception Stop "); } clients.removeAllElements(); } boolean CheckRegexp( String exp ) { /* accepte tout par default */ int i; boolean regexp_ok = true; if ( exp.startsWith( "^" ) && messages_classes != null ) { regexp_ok = false; for ( i = 0 ; i < messages_classes.length; i++ ) { if ( messages_classes[i].equals( exp.substring(1)) ) return true; } } return regexp_ok; } public boolean checkConnected( IvyClient clnt ) { if ( clnt.appPort == 0 ) return false; for ( int i = 0 ; i < clients.size(); i++ ) { IvyClient client = (IvyClient)clients.elementAt(i); if ( clnt != client && client.sameClient( clnt ) ) return true; } return false; } public void run() { Socket socket; while( ivyRunning() ) { try { socket = app.accept(); addClient( socket ); } catch( IOException e ) { /* Normal terminaison si socket close */ /* TODO: et les autres */ traceDebug("Error IvyServer exception: " + e.getMessage()); } } } private void traceDebug(String s){ if (debug) System.out.println("-->ivy<-- "+s); } } // class Ivy