https://hal.archives-ouvertes.fr/hal-02177293
Raw File
Tip revision: a5c3a632ff52caf942ac0457ce1ec733926a867b authored by Software Heritage on 01 January 2004, 00:00:00 UTC
hal: Deposit 315 in collection hal
Tip revision: a5c3a63
EditeurObservation.java
/*
 * Créé le 25 juil. 2004
 *
 */
package traitement.section;

import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Vector;

import traitement.InterfaceTraitement;
import traitement.TraitementEvent;
import traitement.TraitementIncompletException;
import traitement.TraitementListener;
import traitement.modele.Modele;
import information.InformationAdapter;
import information.InformationEvent;
import information.InformationExistanteException;
import information.InformationListener;
import information.magnitude.InterfaceContientMagnitude;
import information.magnitude.Magnitude;
import information.magnitude.VectorMagnitude;
import fichier.ContenuFichierIncompatibleException;
import fichier.TypeFichierIncompatibleException;
import fichier.VersionFichierIncompatibleException;
import fichier.flux.RageInputStream;
import fichier.flux.RageOutputStream;
import gui.InterfaceAffichable;
import principal.Commun;
import principal.copiercoller.CopiableIncompatibleException;
import principal.copiercoller.HomonymeIntrouvableException;
import principal.copiercoller.InterfaceCollable;
import principal.copiercoller.InterfaceCopiable;
import principal.copiercoller.InterfaceHomonyme;
import principal.copiercoller.Tampon;

/**
 * permet d'éditer le fichier d'observation d'une SectionInformationEndogene.
 * 
 * @author	Vincent Labatut
 * @version	1
 * @see		traitement.section.AbstractSectionInformationEndogene
  */
public class EditeurObservation extends InformationAdapter implements InterfaceTraitement, InterfaceContientMagnitude, InformationListener, InterfaceAffichable, InterfaceCollable
{	/**
	 * Fichier d'observation.
	  */
	private File observationFichier;
	/**
	 * Flux du fichier d'observation.
	  */
	private RageInputStream observationInput;	
	/**
	 * Valeur observée courante
	  */
	private Magnitude observationValeur;
	/**
	 * Index de la valeur observée courante.
	  */
	private int observationIndex;
	/**
	 * Indicateur d'observabilité.
	  */
	private boolean observationFlag;
	/**
	* Liste des Magnitudes observées, sous forme d'un VectorMagnitude.
	 */
	private VectorMagnitude vDonnee;
	/**
	* Liste des instants observés, sous forme d'un Vector d'Integer.
	 */
	private Vector vInstant;
	/**
	* Liste des TraitementListeners ŕ l'écoute de cet EditeurObservation.
	 */
	private Vector vectorTraitementListener;
	/**
	* AbstractSectionInformationEndogene parent de cet EditeurObservation.
	 */
	private AbstractSectionInformationEndogene parent;
	/**
	* Indicateur permettant de savoir si un fichier a été 
	* affecté ŕ l'Editeur.
	 */
	private boolean observationFichierAffecte;
	/**
	 * indique si cet objet a été modifé depuis sa derničre sauvegarde.
	  */
	private boolean modifie;
	
//	----------------------------------------	
//	Constructeurs
//	----------------------------------------
	/**
	 * Constructeur pour créer un EditeurObservation de parent la SectionInformationEndogene
	 * passée en paramčtre.
	 * 
	 * @param	p	parent de cet EditeurObservation.
	 * 
	  */
	public EditeurObservation(AbstractSectionInformationEndogene p) 
	{	
    	parent = p;
		//
		vectorTraitementListener = new Vector();
		//
		File repertoire = parent.getRepertoireObservation();
		if (repertoire != null)
			observationFichier = new File(parent.getRepertoireObservation().getPath()
				+ Commun.EXT_OBSERVATION);
		else
			observationFichier = null;
		//
		observationIndex = 0;
		observationFlag = false;
		observationFichierAffecte = false;
		//
		vDonnee = new VectorMagnitude();
		vInstant = new Vector();
		setModifie();
	}

//	----------------------------------------	
//	Fichier
//	----------------------------------------
	/**
	 * permet de savoir si la Magnitude est observable.
	 * Si c'est le cas, il faut lui associer un fichier contenant les observations.
	 * 
	 * @return	vrai si la Magnitude est observable, faux sinon.
	  */
	public boolean estObservable()
	{	return observationFlag;
	}
	/**
	 * permet de basculer la Magnitude en mode observable ou non observable.
	 * Emission de TraitementEvents de raffraichissement et de complétude.
	 * 
	 * @param	flag	si le flag est vrai, la Magnitude devient observable.
	 * 					Sinon, elle devient non-observable.
	  */
	public void setObservable(boolean flag)
	{	observationFlag = flag;
		setModifie();
    	fireTraitementRaffr(new TraitementEvent(this));
	}
	/**
	 * renvoie le fichier d'observation de la Magnitude.
	 * Si elle n'est pas observable, la méthode renvoie null.
	 * 
	 * @return	le fichier d'observation de la Magnitude.
	  */
	public File getObservationFichier()
	{	return observationFichier;
	}
	/**
	 * remplace l'ancien fichier d'observation de la Magnitude par celui passé en paramčtre.
	 * On ouvre le fichier et le copie en mémoire, puis on le referme.
	 * Emission de TraitementEvents de raffraichissement et de complétude.
	 * 
	 * @param	f	le nouvau fichier d'observation de la Magnitude d'activation.
	 * @throws	IOException si une erreur se produit lors de la vérification du fichier.
	 * @throws	ClassNotFoundException une erreur se produit lors de la vérification du fichier.
	 * @throws	VersionFichierIncompatibleException le fichier n'est pas d'une version compatible.
	 * @throws	TypeFichierIncompatibleException le fichier n'est pas un fichier d'observation.
	 * @throws	ContenuFichierIncompatibleException  le contenu du fichier est erroné.
	  */
	public void setObservationFichier(File f) throws IOException, ContenuFichierIncompatibleException, VersionFichierIncompatibleException, TypeFichierIncompatibleException
	{	// on vire l'ancien fichier et l'ancien contenu de cet Editeur
		removeObservationFichier();
		// si le nouveau fichier est vide
		if (f == null)
			// on met en place le nouveau fichier
			observationFichierAffecte = false;
		// s'il n'est pas vide
		else
		{	FileInputStream in = null;
			try
			{	// on le teste de façon moins stricte que dans test
				// et on le remplit
				// ouvrir et vérifier le fichier
				// on ouvre le flux
				in = new FileInputStream(f);			
				RageInputStream input = new RageInputStream(in,getModele().getCreerReferenceSiAbsente(),true);
			
				// on récupčre la version du fichier
				Float version = (Float)input.readObject();
				if (version.compareTo(Commun.VERSION)>0)
					throw new VersionFichierIncompatibleException(f.getPath());
			
				// on récupčre le type de fichier
				String typeFichier = (String)input.readObject();
				if (!typeFichier.equals(Commun.FICHIER_CODE_OBSERVATION))
					throw new TypeFichierIncompatibleException(f.getPath());
			
				// on récupčre chaque index et magnitude
				int index = -1;
				try
				{	while (true)
					{	int tempIndex = ((Integer)input.readObject()).intValue();
						vInstant.add(new Integer(tempIndex));
						Magnitude tempMag = input.readMagnitude(this);
						tempMag.setParent(this);
						vDonnee.addMagnitude(tempMag);
						tempMag.addInformationListener(this);
						if (index>= tempIndex)
							throw new ContenuFichierIncompatibleException(f.getPath());
						index = tempIndex;
					}
				}
				catch (EOFException e)
				{	// ok
				}
				// on ferme
				in.close();
			}
			catch (FileNotFoundException e)
			{	if (in != null)
					in.close();
				setObservationFichier(null);	
				throw e;
			}
			catch (IOException e)
			{	if (in != null)
					in.close();
				setObservationFichier(null);	
				throw e;
			}
			catch (ClassNotFoundException e)
			{	if (in != null)
					in.close();
				setObservationFichier(null);	
				throw new ContenuFichierIncompatibleException(f.getPath());
			}
			catch (VersionFichierIncompatibleException e)
			{	if (in != null)
					in.close();
				setObservationFichier(null);	
				throw e;
			}
			catch (TypeFichierIncompatibleException e) 
			{	if (in != null)
					in.close();
				setObservationFichier(null);	
				throw e;
			}
			catch (ContenuFichierIncompatibleException e) 
			{	if (in != null)
					in.close();
				setObservationFichier(null);	
				throw e;
			}

			// test ok, on copie le fichier au bon endroit
			// sauf si f==observationFichier
			if (!f.getPath().equals(observationFichier.getPath()))
			{	// si le fichier existait déjŕ, on le copie en .back
				if (observationFichier.exists())
					Commun.copierFichier(observationFichier,new File(observationFichier.getPath()+Commun.EXT_BACK));
				// copie
				try
				{	Commun.copierFichier(f,observationFichier);
				}
				catch (IOException e1)
				{	setObservationFichier(null);	
					throw e1;
				}
			}
			//
			observationFichierAffecte = true;
		}
		setModifie();
	    fireTraitementRaffr(new TraitementEvent(this));
	}
	/**
	 * réinitialise le fichier d'observation ŕ null.
	 * Les Magnitudes d'observation contenues dans cet Editeur sont supprimées.
	 * 
	  */
	public void removeObservationFichier()
	{	while (vDonnee.size()!=0)
			removeObservation(0);
		observationFichierAffecte = false;
	}
	/**
	 * teste si le fichier passé en paramčtre est valide 
	 * pour devenir le fichier d'observation.
	 * Structure d'un fichier d'observation :
	 *	- String : version
	 *	- String : type de fichier
	 *	- Integer : instant de l'observation
	 *	- Magnitude : (magnitude d'activation ou d'émission) n fois
	 *
	 * @param	f	le fichier d'observation ŕ tester.
	 * @return : la taille du fichier.
	 * @throws	IOException si une erreur se produit lors de la vérification du fichier.
	 * @throws	ClassNotFoundException une erreur se produit lors de la vérification du fichier.
	 * @throws	VersionFichierIncompatibleException le fichier n'est pas d'une version compatible.
	 * @throws	TypeFichierIncompatibleException le fichier n'est pas un fichier d'observation.
	 * @throws	ContenuFichierIncompatibleException  le contenu du fichier est erroné.
	  */
	public int testerObservationFichier(File f) throws IOException, ClassNotFoundException, VersionFichierIncompatibleException, TypeFichierIncompatibleException, ContenuFichierIncompatibleException
	{	if (f == null)
			throw new FileNotFoundException();
		// ouvrir et vérifier le fichier		
		// on ouvre le flux
		FileInputStream in = new FileInputStream(f);			
		RageInputStream input = new RageInputStream(in,getModele().getCreerReferenceSiAbsente(),true);
			
		// on récupčre la version du fichier
		Float version = (Float)input.readObject();
		if (version.compareTo(Commun.VERSION)>0)
			throw new VersionFichierIncompatibleException(f.getPath());
			
		// on récupčre le type de fichier
		String typeFichier = (String)input.readObject();
		if (!typeFichier.equals(Commun.FICHIER_CODE_OBSERVATION))
			throw new TypeFichierIncompatibleException(f.getPath());
		
		// on teste chaque Magnitude et on en profite pour mettre la taille du fichier ŕ jour
		int resultat = -1;
		int index = -1;
		try
		{	while (true)
			{	int tempIndex = ((Integer)input.readObject()).intValue();
				if (index>= tempIndex)
					throw new ContenuFichierIncompatibleException(f.getPath());
				Magnitude tempMag = input.readMagnitude(this);
				if (!tempMag.estComplet())
					throw new ContenuFichierIncompatibleException(f.getPath());
				// on n'a plus besoin de cette Magnitude
				tempMag.remove();
				index = tempIndex;
				resultat ++;
			}
		}
		catch (EOFException e)
		{	// ok
		}
		// on referme
		in.close();
		// et tout finit bien
		return resultat;
	}
	/**
	 * crée un nouveau fichier d'observation de la Magnitude.
	 * Ce fichier est vide d'observations.
	 * 
	 * @throws	IOException si une erreur se produit lors de la vérification du fichier.
	 * @throws	ClassNotFoundException une erreur se produit lors de la vérification du fichier.
	 * @throws	VersionFichierIncompatibleException le fichier n'est pas d'une version compatible.
	 * @throws	TypeFichierIncompatibleException le fichier n'est pas un fichier d'observation.
	 * @throws	ContenuFichierIncompatibleException  le contenu du fichier est erroné.
	  */
	public void newObservationFichier() throws IOException
	{	//création éventuelle du répertoire
		//creerRepertoire();
observationFichier.getParentFile().mkdirs();
			
		// si le fichier existait déjŕ, on le copie en .back
		if (observationFichier.exists())
			try
			{	Commun.copierFichier(observationFichier,new File(observationFichier.getPath()+Commun.EXT_BACK));
			}
			catch (IOException e)
			{	//e.printStackTrace();
				//si ça foire tant pis
			}
		
		// on ouvre le flux
		FileOutputStream out = null;
		try
		{	out = new FileOutputStream(observationFichier);
			RageOutputStream output = new RageOutputStream(out);
			
			// on écrit la version du fichier
			output.writeObject(Commun.VERSION);
			// on écrit le type de fichier
			output.writeObject(Commun.FICHIER_CODE_OBSERVATION);
			// on écrit une Magnitude
			//output.writeObject(new Integer(0));
			//output.writeMagnitude(new Magnitude(this));
			// on referme
			out.close();
		}
		catch (IOException e)
		{	if (out!=null)
				out.close();
			throw e;
		}

		// on affecte le fichier ŕ this
		observationFichierAffecte = true;
		setModifie();
	    fireTraitementRaffr(new TraitementEvent(this));
	}
	/**
	 * permet de savoir s'il existe une observation pour la Magnitude
	 * ŕ un instant donné. En effet, l'observation n'est pas systématique ŕ chaque
	 * instant, il est possible de se passer d'observations ŕ certains instants.
	 * 
	 * @param	instant	instant pour lequel on veut savoir s'il existe une observation.
	 * @return	vrai s'il existe une observation ŕ cet instant, faux sinon.
	 * @throws	IOException si une erreur se produit lors de la vérification du fichier.
	 * @throws	ClassNotFoundException une erreur se produit lors de la vérification du fichier.
	  */
	public boolean estObservable(int instant) throws IOException, ClassNotFoundException
	{	boolean resultat;
		if (observationIndex < instant)
			lireObservation();
		if (observationIndex > instant)
			resultat = false;
		else
			resultat = true;
		return resultat;
	}
	/**
	 * renvoie l'observation de la Magnitude ŕ un instant donné.
	 * 
	 * @param	instant	instant pour lequel on veut obtenir l'observation.
	 * @return	Magnitude observée ŕ l'instant passé en paramčtre.
	 * @throws	IOException si une erreur se produit lors de la vérification du fichier.
	 * @throws	ClassNotFoundException une erreur se produit lors de la vérification du fichier.
	  */
	public Magnitude getObservationValeur(int instant) throws IOException, ClassNotFoundException
	{	Magnitude resultat;
		resultat = new Magnitude(this);
		if (observationIndex < instant)
			lireObservation();
		if (observationIndex == instant)
			resultat = observationValeur;
		return resultat;					
	}
	/**
	 * lit l'observation de la Magnitude d'emission de l'instant suivant
	 * (et le numéro de l'instant lui męme),
	 * dans le fichier d'observation.
	 * 
	 * @throws	IOException si une erreur se produit lors de la vérification du fichier.
	 * @throws	ClassNotFoundException une erreur se produit lors de la vérification du fichier.
	  */
	public void lireObservation() throws IOException, ClassNotFoundException
	{	observationIndex = ((Integer)observationInput.readObject()).intValue();  
		observationValeur = observationInput.readMagnitude(this);
	}
	/**
	 * enregistre le contenu de ce Editeur dans 
	 * le fichier.
	 * @throws	IOException	si une erreur se produit durant l'écriture.
	 * 
	  */
	public void enregistrerObservationFichier() throws IOException
	{	//création éventuelle du répertoire
		//creerRepertoire();
observationFichier.getParentFile().mkdirs();
			
		// on ouvre le flux
		FileOutputStream out = null;
		try
		{	out = new FileOutputStream(observationFichier);
			RageOutputStream output = new RageOutputStream(out);
			
			// on écrit la version du fichier
			output.writeObject(Commun.VERSION); 
		
			// on écrit le type de fichier
			output.writeObject(Commun.FICHIER_CODE_OBSERVATION);
		
			// on écrit les Magnitudes
			for (int i=0;i<size();i++)
			{	output.writeObject(vInstant.get(i)); 
				output.writeMagnitude(vDonnee.getMagnitude(i));
			}
		
			// on referme
			out.close();
		}
		catch (IOException e)
		{	if (out != null)
				out.close();
			throw e;
		}
		setNonModifie();
	}
	 /**
	 * enregistre le contenu de ce Editeur dans 
	 * un fichier différent du fichier qui lui est affecté.
	 * Ce fichier est passé en paramčtre.
	 * 
	 * @param	fichier	fichier dans lequel enregistrer le contenu de cet Editeur.
	 * @throws	IOException	si une erreur se produit durant l'écriture.
	 * 
	  */
	public void exporterObservationFichier(File fichier) throws IOException
	{	// on s'assure de la présence de l'extension
		if (!fichier.getPath().endsWith(Commun.EXT_OBSERVATION))
			fichier = new File(fichier.getPath()+Commun.EXT_OBSERVATION);
	
		// on ouvre le flux
		FileOutputStream out = null;
		try
		{	out = new FileOutputStream(fichier);
			RageOutputStream output = new RageOutputStream(out);
			
			// on écrit la version du fichier
			output.writeObject(Commun.VERSION); 
		
			// on écrit le type de fichier
			output.writeObject(Commun.FICHIER_CODE_OBSERVATION);
		
			// on écrit les Magnitudes
			for (int i=0;i<size();i++)
			{	output.writeObject(vInstant.get(i)); 
				output.writeMagnitude(vDonnee.getMagnitude(i));
			}
		
			// on referme
			out.close();
		}
		catch (IOException e)
		{	if (out!=null)
				out.close();
			throw e;
		}
	}

//	----------------------------------------	
//	Observations
//	----------------------------------------
	/**
	 * renvoie la Magnitude observée ŕ la position 
	 * (et non pas l'instant) 'index'.
	 *
	 * @param	index	position de la Magnitude désirée.
	 * @return	la Magnitude observée numéro 'index'.
	  */
	public Magnitude getObservation(int index)
	{	return vDonnee.getMagnitude(index);
	}
	/**
	 * renvoie l'instant ŕ la position 
	 * (et non pas l'instant) 'index'.
	 * 
	 * @param	index	position de l'instant désiré. 
	 * @return	l'instant numéro 'index'.
	  */
	public int getInstant(int index)
	{	return ((Integer)vInstant.get(index)).intValue();
	}
	/**
	 * ajoute une Magnitude ŕ la liste des observations,
	 * ŕ l'instant (et non pas la position) spécifié en paramčtre.
	 * L'instant est ajouté dans la liste des instants.
	 * 
	 * @param	mag		la Magnitude observée ŕ rajouter.
	 * @param	instant	l'instant associé ŕ la nouvelle Magnitude observée.
	 * @throws 	InformationExistanteException si une Magnitude observée existe dékŕ ŕ cet instant.
	  */
	public void addObservation(Magnitude mag, int instant) throws InformationExistanteException
	{	int i = 0;
		// on cherche ou insérer la nouvelle observation
		while (i<size() && getInstant(i)<instant)
			i++;
		// si déjŕ une observation ŕ cet instant
		if (i!=size() && getInstant(i)==instant)
			throw new InformationExistanteException(getIdentification()+":"+instant);
		// sinon on insčre
		vDonnee.addMagnitude(i,mag);
		mag.setParent(this);
		mag.addInformationListener(this);
		vInstant.add(i,new Integer(instant));
		//
		setModifie();
	    fireTraitementEltModif(new TraitementEvent(this,TraitementEvent.ELT_INSER,i));
	}
	/**
	 * ajoute une Magnitude ŕ la liste des observations,
	 * ŕ la fin.
	 * L'instant est ajouté dans la liste des instants.
	 * 
	 * @param	mag		la Magnitude observée ŕ rajouter.
	  */
	public void addObservation(Magnitude mag)
	{	try
		{	addObservation(mag,getInstant(size()-1)+1);
		}
		catch (InformationExistanteException e)
		{	e.printStackTrace();
		}
	}
	/**
	 * crée une nouvelle Magnitude vide, et l'ajoute 
	 * ŕ la liste des observations, ŕ l'instant spécifié
	 * (et non pas la position).
	 * L'instant est ajouté dans la liste des instants.
	 * 
	 * @param	instant	instant correspondant ŕ la nouvelle Magnitude observée.
	  */
	public void newObservation(int instant)
	{	try
		{	addObservation(new Magnitude(this),instant);
		}
		catch (InformationExistanteException e)
		{	e.printStackTrace();
		}
	}
	/**
	 * crée une nouvelle Magnitude vide, et l'ajoute 
	 * ŕ la fin de la liste des observations,
	 * L'instant est ajouté dans la liste des instants.
	 * 
	  */
	public void newObservation()
	{	int instant;
	
	    if (size()==0)
	    	instant = 1;
	    else
	        instant = getInstant(size()-1)+1;
	    newObservation(instant);
	}
	/**
	 * supprime une Magnitude observée de la liste des observations,
	 * ŕ la position spécifiée (et non pas l'instant).
	 * L'instant correspondant est supprimé de la liste des instants.
	 * 
	 * @param	index	position de la Magnitude observée ŕ supprimer.
	  */
	public void removeObservation(int index)
	{	Magnitude temp = vDonnee.getMagnitude(index);
		temp.removeInformationListener(this);
		vDonnee.removeMagnitude(index);
		vInstant.remove(index);
		temp.remove();
		setModifie();
	    fireTraitementEltModif(new TraitementEvent(this,TraitementEvent.ELT_SUPPR,index));
	}
	/**
	 * remplace l'instant de la Magnitude observée
	 * située ŕ la position 'index' par la valeur 'instant', 
	 * passée en second paramčtre.
	 * Cela peut nécessiter de déplacer la Magnitude dans la liste
	 * des observation.
	 * 
	 * @param	index	position de la Magnitude observée dont on veut modifier l'instant associé.
	 * @param	instant	nouvel instant associé ŕ la Magnitude observée.
	 * @throws	InformationExistanteException si une Magnitude observée existe déjŕ pour l'instant 'instant'.
	  */
	public void setInstant(int index, int instant) throws InformationExistanteException
	{	int vieux = getInstant(index);
		Magnitude valeur = getObservation(index).cloner();
		if (instant != vieux)
		{	if (containsInstant(instant))
				throw new InformationExistanteException(getIdentification()+":"+instant);
			vInstant.remove(index);
			vDonnee.getMagnitude(index).removeInformationListener(this);
			vDonnee.getMagnitude(index).remove();
			vDonnee.removeMagnitude(index);
			int i = 0;
			boolean trouve = false;
			while (i<size() && !trouve)
			{	if (getInstant(i)<instant)
					i++;
				else
					trouve = true;
			}
			vInstant.add(i,new Integer(instant));
			vDonnee.addMagnitude(i,valeur);
			valeur.addInformationListener(this);
			setModifie();
		    fireTraitementEltModif(new TraitementEvent(this,TraitementEvent.ELT_REMPL,index));
		}
	}
	/**
	 * renvoie le nombre de Magnitudes observées.
	 * 
	 * @return	la nombre de Magnitudes observées.
	  */
	public int size()
	{	return vDonnee.size();
	}
	/**
	 * teste s'il existe une Magnitude observée associée ŕ 
	 * l'instant passé en paramčtre.
	 * 
	 * @return	vrai s'il existe une telle Magnitude, faux sinon.
	  */
	public boolean containsInstant(int instant)
	{	int i = 0;
		while (i<size() && getInstant(i)<instant)
			i++;
		// si déjŕ une observation ŕ cet instant
		return (i!=size() && getInstant(i)==instant);
	}

//	----------------------------------------	
//	This
//	----------------------------------------
	/*
	 * 
	 */
	public void remove()
	{	fireTraitementSuppr(new TraitementEvent(this));
		// on efface tous les liens
		removeObservationFichier();
		parent = null;
		vInstant = null;
		vDonnee = null;
		observationFichier = null;
		observationInput = null;	
		observationValeur = null;
		
	}

//	----------------------------------------	
//	Simulation
//	----------------------------------------
	/*
	 * 
	 */
	public boolean estComplet()
	{	boolean resultat = true;
		
		if (estObservable())
		{	
			try
			{	testerObservationFichier(observationFichier);
			}
			catch (Exception e)
			{
				resultat = false;
			}
		}
		return resultat;				
	}
	/**
	 * détermine si cette Section est complčtement définie.
	 * Elle est destinée ŕ ętre appelée par la GUI, et par conséquent 
	 * les tests effectués sont moins stricts que dans le cas de la
	 * méthode estComplet, qui est, elle, destinée ŕ prévenir la simulation
	 * de tout problčme. En particulier, ici, on ne teste pas le contenu
	 * des fichiers.
	 * 
	 * @return 	vrai si cette Section est complčtement définie.
	  */
	public boolean estCompletInterface()
	{	boolean resultat = true;

		if (estObservable())
			if (!observationFichierAffecte)
				resultat = false;
			else
			{	int i=0;
				while (resultat && i<vDonnee.size())
				{	if (getMagnitude(i).estComplet())
						i++;
					else
						resultat = false;
				}
			}
		return resultat;
	}

	/**
	 * ouvre le fichier d'observation de la Magnitude 
	 * et le prépare pour la simulation en consommant 
	 * certaines données inutiles pour la 
	 * simulation et contenues au début du fichier. 
	 * A ce stade, le fichier a été testé
	 * et est supposé ętre valide.
	 * 
	 * @throws	IOException si une erreur se produit lors de la vérification du fichier.
	 * @throws	ClassNotFoundException une erreur se produit lors de la vérification du fichier.
	  */
	public void preparerSimulation() throws IOException, ContenuFichierIncompatibleException
	{	// on supprime le contenu de cet editeur
		File fichier = observationFichier;
		removeObservationFichier();
		observationFichier = fichier;
		// puis on ouvre le fichier et on le lit en flux tendu
		FileInputStream in = null;
		try
		{	in = new FileInputStream(observationFichier);
			observationInput = new RageInputStream(in,getModele().getCreerReferenceSiAbsente(),true);
			// on se positionne au début de la série de mag
			Float version = (Float)observationInput.readObject();
			String typeFichier = (String)observationInput.readObject();
		}
		catch (FileNotFoundException e)
		{	if (in!= null)
				in.close();
			throw e;
		}
		catch (IOException e)
		{	if (in!= null)
				in.close();
			throw e;
		}
		catch (ClassNotFoundException e)
		{	if (in!= null)
				in.close();
			throw new ContenuFichierIncompatibleException(observationFichier.getPath());
		}
	}
	/**
	 * interrompt la simulation, c'est ŕ dire que les Noeuds doivent
	 * ętre réinitialisés et les fichiers ouverts doivent ętre fermés.
	 * 
	 * @throws	 IOException	si une erreur survient lors de l'accčs au fichier.
	 * @throws	 ContenuFichierIncompatibleException	si le contenu du fichier est erroné.
	 * @throws	 VersionFichierIncompatibleException	si la version de Rage qui a généré le fichier n'est pas compatible avec cette version-ci.
	 * @throws	 TypeFichierIncompatibleException	le fichier n'est pas un fichier de resultats.
	  */
	public void interrompreSimulation() throws IOException, ContenuFichierIncompatibleException, VersionFichierIncompatibleException, TypeFichierIncompatibleException
	{	observationInput.close();
		setObservationFichier(observationFichier);
	}
	/**
	 * ferme le fichier d'observation ŕ la fin de la simulation.
	 * Il est réouvert en suivant en tant qu'éditeur, au cas oů
	 * l'utilisateur continuerait l'édition en suivant de la simulation.
	 * 
	 * @throws	IOException si une erreur se produit lors de la vérification du fichier.
	  */
	public void terminerSimulation() throws IOException, ContenuFichierIncompatibleException, VersionFichierIncompatibleException, TypeFichierIncompatibleException
	{	observationInput.close();
		setObservationFichier(observationFichier);
	}

//	----------------------------------------	
//	Parent
//	----------------------------------------
	/**
	 * renvoie la AbstractSectionInformationEndogene parent de cet Editeur.
	 * 
	 * @return 	la AbstractSectionInformationEndogene parent.
	  */
	public AbstractSectionInformationEndogene getParent()
	{	return parent;
	}
	/**
	 * modifie la AbstractSectionInformationEndogene qui contient cet Editeur
	 * (i.e. son parent).
	 * Un TraitementEvent de raffraichissement est émis.
	 * 
	 * @param	p nouveau parent. 
	  */
	public void setParent(AbstractSectionInformationEndogene p) throws IOException
	{	parent = p;
		raffraichirRepertoireObservation();
		setModifie();
	    fireTraitementRaffr(new TraitementEvent(this));
	}

//	----------------------------------------	
//	Modele
//	----------------------------------------
	/*
	 * 
	 */
	public Modele getModele()
	{	return parent.getModele();
	}

//	----------------------------------------	
//	InterfaceTraitement
//	----------------------------------------
	/*
	 * 
	 */
	public void addTraitementListener(TraitementListener i)
	{	vectorTraitementListener.add(i);
	}
	/*
	 * 
	 */
	public void removeTraitementListener(TraitementListener i)
	{	vectorTraitementListener.remove(i);
	}
	/**
	 * annonce la suppression de cet EditeurObservation.
	 * Chaque TraitementListener doit se supprimer lui-męme de la liste des listeners de cet EditeurObservation.  
	 * 
	 * @param 	e	le TraitementEvent qui est émis vers les TraitementListeners. 
	  */
	private void fireTraitementSuppr(TraitementEvent e)
	{	
	    while (vectorTraitementListener.size()!=0)
			try {
				((TraitementListener) vectorTraitementListener.get(0)).traitementSuppr(e);
			} catch (TraitementIncompletException e1) {
				e1.printStackTrace();
			}
	}
	/**
	 * annonce une modification d'un des constituants de cet EditeurObservation.
	 * 
	 * @param 	e	le TraitementEvent qui est émis vers les TraitementListeners. 
	  */
	private void fireTraitementEltModif(TraitementEvent e)
	{	
	    for (int i=0;i<vectorTraitementListener.size();i++)
			try {
				((TraitementListener) vectorTraitementListener.get(i)).traitementEltModif(e);
			} catch (TraitementIncompletException e1) {
				e1.printStackTrace();
			}
	}
	/**
	 * annonce un raffraichissement de cet EditeurObservation.
	 * 
	 * @param 	e	le TraitementEvent qui est émis vers les TraitementListeners. 
	  */
	private void fireTraitementRaffr(TraitementEvent e)
	{	
	    for (int i=0;i<vectorTraitementListener.size();i++)
			try {
				((TraitementListener) vectorTraitementListener.get(i)).traitementRaffr(e);
			} catch (TraitementIncompletException e1) {
				e1.printStackTrace();
			}
	}
	/**
	 * annonce un échange.
	 * 
	 * @param 	e	l'TraitementEvent qui est émis vers les TraitementListeners. 
	  */
	private void fireTraitementRempl(TraitementEvent e)
	{	for (int i=0;i<vectorTraitementListener.size();i++)
			try
			{	((TraitementListener) vectorTraitementListener.get(i)).traitementRempl(e);
			}
			catch (TraitementIncompletException e1)
			{	e1.printStackTrace();
			}
	}
	/**
	 * annonce un masquage.
	 * 
	 * @param 	e	l'TraitementEvent qui est émis vers les TraitementListeners. 
	  */
	private void fireTraitementCache(TraitementEvent e)
	{	for (int i=0;i<vectorTraitementListener.size();i++)
			try
			{	((TraitementListener) vectorTraitementListener.get(i)).traitementCache(e);
			}
			catch (TraitementIncompletException e1)
			{	e1.printStackTrace();
			}
	}

//	----------------------------------------	
//	InformationListener
//	----------------------------------------
	/*
	 * appelée lors de la réception d'un InformationEvent de modification de constituant.
	 * cet EditeurObservation écoute ses Magnitudes observées.
	 * Méthode inutile ici.
	  */
	public void informationEltModif(InformationEvent e)
	{	setModifie();
		fireTraitementRaffr(new TraitementEvent(this));
	}
	/*
	 * appelée lors de la réception d'un InformationEvent de raffraichissement.
	 * cet EditeurObservation écoute ses Magnitudes observées.
	 * On lčve un TraitementEvent de raffraichissement
	  */
	public void informationRaffr(InformationEvent e)
	{	if (e.getSource().estModifie())
		{    setModifie();
			fireTraitementRaffr(new TraitementEvent(this));
		}
	}
	/*
	 * appelée lors de la réception d'un InformationEvent de changement de Modele.
	 * cet EditeurObservation écoute ses Magnitudes observées.
	 * Tous les liens vers la Magnitude, y compris l'instant concernés,
	 * sont supprimés.
	  */
	public void informationChangementModele(InformationEvent e)
	{	Magnitude temp = (Magnitude)e.getSource();
		if (temp.getModele() != getModele())
		{	temp.removeInformationListener(this); 
			vInstant.remove(vDonnee.indexOfObjet(temp));
			vDonnee.removeMagnitude(temp);

		}	
	}
		
//	----------------------------------------	
//	InterfaceContientMagnitude
//	----------------------------------------
	/*
	 * 
	 */
	public Magnitude getMagnitude(int index)
	{	return vDonnee.getMagnitude(index);
	}
	/*
	 * 
	 */
	public int indexOfMagnitude(Magnitude magnitude)
	{	return vDonnee.indexOfObjet(magnitude);
	}

//	----------------------------------------	
//	InterfaceAffichable
//	----------------------------------------
	/*
	 * 
	 */
	public void remplacer(InterfaceAffichable d)
	{	fireTraitementRempl(new TraitementEvent(this,(EditeurObservation)d));
	}
	/*
	 * 
	 */
	public void cacher()
	{	fireTraitementCache(new TraitementEvent(this));
	}

//	----------------------------------------	
//	Copier/Coller/Undo
//	----------------------------------------
	/*
	 * renvoie une copie de cet EditeurObservation.
	 * Le nouvel Editeur est réglé sur le męme fichier.
	 * Il a le męme parent que cet Editeur, 
	 * mais c'est temporaire : la copie est destinée ŕ 
	 * ętre insérée dans une autre SectionInformationEndogene.
	 * L'observationFichier et l'observationFlag sont les męmes.
	  */
	public EditeurObservation cloner()
	{	EditeurObservation resultat;
		
		// COPIE
		resultat = new EditeurObservation(parent);
		resultat.setObservable(observationFlag);
		// on clone le fichier
		resultat.setclonerObservationFichier(new File(observationFichier.getPath()));
		resultat.setclonerEstObservationFichierAffecte(observationFichierAffecte);
		// la liste de magnitudes
		VectorMagnitude tempVmag = new VectorMagnitude();
		for (int i=0;i<size();i++)
		{	Magnitude mag = vDonnee.getMagnitude(i).cloner();
			mag.setParent(resultat);
			tempVmag.addMagnitude(mag);
			mag.addInformationListener(resultat);
		}
		resultat.setclonerDonnees(tempVmag);
		//  la liste d'instants
		Vector tempVinst = new Vector();
		for (int i=0;i<size();i++)
		{	Integer inst = new Integer(((Integer)vInstant.get(i)).intValue());
			tempVinst.add(inst);
		}
		resultat.setclonerInstants(tempVinst);
		 
		resultat.setNonModifie();
		return resultat;
	}
	/**
	 * utilisée lors du clonage pour modifier un champ 
	 * de façon directe.
	 * 
	  */
	public void setclonerObservationFichier(File fichier)
	{	observationFichier = fichier;
	}
	/**
	 * utilisée lors du clonage pour modifier un champ 
	 * de façon directe.
	 * 
	  */
	public void setclonerDonnees(VectorMagnitude v)
	{	vDonnee = v;
	}
	/**
	 * utilisée lors du clonage pour modifier un champ 
	 * de façon directe.
	 * 
	  */
	public void setclonerInstants(Vector v)
	{	vInstant = v;
	}
	  /**
	   * utilisée lors du clonage pour modifier un champ 
	   * de façon directe.
	   * 
		*/
	public void setclonerEstObservationFichierAffecte(boolean b)
	{	observationFichierAffecte = b;
	}
	/*
	 * 
	 */
	public InterfaceHomonyme getHomonyme(Modele m) throws HomonymeIntrouvableException
	{	InterfaceHomonyme resultat;
		if (m == getModele())
		    resultat = this;
		else
		{	resultat = ((AbstractSectionInformationEndogene)parent.getHomonyme(m)).getObservationEditeur(); 
		}
		return resultat;
	}
	/*
	 *
	 */
	public boolean estCollable()
	{	boolean resultat = true;
	    Tampon tampon = getModele().getTampon();
		if (tampon.estVide())
			resultat = false;
		else
		{	InterfaceCopiable buffer = tampon.get();
			if (buffer instanceof Magnitude)
			    resultat = true;
			else
				resultat = false;
		}
		return resultat;
	}
	/*
	 * 
	 */
	public void coller() throws CopiableIncompatibleException
	{	  Tampon tampon = getModele().getTampon();
		if (tampon.estVide())
			throw new CopiableIncompatibleException(getIdentification());
		InterfaceCopiable buffer = tampon.get();
		if (buffer instanceof Magnitude)
		{	Magnitude temp = (Magnitude) buffer;
		    addObservation(temp);
		}
		else
			throw new CopiableIncompatibleException(getIdentification());
	}
	/**
	 * récupčre le répertoire d'observation du parent et le complčte de maničre
	 * ŕ construire le répertoire d'observation de cet Editeur.  
	 * 
	 * @throws	IOException	si une erreur se produit lors de l'accčs au répertoire.
	 * 
	  */
	public void raffraichirRepertoireObservation() throws IOException
	{	File repertoire = parent.getRepertoireObservation();
		if (repertoire != null)
		{	File repertoireObservation = new File(repertoire.getPath()
				+ Commun.EXT_OBSERVATION);
			if (!repertoireObservation.getPath().equals(observationFichier.getPath()))
			{	File temp = observationFichier;
				// de toute façon, on change le nom du fichier d'observation 			
				observationFichier = repertoireObservation;
				// si un fichier a été affecté
				if (observationFichierAffecte)
				{	//création éventuelle du répertoire
//				  creerRepertoire();
observationFichier.getParentFile().mkdirs();
					//on le copie au nouvel emplacement
					Commun.copierFichier(temp,observationFichier);
				}
			}
		}
		else
		{	removeObservationFichier();
			observationFichier = null;
			observationFichierAffecte = false;
		}
		setModifie();
	    fireTraitementRaffr(new TraitementEvent(this));
	}
	/**
	 * renvoie vrai si cet Editeur dispose d'un fichier
	 * d'observation.  
	 *
	 * @return	vrai si cet Editeur a un fichier d'observation. 
	  */
	public boolean estObservationFichierAffecte()
	{	return observationFichierAffecte;
	}
	/**
	 * modifie l'indicateur d'observation de cet Editeur 
	 * suivant la valeur passée en paramčtre.  
	 *
	 * @param	flag	nouvelle valeur de l'indicateur d'observation. 
	  */
	public void setObservationFichierAffecte(boolean flag) throws IOException, ClassNotFoundException, VersionFichierIncompatibleException, TypeFichierIncompatibleException, ContenuFichierIncompatibleException
	{	if (observationFichier != null)
		{	observationFichierAffecte = flag; 
			if (flag)
				setObservationFichier(observationFichier);
			else
				removeObservationFichier();
			setModifie();
		    fireTraitementRaffr(new TraitementEvent(this));
		}
	}
	/*
	 * 
	 */
	public String getIdentification()
	{	return parent.getIdentification()+">"+Commun.STRING_EDITEUR+" "+Commun.STRING_OBSERVATIONS;
	}

	//	----------------------------------------	
	//	Modification
	//	----------------------------------------
	/*
	 * 
	 */
	public void setModifie()
	{	modifie = true;
	}
	/*
	 * 
	 */
	public boolean estModifie()
	{	return modifie;  
	}
	/*
	 * 
	 */
    public void setNonModifie()
    {	modifie = false;
		for (int i=0;i<size();i++)
		{	getMagnitude(i).setNonModifie();
		}
	    fireTraitementRaffr(new TraitementEvent(this));
    }
}
back to top