/* * Créé le 17 août 2004 * */ package traitement.section; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.util.Vector; import fichier.ContenuFichierIncompatibleException; import fichier.TypeFichierIncompatibleException; import fichier.VersionFichierIncompatibleException; import fichier.flux.RageInputStream; import principal.Commun; import principal.copiercoller.InterfaceCopiable; import principal.copiercoller.Tampon; import information.DomaineIncompatibleException; import information.InformationEvent; import information.InformationIncompleteException; import information.InformationListener; import information.InterfaceInformation; import information.domaine.InterfaceContientDomaine; import information.domaine.InterfaceDomaine; import information.magnitude.InterfaceContientMagnitude; import information.magnitude.Magnitude; import information.magnitude.VectorMagnitude; import information.reference.InterfaceChampCategoriel; import information.type.InterfaceContientType; import information.type.Type; import information.type.VectorType; import resultat.vue.VueMagnitude; import resultat.vue.VueType; import traitement.TraitementAdapter; import traitement.TraitementEvent; import traitement.TraitementIncompletException; import traitement.TraitementListener; import traitement.modele.Modele; import traitement.noeud.fonctionnel.AbstractNoeudFonctionnelPlein; /** * base des constituants des Noeuds. * Ce type de Section est utilisé pour gérer les parties d'activation d'un NoeudFonctionnelEndogene ou * les parties d'émission d'un NoeudFonctionnelEndogene ou d'un NoeudFonctionnelExogene. * Une AbstractSectionInformation possède son propre Domaine, et des historiques de Magnitudes et de Types * sous la forme d'un VectorMagnitude et d'un VectorType. * A noter que la gestion de l'apprentissage et des TPT se fait via une SectionApprentissage. * * @author Vincent Labatut * @version 1 * @see traitement.noeud.fonctionnel.NoeudFonctionnelEndogene * @see traitement.noeud.fonctionnel.NoeudFonctionnelExogene * @see traitement.section.SectionApprentissage */ public abstract class AbstractSectionInformation extends TraitementAdapter implements InterfaceSection, InterfaceContientMagnitude, InterfaceContientType, InterfaceContientDomaine, InformationListener, TraitementListener { /** * Domaine de cette AbstractSectionInformation. */ protected InterfaceDomaine domaine; /** * Historique des Magnitudes. */ protected VectorMagnitude vectorMagnitude; /** * Historique des Types. */ protected VectorType vectorType; /** * InterfaceNoeudFonctionnel parent de cette AbstractSectionInformation. */ protected AbstractNoeudFonctionnelPlein parent; /** * Liste des TraitementListeners qui écoutent cette AbstractSectionInformation. */ protected Vector vectorTraitementListener; /** * Répertoire contenant les résultats de la simulation. */ protected File repertoireSimulation; /** * la Vue associée aux Types de cette Section. */ protected VueType vueType; /** * la Vue associée aux Magnitudes de cette Section. */ protected VueMagnitude vueMagnitude; /** * indique si cet objet a été modifé depuis sa dernière sauvegarde. */ protected boolean modifie; // ---------------------------------------- // HistoriqueMagnitude // ---------------------------------------- /* * */ public Magnitude getMagnitude(int instant) { if (instant<0) return vectorMagnitude.getMagnitude(0); else return vectorMagnitude.getMagnitude(instant); } /** * renvoie la Magnitude initiale. * * @return la Magnitude initiale. */ public Magnitude getMagnitudeInitiale() { return getMagnitude(0); } /** * rajoute une Magnitude dans l'historique. * Emission de TraitementEvents de raffraichissement et de complétude. * * @param magnitude la Magnitude à rajouter. */ public void addMagnitude(Magnitude magnitude) { vectorMagnitude.addMagnitude(magnitude); magnitude.setParent(this); setModifie(); fireTraitementRaffr(new TraitementEvent(this)); } /** * remplace, dans l'historique, la Magnitude * de l'instant spécifié, par la Magnitude passée en paramètre. * Si aucune Magnitude n'existe à l'instant spécifié, la Magnitude est simplement rajoutée. * Emission de TraitementEvents de raffraichissement et de complétude. * * @param instant de la substitution. * @param magnitude la Magnitude à substituer. */ public void setMagnitude(int instant, Magnitude magnitude) { if (vectorMagnitude.size()>instant) { vectorMagnitude.getMagnitude(instant).remove(); vectorMagnitude.setMagnitude(instant,magnitude); magnitude.setParent(this); } else addMagnitude(magnitude); setModifie(); fireTraitementRaffr(new TraitementEvent(this)); } /** * remplace la Magnitude initiale * par la Magnitude passée en paramètre. * * @param magnitude la Magnitude à substituer. */ public void setMagnitudeInitiale(Magnitude magnitude) { getMagnitudeInitiale().removeInformationListener(this); setMagnitude(0,magnitude); magnitude.addInformationListener(this); } // ---------------------------------------- // HistoriqueType // ---------------------------------------- /* * */ public Type getType(int instant) { if (instant<0) return vectorType.getType(0); else return vectorType.getType(instant); } /** * renvoie le Type initial. * * @return le Type initial. */ public Type getTypeInitial() { return getType(0); } /** * rajoute un Type dans l'historique. * Emission de TraitementEvents de raffraichissement et de complétude. * * @param type le Type à rajouter. * @throws DomaineIncompatibleException si le Domaine du Type est * incompatible avec celui de cette AbstractSectionInformation. */ public void addType(Type type) throws DomaineIncompatibleException { if (domaine.estCompatibleDomaine(type.getDomaine())) { vectorType.addType(type); type.setParent(this); } else throw new DomaineIncompatibleException(getIdentification()+":"+type.getIdentification()); setModifie(); fireTraitementRaffr(new TraitementEvent(this)); } /** * remplace, dans l'historique, le Type * de l'instant spécifié, par le Type passée en paramètre. * Si aucun Type n'existe à l'instant spécifié, le Type est simplement rajouté. * Emission de TraitementEvents de raffraichissement et de complétude. * * @param instant de la substitution. * @param type le Type à substituer. * @throws DomaineIncompatibleException si le Domaine du Type est * incompatible avec celui de cette AbstractSectionInformation. */ public void setType(int instant, Type type) throws DomaineIncompatibleException { if (domaine.estCompatibleDomaine(type.getDomaine())) if (vectorType.size()>instant) if (domaine.estCompatibleDomaine(type.getDomaine())) { getType(instant).remove(); vectorType.setType(instant,type); type.setParent(this); } else addType(type); else throw new DomaineIncompatibleException(getIdentification()+":"+type.getIdentification()); setModifie(); fireTraitementRaffr(new TraitementEvent(this)); } /** * remplace le Type initial * par le Type passé en paramètre. * * @param type le Type à substituer. * @throws DomaineIncompatibleException si le Domaine du Type est * incompatible avec celui de cette AbstractSectionInformation. */ public void setTypeInitial(Type type) throws DomaineIncompatibleException { getTypeInitial().removeInformationListener(this); setType(0,type); type.addInformationListener(this); } // ---------------------------------------- // Domaine // ---------------------------------------- /* * */ public InterfaceDomaine getDomaine() { return domaine; } /** * remplace le Domaine de cette AbstractSectionInformation par celui passé * en paramètre. L'ancien Domaine apparenant à cette AbstractSectionInformation, * il n'est pas nécessaire de le remplacer véritablement : ce sont ses ChampCategoriels * qui sont échangés, et les listeners du Domaine s'adaptent tous seuls. * En conséquence, le nouveau Domaine est une copie de celui passé en paramètre. * Un TraitementEvent de raffraichissement est indirectemet émis, puisque cette * AbstractSectionInformation écoute son Domaine, qui va lui-même émettre un évènement. * * @param d le nouveau Domaine de cette AbstractSectionInformation. */ public void setDomaine(InterfaceDomaine d) { // pour chaque CC du nouveau Domaine for (int i=0;id.size()) removeChampCategoriel(domaine.size()-1); } // ---------------------------------------- // ChampCategoriel // ---------------------------------------- /** * ajoute un ChampCategoriel dans le Domaine de cette AbstractSectionInformation. * * @param cc ChampCategoriel à ajouter au Domaine. */ public void addChampCategoriel(InterfaceChampCategoriel cc) { domaine.addChampCategoriel(cc); } /** * insère un ChampCategoriel dans le Domaine de cette AbstractSectionInformation, au rang spécifié. * * @param rang rang où insérer le ChampCategoriel. * @param cc ChampCategoriel à ajouter au Domaine. */ public void addChampCategoriel(int rang, InterfaceChampCategoriel cc) { domaine.addChampCategoriel(rang, cc); } /** * remplace, dans le Domaine de cette AbstractSectionInformation, le ChampCategoriel * de rang 'rang' par le ChampCategoriel passé en paramètre. * * @param rang rang ChampCategoriel à remplacer. * @param cc ChampCategoriel à substituer dans le Domaine. */ public void setChampCategoriel(int rang, InterfaceChampCategoriel cc) { domaine.setChampCategoriel(rang, cc); } /** * supprime un ChampCategoriel dans le Domaine de cette AbstractSectionInformation, au rang spécifié. * * @param rang rang du ChampCategoriel à supprimer. */ public void removeChampCategoriel(int rang) { domaine.removeChampCategoriel(rang); } // ---------------------------------------- // Parent // ---------------------------------------- /** * renvoie l'InterfaceNoeudFonctionnel parent de cette AbstractSectionInformation. * * @return l'InterfaceNoeudFonctionnel parent. */ public AbstractNoeudFonctionnelPlein getParent() { return parent; } /** * modifie l'InterfaceNoeudFonctionnel parent de cette AbstractSectionInformation. * Ceci peut provenir d'un changement de Modele, donc cette action est * propagée aux fils de cette AbstractSectionInformation. * * @param n le nouvel InterfaceNoeudFonctionnel parent de cette AbstractSectionInformation. */ public void setParent(AbstractNoeudFonctionnelPlein n) { parent = n; // domaine.setParent(this); // for (int i=0;i0) throw new VersionFichierIncompatibleException(fichier.getPath()); // on récupère le type de fichier String typeFichier = (String)inputStream.readObject(); if (!typeFichier.equals(Commun.FICHIER_CODE_RESULTAT)) throw new TypeFichierIncompatibleException(fichier.getPath()); // le Domaine d'activation InterfaceDomaine dom; dom = inputStream.readDomaineComplexe(this); if (!dom.egaleDomaine(domaine)) throw new ContenuFichierIncompatibleException(fichier.getPath()); // on n'a plus besoin de ce Domaine, il ne sert que pour le test. dom.remove(); // la taille du Vector à écrire int taille = ((Integer)inputStream.readObject()).intValue(); // et enfin chaque information for (int i=1;i0) throw new VersionFichierIncompatibleException(fichier.getPath()); // on récupère le type de fichier typeFichier = (String)inputStream.readObject(); if (!typeFichier.equals(Commun.FICHIER_CODE_RESULTAT)) throw new TypeFichierIncompatibleException(fichier.getPath()); // la taille du Vector à écrire taille = ((Integer)inputStream.readObject()).intValue(); // et enfin chaque information for (int i=1;i1) { vectorType.getType(1).remove(); vectorType.removeType(1); } while (vectorMagnitude.size()>1) { vectorMagnitude.getMagnitude(1).remove(); vectorMagnitude.removeMagnitude(1); } } // ---------------------------------------- // Modification // ---------------------------------------- /** * met à true l'indicateur de modification. * */ public void setModifie() { modifie = true; } /** * indique si cet Objet a besoin ou pas d'être sauvegardé * (dans le sens enregistré dans un fichier). * * @return vrai si cet Objet a été modifié depuis le dernier enregistrement. * */ public boolean estModifie() { return modifie; } /** * renvoie l'indicateur indiquant si un Noeud nécessaire * mais absent doit être créé. * * @return l'indicateur. */ public boolean getCreerNoeudSiAbsent() { return getParent().getCreerNoeudSiAbsent(); } }