package graphe; import java.io.*; import java.lang.*; import java.util.*; import java.text.*; import javax.swing.*; /** * Classe Sommet. * Le Sommet permet de communiquer avec les Sommets voisins du graphe. * Il connaît tous ses voisins ainsi que le nombre de sommets total du graphe. * Il permet aussi d'effectuer des statistiques sur le nombre de messages échangés * ainsi que sur la durée de certains traitements. * @author Estelle Colin, Thomas Peclier, Fabrice Berna @ IUP GMI * @see Graphe, Application * @version 1.0 */ public abstract class Sommet extends Thread { /*----------------------------- Variables -----------------------------*/ /** *Variable utilisée pour un tirage aléatoire des sommets */ private final Random rand; /** * Nombre de sommets du graphe */ int nbSommet; /** * Identifiant du Sommet */ int id; /** * Nombre de voisins dans le graphe */ public int nbvoisins; /** * Tableau permettant de retrouver le canal par rapport à l'identifiants d'un voisins */ int[] voisins; /** * Tableau permettant de retrouver l'identifiant d'un voisin à partir du numéro de son canal de communication */ public int[] voisinsId; /** *Tableau de PipeReader (réception des messages) */ private final PipedReader[] pipeLecteur; /** * Tableau de BufferedReader (lecture des messages reçus dans les tubes) */ private final BufferedReader[] lecteur; /** * Tableau de PipeWriter (envoi des messages) */ private final PipedWriter[] ecrivain; /** * Permet l'exécution ou arrête le Thread */ private boolean encours; /** * Totalise le nombre total de messages envoyés pour les statistiques */ private int nbMess; /** * Totalise le nombre total de messages pour la coloration */ private int nbMessCouleur; /** * Totalise la durée de certains traitements */ private int debut; int fin; /** * Canaux d'écriture */ private PrintStream sortie; private JTextArea visu; /*----------------------------- Accesseurs -----------------------------*/ /** * Getter d'un lecteur * @param int, le numéro du lecteur * @return PipedReader */ public final PipedReader getLecteur(int i) { return pipeLecteur[voisins[i]]; } /** * Getter d'un ecrivain * @param int, le numéro de l'écrivain * @return PipedWriter */ public final PipedWriter getEcrivain(int i) { return ecrivain[voisins[i]]; } /** * Getter du nombre de messages envoyés * @return int */ public final int getNbMess() { return nbMess; } /** * Getter de la durée d'un traitement * @return long */ public int getDuree() { if (fin != 0) return (fin - debut); else return 0; } /** * Getter du nombre de messages de couleur * @return int */ public final int getNbMessCouleur(){ return(nbMessCouleur); } /*----------------------------- Méthodes -----------------------------*/ /** * Constructeur du ThreadSommet. * Initialisation des variables. * @param int, l'indentifiant * @param int, le nombre de sommets du graphe * @param boolean[], la liste des voisins */ public Sommet(int i, int nb, boolean[] v, JTextArea out) { id = i; nbvoisins = 0; encours = true; nbSommet = nb; rand = new Random(); //canal d'écriture if (out == null) sortie = new PrintStream(System.out); else { sortie = null; visu = out; } //initialisation du nombre de voisins for (int j = 0; j < nb; j++) { if (v[j]) nbvoisins++; } //création des structures en fonction du nombre de voisins pipeLecteur = new PipedReader[nbvoisins]; lecteur = new BufferedReader[nbvoisins]; ecrivain = new PipedWriter[nbvoisins]; voisinsId = new int[nbvoisins]; voisins = new int[nb]; initTubes(v); } /** * Initialisation des tubes : ouverture des extrémités en lecture/ecriture. * Création des structures de lecture dans les tubes (BufferedReaders) * @param boolean[], la liste des voisins */ public final void initTubes(boolean[] v) { int i = 0; for (int j = 0; j < nbSommet; j++) { if (v[j]) { pipeLecteur[i] = new PipedReader(); ecrivain[i] = new PipedWriter(); lecteur[i] = new BufferedReader(pipeLecteur[i]); voisins[j] = i; voisinsId[i] = j; i++; } else { voisins[j] = -1; } } } /** *Envoi d'un message sur le canal i. *@param int, le numéro du canal *@param String, le message à envoyer *@throws IOException */ public final void ecrit(int i, String s) throws IOException { //System.out.println(id + " ecrit (" + s + ") à " + voisinsId[i]); //Nombre total de messages envoyés nbMess++; //Nombre de messages pour la coloration if ((s.indexOf("Couleur") != -1) || (s.indexOf("Ok") != -1) || (s.indexOf("Erreur") != -1) || (s.indexOf("Coloration") != -1)) nbMessCouleur++; //Envoi du message ecrivain[i].write(s + '\n'); } /** * Lecture du message reçu *@param int, le numéro du canal *@return String, le message lu *@throws IOException */ public final String lit(int i) throws IOException { return lecteur[i].readLine(); } /** * Arrêt du processus */ public final void cancel() { encours = false; for (int i = 0; i < nbvoisins; i++) { try { pipeLecteur[i] = new PipedReader(); ecrivain[i] = new PipedWriter(); } catch (Exception e) { } } } /** * Etat du sommet */ public void etat() { println(id + " | " + nbvoisins + " voisins"); } /** *Méthode appelée au lancement de la méthode Start (méthode Thread) */ public final void run() { try { candidature(-1, -1); } catch (Exception theException) { } while (encours) { // ecouter(); try { for (int i = 0; i < nbvoisins; i++) { if (lecteur[i].ready()) { //Il y a quelque chose à lire dans le buffer interprete(lit(i), i); } yield(); } } catch (Exception theException) { } } try { sleep(1000); yield(); } catch (Exception theException) { } System.out.println(id + " déconnecte"); } /** * Fonction d'affichage */ public final void println(String s) { //System.out.println(s); if (sortie == null) { visu.setText(visu.getText() + "\n" + s); } else { sortie.println(s); } } /** * Methode abstraite */ public abstract void candidature(int init, int couleurReçue) throws IOException; /** * Methode abstraite */ public abstract void interprete(String s, int i) throws IOException; }