package dz.esi.edma.noyau; import java.awt.Color; import java.awt.Image; import java.awt.Toolkit; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.Set; import java.util.Map.Entry; import java.util.concurrent.ExecutionException; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.PriorityBlockingQueue; import java.util.concurrent.TimeUnit; import javax.swing.ImageIcon; import javax.swing.border.MatteBorder; import dz.esi.edma.interfacegraphique.Interface; import dz.esi.edma.interfacegraphique.JInternalFrameAgent; import dz.esi.edma.interfacegraphique.JPanelAgent; import dz.esi.edma.noyau.message.IMCompetence; import dz.esi.edma.noyau.message.IMessage; import dz.esi.edma.noyau.message.MCCompetence; import dz.esi.edma.noyau.message.MMCompetence; import dz.esi.edma.noyau.message.MMObjet; import dz.esi.edma.noyau.message.MMString; import dz.esi.edma.noyau.message.MMessage; import dz.esi.edma.noyau.message.Message; /** * La classe de base de tous les agents. Elle crée un agent Atomique comportant * toutes les informations nécessaires pour son bon fonctionnement: *
  • Un identificateur unique. *
  • Un thread de contrôle. *
  • Un cycle de vie qui définit son état. *
  • Une boîte aux lettres (BAL) qui contient des messages. *
  • Une table d’agents (TA). *
  • Une table de compétences réactives. *
  • Une table de compétences proactives. *
  • Une file des tâches. *
  • Deux compétences initiales : une pour communiquer avec ses semblables et * une autre pour apprendre de nouvelles compétences. * * @author Aroussi Sanaa * @author Guessoum Lamia * @version 1.0 2009 */ public class AgentAtomique implements Runnable, Acquisition, Communication, Graphique { /* * LES CLASSES INTERNES */ /* Définir le cycle de vie actif */ private class CycleDeVieActif extends CycleDeVie { /* Spécifier la cause d'attente */ private int causeAttente = 0; private CycleDeVieActif() { super(Initial); } /* * Changer l'état initial à actif, l'état actif à attente ou l'état * attente à actif */ protected void setEtat(int etat, int cause) { this.etat = etat; if (etat == Attente) causeAttente = cause; else causeAttente = 0; setEtatEntree(); } /* Exécuter une tâche */ protected void execute() { ObjetCompétence O = null; if (filedestaches.isEmpty()) cycleDeVieCourant.setEtat(Attente, TacheAExecuter); try { O = filedestaches.take(); } catch (InterruptedException e1) { /* * Le thread du contrôle sera interrompu en appelant la méthode * suspendre ou supprimer */ return;/* Sortir de la méthode */ } if (O != null) { try { URL chemins[] = { new URL(O.getchemin()) }; URLClassLoader loader = new URLClassLoader(chemins); Class cl = loader.loadClass(O.getnom()); Constructor[] ct = cl.getConstructors(); Constructor cons = null; for (int i = 0; i < ct.length; i++) { //System.out.println(ct[i].toString()); if ((ct[i].getParameterTypes().length == 1) && (ct[i].getParameterTypes()[0] .equals(String.class))) { cons = ct[i]; // System.out.println("ok"); break; } } Object o = null; if (cons != null) { //System.out.println("Avec paramètre"); Object[] arg = new String[] { AgentAtomique.this .getNom() }; o = cons.newInstance(arg); } else { o = cl.newInstance(); } Class[] arg = null; Object[] arg1 = null; if (O.getParametre() != null) { Object type[] = O.getParametre(); arg = new Class[type.length]; for (int i = 0; i < type.length; i++) { arg[i] = type[i].getClass(); } arg1 = type; } Method m = o.getClass().getMethod(O.getMethode(), arg); if (m != null) m.invoke(o, arg1); } catch (SecurityException e) { afficherErreur(e); } catch (IllegalArgumentException e) { afficherErreur(e); } catch (NoSuchMethodException e) { afficherErreur(e); } catch (ClassNotFoundException e) { afficherErreur(e); } catch (InstantiationException e) { afficherErreur(e); } catch (IllegalAccessException e) { afficherErreur(e); } catch (MalformedURLException e) { afficherErreur(e); } catch (InvocationTargetException e) { afficherErreur(e); } } /* Le point interruptible de l'agent */ synchronized (mutex) { if (cycleDeVieProchain != null) { cycleDeVieCourant = cycleDeVieProchain; cycleDeVieProchain = null; setEtatEntree(); } } } protected void activer() { /* Réveiller le thread du contrôle */ synchronized (block) { block.notifyAll(); } } } /* Définir le cycle de vie suspendu */ private class CycleDeVieSuspendu extends CycleDeVie { private CycleDeVieSuspendu() { super(Suspendu); } /* Suspendre l'agent */ protected void execute() { /* Bloquer le thread du contrôle */ synchronized (block) { try { block.wait(); } catch (InterruptedException e) { afficherErreur(e); } } } } /* Définir le cycle de vie supprimé */ private class CycleDeVieSupprime extends CycleDeVie { private CycleDeVieSupprime() { super(Supprime); } /* * Annuler l'inscription auprés AMS, supprimer les compétences auprés DF * et libérer les ressources */ protected void fin() { /* desinscription auprés AMS */ RequeteAMS msg = new RequeteAMS(RequeteAMS.ANNULER_INSCRIPTION, AgentAtomique.this, null); try { if ((Boolean) AMS.getDescription().Executer(msg).get()) setEtatEntree(); } catch (InterruptedException e) { afficherErreur(e); } catch (ExecutionException e) { afficherErreur(e); } /*supprimer les compétences*/ Iterator iter = new ArrayList(nomCompetences).iterator(); while (iter.hasNext()) { supprimerCompetence(iter.next()); } /* Nettoyer les structures de données */ TA=null; BAL=null; filedestaches=null; cycleDeVieProchain=null; cycleDeVieSupprime=null; cycleDeVieSuspendu=null; cycleDeVieActif=null; competencesReactives=null; competencesProactives=null; } protected boolean EstEnVie() { return false; } protected void activer() { /* Réveiller le thread du contrôle */ synchronized (block) { block.notifyAll(); } } } /* * LES CONSTANTES */ /** * Définit la priorité minimale qu’un agent peut avoir. La valeur de la * priorité minimale est 1. */ public final static int MIN_PRIORITE = Thread.MIN_PRIORITY; /** * Définit la priorité par défaut d’un agent. La valeur de la priorité par * défaut est 5. */ public final static int NORM_PRIORITE = Thread.NORM_PRIORITY; /** * Définit la priorité maximale qu’un agent peut avoir. La valeur de la * priorité maximale est 10. */ public final static int MAX_PRIORITE = Thread.MAX_PRIORITY; /** * Constante pour définir l'état de l'agent. */ public static final int Initial = 1; /** * Constante pour définir l'état de l'agent. */ public static final int Actif = 2; /** * Constante pour définir l'état de l'agent. */ public static final int Attente = 3; /* Les trois causes d'attente */ private static final int EnvoiMessage = 1; private static final int ReceptionMessage = 2; private static final int TacheAExecuter = 3; /** * Constante pour définir l'état de l'agent. */ public static final int Suspendu = 4; /** * Constante pour définir l'état de l'agent. */ public static final int Supprime = 5; /** Le composant graphique où les agents seront inserés */ private static Object environnementGraphique = null; /* * LES VARIABLES */ /* La date de création de l'agent */ private Date dateDeCreation = null; /* L'identificateur de l'agent */ AID aid = null; /* Le thread de contrôle de l'agent */ Thread thread = null; /* La priorité de l'agent */ private int priorite = -1; /* L'ordre d'arrivé des compétences à exécuter */ private static int ordreArrivé = 1; /* La boite aux lettres de l'agent */ private LinkedBlockingQueue BAL = null; /* La capacité de la boite aux lettres de l'agent */ private int capacite = 0; /* * La base de données de l'agent. Elle contient les descripteurs des agents * qu'il a déjà communiqué avec eux. */ private ArrayList TA = null; /* La file des tâches de l'agent */ PriorityBlockingQueue filedestaches = null; /* Les compétences réactives de l'agent */ private HashMap competencesReactives = null; /* Les compétences proactives de l'agent */ private HashMap competencesProactives = null; /* Les nom des compétence de l'agent */ private ArrayList nomCompetences = null; /* Le cycle de vie courant */ CycleDeVie cycleDeVieCourant = null; /* * Le prochain cycle de vie qui est nécessaire dans le cas où l'agent * exécute une tâche et nous voulons changer son état */ private CycleDeVie cycleDeVieProchain = null; /* Le cycle de vie actif */ private CycleDeVie cycleDeVieActif = null; /* Le cycle de vie supprimé */ private CycleDeVie cycleDeVieSupprime = null; /* Le cycle de vie suspendu */ private CycleDeVie cycleDeVieSuspendu = null; /* Un objet qui sert à suspendre le thread et le réveiller */ private Object block = null; /* * Un objet qui sert à protéger le cycle de vie courant et le prochain cycle * de vie */ private Object mutex = null; /* Le composant graphique qui représente l'agent : L'entrée à l'agent */ private Object entree = null; /* * Le composant graphique où l'agent affiche ses résultats : La sortie de * l'agent */ private Object sortie = null; /* * CONSTRUCTEURS */ AgentAtomique(boolean inscrire, AID nouvAID, int nouvCapacite, int nouvPriorite) throws Exception { if (! inscrire) { try { cycleDeVieCourant = cycleDeVieActif = new CycleDeVieActif(); dateDeCreation = new Date(); aid = nouvAID; thread = new Thread(this); block = new Object(); mutex = new Object(); thread.setPriority(nouvPriorite); priorite = nouvPriorite; capacite = nouvCapacite; BAL = new LinkedBlockingQueue(nouvCapacite); TA = new ArrayList(); competencesProactives = new HashMap(); competencesReactives = new HashMap(); nomCompetences = new ArrayList(); filedestaches = new PriorityBlockingQueue(); } catch (Exception e) { throw new Exception(); } } } /** *Créer un agent atomique en spécifiant son nom, la capacité de sa boite * aux lettre, et sa priorité. * * @param nouvNom * le nom de l'agent * @param nouvCapacite * la capacité de la boite aux lettres de l'agent. * @param nouvPriorite * la priorité de l'agent. * @throws Exception * lorsque la création de l'agent échoue */ public AgentAtomique(AID nouvAID, int nouvCapacite, int nouvPriorite) throws Exception { try { cycleDeVieCourant = cycleDeVieActif = new CycleDeVieActif(); dateDeCreation = new Date(); aid = nouvAID; thread = new Thread(this); block = new Object(); mutex = new Object(); thread.setPriority(nouvPriorite); priorite = nouvPriorite; capacite = nouvCapacite; BAL = new LinkedBlockingQueue(nouvCapacite); TA = new ArrayList(); competencesProactives = new HashMap(); competencesReactives = new HashMap(); nomCompetences = new ArrayList(); filedestaches = new PriorityBlockingQueue(); getEntree(); /* appelle automatiquement getSortie */ RequeteAMS msg = new RequeteAMS(RequeteAMS.INSCRIRE, this, null); if (!(Boolean) AMS.getDescription().Executer(msg).get()) throw new Exception(); } catch (Exception e) { throw e; } ajouterEntree(); ajouterSortie(); } /** * Créer un agent atomique avec ses propriétés par défaut. * * @throws Exception * lorsque la création de l'agent échoue */ public AgentAtomique() throws Exception { this(new AID("Agent" + AMS.getNbrAgentsCrees()), Integer.MAX_VALUE, NORM_PRIORITE); } /** * Créer un agent atomique en spécifiant son nom. * * @param nouvNom * le nom de l'agent * @throws Exception * lorsque la création de l'agent échoue */ public AgentAtomique(String nouvNom) throws Exception { this(new AID(nouvNom), Integer.MAX_VALUE, NORM_PRIORITE); } /** * Créer un agent atomique en spécifiant la capacité de sa BAL. * * @param nouvCapacite * la capacité de la boite aux Lettres de l'agent * @throws Exception * lorsque la création de l'agent échoue */ public AgentAtomique(int nouvCapacite) throws Exception { this(new AID("Agent" + AMS.getNbrAgentsCrees()), nouvCapacite, NORM_PRIORITE); } /** * Créer un agent atomique en spécifiant son nom et la capacité de sa BAL. * * @param nouvNom * le nom de l'agent * @param nouvCapacite * la capacité de la boite aux Lettres de l'agent * @throws Exception * lorsque la création de l'agent échoue */ public AgentAtomique(String nouvNom, int nouvCapacite) throws Exception { this(new AID(nouvNom), nouvCapacite, NORM_PRIORITE); } /* * CYCLE DE VIE */ /** Suspendre l'exécution de l'agent. */ public final void suspendre() { synchronized (mutex) { if (cycleDeVieCourant.equals(cycleDeVieActif)) { if (cycleDeVieSuspendu == null) cycleDeVieSuspendu = new CycleDeVieSuspendu(); if (((CycleDeVieActif) cycleDeVieCourant).causeAttente == TacheAExecuter) { cycleDeVieCourant = cycleDeVieSuspendu; thread.interrupt(); setEtatEntree(); } else cycleDeVieProchain = cycleDeVieSuspendu; } } } /** Reprendre l'éxecution de l'agent. */ public final void reprendre() { synchronized (mutex) { if (cycleDeVieCourant.equals(cycleDeVieSuspendu)) { /* positionner le cycle de vie(execute) */ cycleDeVieCourant = cycleDeVieActif; /* réveiller le thread du contrôle */ cycleDeVieCourant.activer(); setEtatEntree(); } } } /** * Supprimer l'agent. */ public final void supprimer() { if (cycleDeVieSupprime == null) cycleDeVieSupprime = new CycleDeVieSupprime(); synchronized (mutex) { if (cycleDeVieCourant.equals(cycleDeVieSuspendu)) { /* Positionner le cycle de vie (estEnVie) */ cycleDeVieCourant = cycleDeVieSupprime; /* réveiller le thread du contrôle s'il est bloqué */ cycleDeVieCourant.activer(); } if (cycleDeVieCourant.equals(cycleDeVieActif)) { /* S'il est en attente d'une tâche à réaliser */ if (((CycleDeVieActif) cycleDeVieCourant).causeAttente == TacheAExecuter) { cycleDeVieCourant = cycleDeVieSupprime; thread.interrupt(); } else cycleDeVieProchain = cycleDeVieSupprime; } } } public final void run() { while (cycleDeVieCourant.EstEnVie()) { cycleDeVieCourant.execute(); } cycleDeVieCourant.fin(); } /* * LES METHODES CONCERNANT L'INTERFACE ACQUISITION */ public final boolean ajouterCompetence(String nom,String chemin,boolean execute) { if((getEtat()!=Supprime) &&(!nomCompetences.contains(nom))) { try{ URL chemins[] = { new URL(chemin) }; URLClassLoader loader = new URLClassLoader(chemins); Class cl=loader.loadClass(nom); Class c = cl.getSuperclass(); if ((c.getName()).equals("dz.esi.edma.noyau.competences.Compétence")) { if (!competencesReactives.containsKey(nom)) { if(enregistrerCompetence(nom, chemin)) { competencesReactives.put(nom, chemin); nomCompetences.add(nom); MAJlistCompetence(true, nom); return true; } } else {return false;} } else if((c.getName()).equals("dz.esi.edma.noyau.competences.CompétenceAction")) { if (!competencesProactives.containsKey(nom)) { competencesProactives.put(nom, chemin); nomCompetences.add(nom); MAJlistCompetence(true, nom); if(execute) { ObjetCompétence O = new ObjetCompétence(nom, chemin, "Action", null, 0, ordreArrivé); filedestaches.put(O); ordreArrivé++; } } else return false; } else return false; } catch (SecurityException e) { return false; } catch (IllegalArgumentException e) { return false; } catch (ClassNotFoundException e) { return false; } catch (MalformedURLException e) { return false; } } return false; } public final boolean enseignerCompetence(String competence, AgentAtomique recepteur) { if ((competencesReactives.containsKey(competence)) && (recepteur != null)) { MCCompetence contenu = new MCCompetence(competence, competencesReactives.get(competence), null, null); MMCompetence msg = new MMCompetence(contenu, MMCompetence.ENSEIGNER); msg.addRecepteurs(recepteur); msg.setEmetteur(this); return envoyerEnUrgence(msg); } else return false; } public final boolean enseignerCompetence(String competence, AID recepteur) { if ((competencesReactives.containsKey(competence)) && (recepteur != null)) { MCCompetence contenu = new MCCompetence(competence, competencesReactives.get(competence), null, null); MMCompetence msg = new MMCompetence(contenu, MMCompetence.ENSEIGNER); msg.addRecepteurs(recepteur); msg.setEmetteur(this); return envoyerEnUrgence(msg); } else return false; } public final boolean executerCompetence(String competence, String methode, Object[] args) { if(getEtat()!=Supprime) if (competencesProactives.containsKey(competence)) { String chemin = competencesProactives.get(competence); ObjetCompétence O = new ObjetCompétence(competence, chemin, "Action", null, 0, ordreArrivé); filedestaches.put(O); ordreArrivé++; return true; } else if (competencesReactives.containsKey(competence)) { try { URL chemins[] = { new URL(competencesReactives.get(competence)) }; URLClassLoader loader = new URLClassLoader(chemins); Class cl = loader.loadClass(competence); Method[] M = cl.getDeclaredMethods(); //System.out.println("le nombre des méthodes "+M.length); for (int i = 0; i < M.length; i++) { boolean trouve = true; if (M[i].getName().equals(methode)) { Class[] paramTypes = null; Class[] argument = new Class[M[i].getParameterTypes().length]; if (args != null) { paramTypes = new Class[args.length]; for (int j = 0; j < args.length; j++) { paramTypes[j] = args[j].getClass(); } } for (int j = 0; j < M[i].getParameterTypes().length; j++) { argument[j] = M[i].getParameterTypes()[j]; } for (int l = 0; l < argument.length; l++) { if (!(argument[l].toString()).equals(paramTypes[l].toString())) { trouve = false; } if (trouve) { ObjetCompétence O = new ObjetCompétence(competence, competencesReactives.get(competence), methode, args, 1, ordreArrivé); filedestaches.put(O); ordreArrivé++; return true; } } } } } catch (SecurityException E) { return false; } catch (IllegalArgumentException E) { return false; } catch (ClassNotFoundException E) { return false; } catch (MalformedURLException E) { return false; } } return false; } public final boolean traiterMessageCompetence(IMCompetence msg) { String competence = msg.getContenu().getNomCompetence(); String chemin = msg.getContenu().getChemin(); String methode = msg.getContenu().getNomMethode(); Object[] arg = msg.getContenu().getArgumentsMethode(); Object emetteur = msg.getEmetteur(); switch (msg.getPerformative()) { case IMCompetence.EXECUTER: /* Exécuter une compétence */ return executerCompetence(competence, methode, arg); case IMCompetence.DEMANDE_ENSEIGNER: /*Demande d'enseigner une compétence */ if (emetteur instanceof AID) return enseignerCompetence(competence, (AID) emetteur); else if(emetteur instanceof AgentAtomique) return enseignerCompetence(competence,(AgentAtomique) emetteur); case IMCompetence.ENSEIGNER: /* Enseigner une compétence */ { return ajouterCompetence(competence, chemin,false); } case IMCompetence.NECOMPRENDPAS:{} default:{ if(emetteur != null) { MMCompetence msg1=new MMCompetence(msg.getContenu(),MMCompetence.NECOMPRENDPAS); msg1.setEmetteur(this); if (emetteur instanceof AID) msg1.addRecepteurs((AID) emetteur); else msg1.addRecepteurs((AgentAtomique) emetteur); return envoyerEnUrgence(msg1); } } } return false; } @SuppressWarnings("static-access") public final boolean supprimerCompetence(String nom) { if (competencesReactives.containsKey(nom)) { String chemin = competencesReactives.get(nom); competencesReactives.remove(nom); supprimerCompetenceduDF(nom, chemin); nomCompetences.remove(nom); MAJlistCompetence(false, nom); return true; } else { if(competencesProactives.containsKey(nom)) { competencesProactives.remove(nom); nomCompetences.remove(nom); MAJlistCompetence(false, nom); return true; } else { ecrireConsole("La Compétence " + nom + " n'existe pas\r\n"); return false; } } } /* * LES METHODES DE L'INTERFACE COMMUNICATION */ public final boolean envoyer(Message msg) { return envoyer(msg, 0, TimeUnit.NANOSECONDS); } public final boolean envoyerEnUrgence(Message msg) { return envoyer(msg, -1, TimeUnit.NANOSECONDS); } public final boolean envoyer(Message msg, long timeOut, TimeUnit unite) { /* * 0- Vérifier que timeOut >0 ou == 0(mode d'envoi immédiat) ou == * -1(mode d'envoi attente jusqu'à non pleine) */ if ((timeOut < 0) && (timeOut != -1)) return false; /* 1- Vérifier qu'il existe au moins un récepteur pour le message */ if (msg.getRecepteurs().size() == 0) return false; /* * 2- Vérifier que le contenu du message MMString, MMObjet et * MMCompétence sont non null. Pour le contenu du IMString, IMObjet et * IMCompétence sont tjrs non nulls. Cette vérification est faite dans * leurs constructeurs. La plupart des messages ACL exigent le parametre * content. Certains types de message (selon la performative), ont * implicitement le contenu. */ if ((msg instanceof MMString) && (((MMString) msg).getContenu() == null)) return false; if ((msg instanceof MMObjet) && (((MMObjet) msg).getContenu() == null)) return false; if ((msg instanceof MMCompetence) && (((MMCompetence) msg).getContenu() == null)) return false; /* * 3- Transformer le message mutable en message immuable (s'il n'est * pas) */ Message msg1 = msg; if (msg instanceof MMessage) msg1 = ((MMessage) msg).toImmuable(); /* Le processus d'envoi */ for (int i = 0; i < msg1.getNbrRecepteurs(); i++) { Object recepteur = msg1.getRecepteurs().get(i); /* 4 - Vérifier que l'émetteur n'envoi pas le message à lui même */ if (recepteur.equals(this)) { /* * 10- Mettre à jour l'accusé de réception : Echec d'envoi */ msg.getAccuseReception().set(i, false); continue; } AgentAtomique agentRecepteur = null; if (recepteur instanceof AID) { /* * 5- Recherche locale */ int j = TA.indexOf(recepteur); if (j != -1) { agentRecepteur = TA.get(j); if (agentRecepteur.getEtat() == Supprime) { /* l'agent est supprimé */ /* MAJ TA */ TA.remove(i); /* Echec d'envoi */ msg.getAccuseReception().set(i, false); continue; } } else { /* * 6- recherche globale */ agentRecepteur = (AgentAtomique) rechercher((AID) recepteur); if (agentRecepteur == null) { /* l'agent est supprimé */ /* Echec d'envoi */ msg.getAccuseReception().set(i, false); continue; } else { /* MAJ TA */ TA.add(agentRecepteur); } } } else { agentRecepteur = (AgentAtomique) recepteur; if (!TA.contains(agentRecepteur)) /* MAJ TA */ TA.add(agentRecepteur); } /* mode d'envoi immédiat */ if (timeOut == 0) { /* Déposer le message et MAJ accusé de réception */ msg.getAccuseReception().set(i, agentRecepteur.BAL.offer(msg1)); continue; } /* mode d'envoi attente jusqu'à non plein */ if (timeOut == -1) { cycleDeVieCourant.setEtat(Attente, EnvoiMessage); try { /* Déposer le message */ agentRecepteur.BAL.put(msg1); /* Accusé de Réception positif */ msg.getAccuseReception().set(i, true); } catch (InterruptedException e) { /* cas impossible */ msg.getAccuseReception().set(i, false); } cycleDeVieCourant.setEtat(Actif, 0); continue; } /* mode d'envoi attente jusqu'à timeOut */ cycleDeVieCourant.setEtat(Attente, EnvoiMessage); try { /* Déposer le message et MAJ accusé de réception */ msg.getAccuseReception().set(i, agentRecepteur.BAL.offer(msg1, timeOut, unite)); } catch (InterruptedException e) { /* cas impossible */ msg.getAccuseReception().set(i, false); } cycleDeVieCourant.setEtat(Actif, 0); } return true; } public final boolean diffuser(Message msg) { return diffuser(msg, 0, TimeUnit.NANOSECONDS); } public final boolean diffuserEnUrgence(Message msg) { return diffuser(msg, -1, TimeUnit.NANOSECONDS); } /* * L'émetteur demande une copie de répertoire de AMS, puis il envoi le msg à * chaque agent, en utilisant la méthode Envoyer(Message, long, Timeunit); */ public final boolean diffuser(Message msg, long timeMoyenne, TimeUnit unite) { if (msg instanceof IMessage) msg = ((IMessage) msg).toMutable(); ((MMessage) msg).clearRecepteurs(); Iterator iter = AMS.getAgents().iterator(); ((MMessage) msg).addRecepteurs(iter); return envoyer(msg, timeMoyenne, unite); } public final Message recevoir() { return BAL.poll(); } public final Message recevoir(long timeOut, TimeUnit unite) throws InterruptedException { if (timeOut < 0) return null; Message msg = null; cycleDeVieCourant.setEtat(Attente, ReceptionMessage); try { msg = BAL.poll(timeOut, unite); } catch (InterruptedException e) { afficherErreur(e); } cycleDeVieCourant.setEtat(Actif, 0); return msg; } public final Message recevoirEnUrgence() { Message msg = null; cycleDeVieCourant.setEtat(Attente, ReceptionMessage); try { msg = BAL.take(); return msg; } catch (InterruptedException e) { afficherErreur(e); } cycleDeVieCourant.setEtat(Actif, 0); return msg; } /* * LES METHODES CONCERNANT LA BOITE AUX LETTRES */ /** * @return le nombre des messages dans la boite aux lettre de l'agent * @see #getCapacite() * @see #getCapaciteRestantBAL() */ public final int getNbrEltBAL() { return BAL.size(); } /** * @return true si la boite aux lettres de l'agent est vide *
    * sinon false *
    * @see #BALPleine() */ public final boolean BALVide() { return BAL.isEmpty(); } /** * @return true si la boite aux lettres de l'agent est pleine *
    * sinon false *
    * @see #BALVide() */ public final boolean BALPleine() { return (BAL.size() == capacite); } /** * @return le nombre des messages restants à ajouter dans la boite aux * lettres de l'agent. * @see #getCapacite() * @see #getNbrEltBAL() */ public final int getCapaciteRestantBAL() { return BAL.remainingCapacity(); } /** * Vider la boite aux lettres de l'agent. */ public final void viderBAL() { BAL.clear(); } /* * LES METHODES CONCERNANT AID */ /** * @return le nom local de l'agent. */ public final String getNom() { return aid.nom; } /** * @return le nom global de l'agent. */ public final String getGUID() { return aid.getGUID(); } /* * LES METHODES NECESSITANT AMS */ /** * Modifier le nom local de l'agent. * * @param nouvNom * le nouveau nom local de l'agent * @return true si le nouvNom n'existe pas pour un autre * agent. *
    * false sinon. *
    */ public final boolean setNom(String nouvNom) { if (nouvNom == null) return false; RequeteAMS msg = new RequeteAMS(RequeteAMS.MODIFIER, this, new AID( nouvNom)); try { return ((Boolean) AMS.getDescription().Executer(msg).get()); } catch (InterruptedException e) { return false; } catch (ExecutionException e) { return false; } } /** * Rechercher le descripteur d'un autre agent. * * @param aid * l'identificateur de l'agent à rechercher * @return le descripteur de l'agent qui correspond à aid * sinon null. */ public static final AgentAtomique rechercher(AID aid) { if (aid == null) return null; RequeteAMS msg = new RequeteAMS(RequeteAMS.RECHERCHER, null, aid); try { return (AgentAtomique) AMS.getDescription().Executer(msg).get(); } catch (InterruptedException e) { return null; } catch (ExecutionException e) { return null; } } /** * Créer un fils. *
  • Si l'identificateur AID est null alors le fils * possédera un identificateur par défaut. * * @param fils * l'identificateur correspondant au fils. * @return le descripteur de fils s'il est bien crée. *
    * null sinon *
    */ public final AgentAtomique creerFils(AID fils) { RequeteAMS msg = new RequeteAMS(RequeteAMS.CREER, this, fils); try { AgentAtomique a = ((AgentAtomique) AMS.getDescription().Executer( msg).get()); if (a != null) { a.getEntree(); a.ajouterEntree(); a.ajouterSortie(); } return a; } catch (InterruptedException e) { return null; } catch (ExecutionException e) { return null; } } public final AgentAtomique creerFils(AID fils, int capacite, int priorite) { RequeteAMS msg = new RequeteAMS(RequeteAMS.CREER, this, fils); if (capacite < 0) return null; if ((priorite > MAX_PRIORITE) || (priorite < MIN_PRIORITE)) return null; msg.capacite = capacite; msg.priorite = priorite; try { AgentAtomique a = ((AgentAtomique) AMS.getDescription().Executer( msg).get()); if (a != null) { a.getEntree(); a.ajouterEntree(); a.ajouterSortie(); } return a; } catch (InterruptedException e) { return null; } catch (ExecutionException e) { return null; } } /** * Suspendre le fils qui correspond à l'identificateur fils * * @param fils * l'identificateur du fils * @return true si l'agent fils est suspendu *
    * false sinon. *
    */ public final boolean suspendreFils(AID fils) { if (fils == null) return false; RequeteAMS msg = new RequeteAMS(RequeteAMS.SUSPENDRE, this, fils); try { return ((Boolean) AMS.getDescription().Executer(msg).get()); } catch (InterruptedException e) { return false; } catch (ExecutionException e) { return false; } } /** * Réveiller le fils qui correspond à l'identificateur fils * * @param fils * l'identificateur du fils * @return true si l'agent fils est réveillé *
    * false sinon. *
    */ public final boolean reprendreFils(AID fils) { if (fils == null) return false; RequeteAMS msg = new RequeteAMS(RequeteAMS.REPRENDRE, this, fils); try { return ((Boolean) AMS.getDescription().Executer(msg).get()); } catch (InterruptedException e) { return false; } catch (ExecutionException e) { return false; } } /** * Supprimer le fils qui correspond à l'identificateur fils * * @param fils * l'identificateur du fils * @return true si l'agent fils est tué *
    * false sinon. *
    */ public final boolean supprimerFils(AID fils) { if (fils == null) return false; RequeteAMS msg = new RequeteAMS(RequeteAMS.SUPPRIMER, this, fils); try { return ((Boolean) AMS.getDescription().Executer(msg).get()); } catch (InterruptedException e) { return false; } catch (ExecutionException e) { return false; } } /* * LES METHODES CONCERNANT DF */ private boolean enregistrerCompetence(String nom, String chemin) throws IllegalArgumentException { try { URL chemins[] = { new URL(chemin) }; URLClassLoader loader = new URLClassLoader(chemins); Class cl = loader.loadClass(nom); Method[] M = cl.getDeclaredMethods(); for (int i = 0; i < M.length; i++) { Object[] arg = null; if (M[i].getParameterTypes() != null) { arg = new Object[M[i].getParameterTypes().length]; for (int j = 0; j < M[i].getParameterTypes().length; j++) arg[j] = M[i].getParameterTypes()[j]; } RequeteDF requete = new RequeteDF(RequeteDF.ENREGISTRER, nom, M[i].getName(), arg, aid); try { if (!(Boolean) (DF.getDescription().Executer(requete).get())) throw new IllegalArgumentException(); } catch (InterruptedException e) { return false; } catch (ExecutionException e) { return false; } } return true; } catch (SecurityException e) { ecrireConsole(e.getMessage()+" "+e.getCause()); return false; } catch (IllegalArgumentException e) { ecrireConsole(e.getMessage()+" "+e.getCause()); return false; } catch (ClassNotFoundException e) { ecrireConsole("La classe"+e.getMessage()+ "n'existe pas"); return false; } catch (MalformedURLException e) { ecrireConsole(e.getMessage()+" "+e.getCause()); return false; } } public static ArrayList rechercherMethode(String nomCompetence, String nomMethode) { if ((nomMethode == null) || (nomCompetence == null)) return null; else { RequeteDF requete = new RequeteDF(RequeteDF.CHERCHERSANSPARAMETRES, nomCompetence, nomMethode, null, null); try { return (ArrayList) DF.getDescription().Executer(requete).get(); } catch (InterruptedException e) { return null; } catch (ExecutionException e) { return null; } } } public static AID[] rechercherMethode(String nomCompetence, String nomMethode, Object[] args) { if ((nomMethode == null) || (nomCompetence == null)) return null; else { RequeteDF requete = new RequeteDF(RequeteDF.CHERCHERAVECPARAMETRES, nomCompetence, nomMethode, args, null); try { return (AID[]) DF.getDescription().Executer(requete).get(); } catch (InterruptedException e) { return null; } catch (ExecutionException e) { return null; } } } private void supprimerCompetenceduDF(String nom, String chemin) throws IllegalArgumentException{ try { URL chemins[] = { new URL(chemin) }; URLClassLoader loader = new URLClassLoader(chemins); Class cl = loader.loadClass(nom); Method[] M = cl.getDeclaredMethods(); for (int i = 0; i < M.length; i++) { Object[] arg = null; if (M[i].getParameterTypes() != null) { arg = new Object[M[i].getParameterTypes().length]; for (int j = 0; j < M[i].getParameterTypes().length; j++) arg[j] = M[i].getParameterTypes()[j]; } RequeteDF requete = new RequeteDF(RequeteDF.SUPPRIMER, nom, M[i].getName(), arg, aid); try { if (!(Boolean) (DF.getDescription().Executer(requete).get())) throw new IllegalArgumentException(); //System.out.println("Retourner faux"); } catch (InterruptedException e) { afficherErreur(e); } catch (ExecutionException e) { afficherErreur(e); } } } catch (SecurityException e) { afficherErreur(e); } catch (IllegalArgumentException e) { afficherErreur(e); } catch (ClassNotFoundException e) { afficherErreur(e); } catch (MalformedURLException e) { afficherErreur(e); } } /* * LES GETTERS DES VARAIBLES */ /** * @return la capacité de la boite aux lettres de l'agent * @see #getNbrEltBAL() * @see #getCapaciteRestantBAL() */ public final int getCapacite() { return capacite; } /** * @return la priorité de l'agent. */ public final int getPriorite() { return (priorite); } /** * @return une copie de la table des agents. */ @SuppressWarnings("unchecked") public final ArrayList getTA() { return (ArrayList) TA.clone(); } /** * @return true si l'agent a communiqué avec le DF sinon false. */ public final boolean isCommuniquerDF() { return aid.communiquerDF; } /** * @return la date de création de l'agent. */ public final Date getDateDeCreation() { return dateDeCreation; } /** * @param priorite * la priorité de l'agent. * @return la priorité de l'agent sous forme d'une chaîne de caractère. */ public static final String prioriteToString(int priorite) { switch (priorite) { case MIN_PRIORITE: return "minimale"; case NORM_PRIORITE: return "normale"; case MAX_PRIORITE: return "maximale"; } return null; } /** * @return les compétences réactives de l'agent. */ public final Set> getCompetencesReactives() { return competencesReactives.entrySet(); } public final Set> getCompetencesProactives() { return competencesProactives.entrySet(); } /** * @return l'état de l'agent. */ public final int getEtat() { return cycleDeVieCourant.getEtat(); } /** * @param etat * l'état de l'agent. * @return l'état de l'agent sous forme d'une chaîne de caractères. */ public final String etatToString(int etat) { switch (etat) { case Initial: return "initial"; case Actif: return "actif"; case Attente: String str = "attente"; switch (((CycleDeVieActif)cycleDeVieCourant).causeAttente) { case EnvoiMessage : str = str + " l'envoi d'un message"; break; case ReceptionMessage : str = str + " la réception d'un message"; break; case TacheAExecuter : str = str+ " d'une tâche à exécuter"; } return str; case Suspendu: return "suspendu"; case Supprime: return "supprime"; } return null; } /** * @return une copie de compétence de l'agent. */ @SuppressWarnings("unchecked") public final ArrayList getNomCompetences() { return (ArrayList) nomCompetences.clone(); } /* * LES SETTERS DES VARIABLES */ /** * Définir la priorité de l'agent. Cette priorité doit être comprise entre * MIN_ PRIORITE et MAX_ PRIORITE. Utilisez * NORM_ PRIORITE pour une priorité normale. * * @param nouvPriorite * la nouvelle priorité de l'agent * @return true si MIN_PRIORITE<= nouvPriorite <= MAX_PRIORITE *
    * sinon false. *
    * @see #MAX_PRIORITE * @see #MIN_PRIORITE * @see #NORM_PRIORITE */ public final boolean setPriorite(int nouvPriorite) { if ((nouvPriorite >= MIN_PRIORITE) && (nouvPriorite <= MAX_PRIORITE)) { thread.setPriority(nouvPriorite); priorite = nouvPriorite; return true; } return false; } public static void setEnvironnementGraphique(Object environnementGraphique) { AgentAtomique.environnementGraphique = environnementGraphique; } /* * LES METHODES DE L'OBECT */ /** * @param agent * l'agent * @return true si l'agent en cours correspond à agent */ public final boolean equals(AgentAtomique agent) { if (agent instanceof AgentAtomique) return aid.equals(((AgentAtomique) agent).aid); return false; } /* * retourne true si les deux agents sont identitiques (même AID) ET aussi si * on compare l'agent avec son identificateur. En effet:Les récepteurs du * message est de type Arraylist où T peut être AID ou AgentAtomique. * Pour ne pas insérer des doublons, la méthode equals doit nous retourne * true si on compare l'agent avec son identificateur pour que la méthode * contains return true; */ public final boolean equals(Object o) { if (o instanceof AgentAtomique) return aid.equals(((AgentAtomique) o).aid); if (o instanceof AID) return aid.equals((AID) o); return false; } /** * @return une représentation de l'agent sous forme (Identité, Nom, * Priorité, Etat, Date de création). */ public String toString() { String str = "GUID = " + aid.getGUID() + " ; " + "ETAT = " + etatToString(getEtat()) + " ; " + "PRIORITE = " + prioriteToString(priorite) + " ; " + "DATE DE CREATION = " + dateDeCreation + " ."; return str; } /* * LES METHODES CONCERNANT L'INTERFACE GRAPHIQUE */ /* * public Object getEntree() { return null; } */ public Object getEntree() { if ((entree == null) && (environnementGraphique != null)) { entree = new JPanelAgent(this, (JInternalFrameAgent) getSortie()); if (Interface.jPanelAgentSelectionne != null) { Interface.jPanelAgentSelectionne.setBorder(new MatteBorder(0, 0, 0, 0, Color.WHITE)); Interface.jPanelAgentSelectionne.getPopupMenu().setVisible( false); } Interface.jPanelAgentSelectionne = (JPanelAgent) entree; ((JPanelAgent) entree).setBorder(new MatteBorder(5, 5, 5, 5, JPanelAgent.getColor(getEtat()))); } return entree; } /* * public void ajouterEntree() {} */ public void ajouterEntree() { if (entree != null) { ((Interface) environnementGraphique).getJPanelAgents().add( (JPanelAgent) entree, null); /* Redessiner Fenetres d'agents */ ((Interface) environnementGraphique).getJPanelAgents().validate(); ((Interface) environnementGraphique).getJPanelAgents().repaint(); ((Interface) environnementGraphique).getJScrollPane().validate(); } } /* * public void setEtarEntree() {} */ public void setEtatEntree() { if (entree != null) { ((JPanelAgent) getEntree()) .setFond(new ImageIcon((((Image) Toolkit.getDefaultToolkit().getImage( getClass().getResource(JPanelAgent.getImageFond(getEtat()))))). getScaledInstance(125, 70,Image.SCALE_DEFAULT)).getImage()); if (entree == Interface.jPanelAgentSelectionne) { Interface.jPanelAgentSelectionne.setBorder(new MatteBorder(5, 5, 5, 5, JPanelAgent.getColor(getEtat()))); switch (getEtat()) { case AgentAtomique.Actif: ((Interface) environnementGraphique).getSuspendreAgent() .setEnabled(true); ((Interface) environnementGraphique).getReprendreAgent() .setEnabled(true); ((Interface) environnementGraphique).getSupprimerAgent() .setEnabled(true); ((Interface) environnementGraphique).getNom().setEnabled( true); ((Interface) environnementGraphique).getPriorite() .setEnabled(true); ((Interface) environnementGraphique).getAjouterCompetence() .setEnabled(true); ((Interface) environnementGraphique) .getSupprimerCompetence().setEnabled(true); ((Interface) environnementGraphique) .getExecuterCompetence().setEnabled(true); break; case AgentAtomique.Attente: ((Interface) environnementGraphique).getSuspendreAgent() .setEnabled(true); ((Interface) environnementGraphique).getReprendreAgent() .setEnabled(true); ((Interface) environnementGraphique).getSupprimerAgent() .setEnabled(true); ((Interface) environnementGraphique).getNom().setEnabled( true); ((Interface) environnementGraphique).getPriorite() .setEnabled(true); ((Interface) environnementGraphique).getAjouterCompetence() .setEnabled(true); ((Interface) environnementGraphique) .getSupprimerCompetence().setEnabled(true); ((Interface) environnementGraphique) .getExecuterCompetence().setEnabled(true); break; case AgentAtomique.Suspendu: ((Interface) environnementGraphique).getSuspendreAgent() .setEnabled(false); ((Interface) environnementGraphique).getReprendreAgent() .setEnabled(true); ((Interface) environnementGraphique).getSupprimerAgent() .setEnabled(true); ((Interface) environnementGraphique).getNom().setEnabled( true); ((Interface) environnementGraphique).getPriorite() .setEnabled(true); ((Interface) environnementGraphique).getAjouterCompetence() .setEnabled(true); ((Interface) environnementGraphique) .getSupprimerCompetence().setEnabled(true); ((Interface) environnementGraphique) .getExecuterCompetence().setEnabled(true); break; case AgentAtomique.Supprime: ((Interface) environnementGraphique).getSuspendreAgent() .setEnabled(false); ((Interface) environnementGraphique).getReprendreAgent() .setEnabled(false); ((Interface) environnementGraphique).getSupprimerAgent() .setEnabled(false); ((Interface) environnementGraphique).getNom().setEnabled( false); ((Interface) environnementGraphique).getPriorite() .setEnabled(false); ((Interface) environnementGraphique).getAjouterCompetence() .setEnabled(false); ((Interface) environnementGraphique) .getSupprimerCompetence().setEnabled(false); ((Interface) environnementGraphique) .getExecuterCompetence().setEnabled(false); } } ((JPanelAgent) getEntree()).validate(); ((JPanelAgent) getEntree()).repaint(); } } /* * public void supprimerEntree() {} */ public void supprimerEntree() { if (entree != null) { ((Interface) environnementGraphique).getJPanelAgents().remove( (JPanelAgent) entree); ((Interface) environnementGraphique).getJPanelAgents().validate(); ((Interface) environnementGraphique).getJPanelAgents().repaint(); ((Interface) environnementGraphique).getJScrollPane().validate(); } } /* * public Object getSortie() { return null; } */ public Object getSortie() { if ((sortie == null) && (environnementGraphique != null)) { sortie = new JInternalFrameAgent(); ((JInternalFrameAgent) sortie).setTitle(getNom()); } return sortie; } /* * public void ajouterSortie() {} */ public void ajouterSortie() { if (sortie != null) { ((Interface) environnementGraphique).getJPanelExecution().add( (JInternalFrameAgent) sortie, null); ((Interface) environnementGraphique).getJPanelExecution() .validate(); ((Interface) environnementGraphique).getJScrollPane1().repaint(); } } /* * public void Ecrire() {} */ public void ecrireFenetre(String x) { if (sortie != null) { ((JInternalFrameAgent) sortie).getJTextArea().append(x); ((JInternalFrameAgent) sortie).getJTextArea().append("\r\n"); } } /* * public void removeSortie() {} */ public void supprimerSortie() { if (sortie != null) { ((Interface) environnementGraphique).getJPanelExecution().remove( (JInternalFrameAgent) sortie); ((Interface) environnementGraphique).getJPanelExecution() .validate(); ((Interface) environnementGraphique).getJScrollPane1().repaint(); } } public void ecrireConsole(String x) { if (environnementGraphique != null) Interface.jListConsole.append(x + "\r\n"); } public static Object getEnvironnementGraphique() { return environnementGraphique; } public void MAJlistCompetence(boolean ajouter, String competence) { if(environnementGraphique !=null) if (ajouter) ((Interface) environnementGraphique).ListCompetences.addElement(competence); else ((Interface) environnementGraphique).ListCompetences.removeElement(competence); } public void afficherErreur(Exception e) { if (environnementGraphique != null) ecrireConsole(e.getMessage() +"---"+ e.getCause()); else e.printStackTrace(); } }