private EtatInfos Ajouter( EtatInfos etatInfos) { try { etatInfos.EstActif = true; using (lockeur.RecupererLockEcriture()) { #if DEBUG if (dicoEtatsInfos.ContainsKey(etatInfos.EtatOrigine)) { // L'état est déjà dans l'arbre => erreur throw new ExceptionTechniqueArbreConstruction( ExceptionBase.RecupererLibelleMessage()); } #endif dicoEtatsInfos .Add( etatInfos.EtatOrigine, etatInfos); return(etatInfos); } } catch (Exception ex) { throw EncapsulerEtGererException <ExceptionTechniqueArbreConstruction>( ex); } }
public IEtatTransitionsSortantes Supprimer( Transition transition) { try { if (transitions.Contains(transition)) { transitions.Remove( transition); } else { throw new ExceptionTechnique( ExceptionBase.RecupererLibelleMessage( $"Impossible de supprimer la transition {transition}")); } return(this); } catch (Exception ex) { throw EncapsulerEtGererException <ExceptionTechnique>( ex); } }
public static bool EstIdentique <T>( this IEnumerable <T> elements1, IEnumerable <T> elements2) { try { elements1 = (elements1 as ICollection <T>) ?? elements1.ToArray(); // Permet de ne pas recalculer en permanence le contenu si c'est un Enumerable 'pur' elements2 = (elements2 as ICollection <T>) ?? elements2.ToArray(); if (elements1.Count() != elements2.Count()) { return(false); } else { return(!elements1 .Except(elements2) .Any()); } } catch (Exception ex) { Fabrique.Instance ?.RecupererGestionnaireTraces() ?.PublierException( ex); throw new ExceptionTechnique( ExceptionBase.RecupererLibelleMessage(), ex); } }
public static ICollection <T> AjouterSaufSiStocke <T>( this ICollection <T> collection, IEnumerable <T> elementsAAjouter) { try { elementsAAjouter = (elementsAAjouter as ICollection <T>) ?? elementsAAjouter.ToArray(); // Permet de ne pas recalculer en permanence le contenu si c'est un Enumerable 'pur' if (elementsAAjouter.Any()) { if (elementsAAjouter.Count() == 1) { var item = elementsAAjouter.First(); if (!collection.Contains(item)) { collection .Add( item); } } else { var items = elementsAAjouter .Except(collection); collection .Ajouter(items); } } return(collection); } catch (Exception ex) { Fabrique.Instance ?.RecupererGestionnaireTraces() ?.PublierException( ex); throw new ExceptionTechnique( ExceptionBase.RecupererLibelleMessage(), ex); } }
public static ICollection <T> AjouterSaufSiStocke <T>( this ICollection <T> collection, params T[] elementsAAjouter) { try { return(collection .AjouterSaufSiStocke( elementsAAjouter.AsEnumerable())); } catch (Exception ex) { Fabrique.Instance ?.RecupererGestionnaireTraces() ?.PublierException( ex); throw new ExceptionTechnique( ExceptionBase.RecupererLibelleMessage(), ex); } }
public static ICollection <T> Ajouter <T>( this ICollection <T> collection, IEnumerable <T> elementsAAjouter) { try { var liste = collection as List <T>; if (null != liste) { liste .AddRange(elementsAAjouter); } else { foreach (var item in elementsAAjouter) { collection .Add(item); } } return(collection); } catch (Exception ex) { Fabrique.Instance ?.RecupererGestionnaireTraces() ?.PublierException( ex); throw new ExceptionTechnique( ExceptionBase.RecupererLibelleMessage(), ex); } }
public void Etiquetter( string id, EnumTypeBlock typeBlock, Etat etatEntree, Etat etatSortie) { try { // Récupération des infos sur les états en entrée et en sortie EtatInfos etatInfosEntree = null, etatInfosSortie = null; using (lockeur.RecupererLockLecture()) { bool etatEntreeDansArbre = dicoEtatsInfos .TryGetValue( etatEntree, out etatInfosEntree); bool etatSortieDansArbre = dicoEtatsInfos .TryGetValue( etatSortie, out etatInfosSortie); if (!etatEntreeDansArbre || !etatSortieDansArbre) { throw new ExceptionTechniqueArbreConstruction( ExceptionBase.RecupererLibelleMessage()); } } // Note : on lève le verrou sur le dico pour maintenir les performances. On vérifie plus loin que les états existent encore (après les avoir lockés)... // Lock sur les états source et cible en évitant les inter-locks : lock toujours dans le même ordre var lockeurs = RecupererLockeurs( etatInfosEntree, etatInfosSortie); using (lockeurs[0].RecupererLockEcriture()) { if (!etatInfosEntree.EstActif) { throw new ExceptionTechniqueArbreConstruction( ExceptionBase.RecupererLibelleMessage()); } etatEntree.Etiquette = new EtiquetteDto( id, typeBlock, EnumExtremiteEtiquette.Entree); etatInfosEntree .InterdireTransitionSortante(); } if (lockeurs.Length == 2) { using (lockeurs[1].RecupererLockEcriture()) { if (!etatInfosSortie.EstActif) { throw new ExceptionTechniqueArbreConstruction( ExceptionBase.RecupererLibelleMessage()); } etatSortie.Etiquette = new EtiquetteDto( id, typeBlock, EnumExtremiteEtiquette.Sortie); etatInfosSortie .InterdireTransitionEntrante(); } } } catch (Exception ex) { throw EncapsulerEtGererException <ExceptionTechniqueArbreConstruction>( ex); } }
public Transition AjouterTransition( Etat etatSource, Etat etatCible, char?symbole) { try { // Récupération des infos sur les états source et cible EtatInfos etatInfosSource = null, etatInfosCible = null; using (lockeur.RecupererLockLecture()) { bool etatSourceDansArbre = dicoEtatsInfos .TryGetValue( etatSource, out etatInfosSource); bool etatCibleDansArbre = dicoEtatsInfos .TryGetValue( etatCible, out etatInfosCible); if (!etatSourceDansArbre || !etatCibleDansArbre) { throw new ExceptionTechniqueArbreConstruction( ExceptionBase.RecupererLibelleMessage()); } } // Note : on lève le verrou sur le dico pour maintenir les performances. On vérifie plus loin que les états existent encore (après les avoir lockés)... // Lock sur les états source et cible en évitant les inter-locks : lock toujours dans le même ordre var lockeurs = RecupererLockeurs( etatInfosSource, etatInfosCible); using (lockeurs[0].RecupererLockEcriture()) { using ((lockeurs.Length == 2 ? lockeurs[1] : new LockEcritureEtLectureFake()) // Si la transition est récursive, alors Fake .RecupererLockEcriture()) { // Les états source et cible sont-ils encore dans l'arbre ? (vérification pour se prémunir dans un environnement multi-threads) if (!etatInfosSource.EstActif || !etatInfosCible.EstActif) { // L'état source et/ou l'état cible n'existe(nt) plus dans l'arbre => erreur throw new ExceptionTechniqueArbreConstruction( ExceptionBase.RecupererLibelleMessage()); } // La transition existe t'elle déjà ? var transition = new Transition( etatSource, etatCible, symbole); var etatSourceTransitionsSortantes = etatInfosSource.TransitionsSortantes; var transitionEquivalente = etatSourceTransitionsSortantes .RecupererTransitionEquivalente(transition); if (null != transitionEquivalente) { // La transition existe déjà => pas d'ajout // RDG 1 : Il ne peut y avoir qu'une seule transition pour un état cible et un symbole (même vide) donné, pour un état source. return(transitionEquivalente); } else { // La transition n'existe pas encore => ajout if (!etatInfosSource.AjoutTransitionSortantePossible) { throw new ExceptionTechniqueArbreConstruction( ExceptionBase.RecupererLibelleMessage( $"L'ajout d'une transition sortante sur l'état {etatInfosCible.EtatOrigine.Identifiant} est interdit")); } if (!etatInfosCible.AjoutTransitionEntrantePossible) { throw new ExceptionTechniqueArbreConstruction( ExceptionBase.RecupererLibelleMessage( $"L'ajout d'une transition entrante sur l'état {etatInfosCible.EtatOrigine.Identifiant} est interdit")); } if (symbole.HasValue) { // Ajout d'une transition avec symbole // Le symbole existe t'il déjà sur une transition sortante ? // RDG 2 : Un état ne doit avoir qu'une transition sortante par symbole. // RDG 3 : Il peut y avoir plusieurs transitions sans symbole vers des états différents. transitionEquivalente = etatSourceTransitionsSortantes .RecupererTransitionAvecSymbole( symbole.Value); if (null != transitionEquivalente) { // Une transition existe déjà avec le même symbole (vers un autre état) => reconstruction pour respecter les RDG // Création d'un état intermédiaire qui deviendra la cible du symbole. // Il sera également la source de transitions sans symbole : // - vers l'état ciblé par la transition équivalente // - et l'état ciblé en paramètre. var etatCibleSurEquivalence = transitionEquivalente.EtatCible; var etatInfosIntermediaire = CreerEtatEtSesInfos(); // Création de l'état intermédiaire sans l'ajouter dans l'arbre, ce qui permet de le locker var etatIntermediaire = etatInfosIntermediaire.EtatOrigine; var etatIntermediaireTransitionsSortantes = etatInfosIntermediaire.TransitionsSortantes; // Préparation des transitions var transitionIntermediaire = new Transition( etatSource, etatIntermediaire, symbole.Value); var transitionVersEtatCibleOrigine = new Transition( etatIntermediaire, etatCibleSurEquivalence); var transitionVersEtatCible = new Transition( etatIntermediaire, etatCible); // Ajout de l'état intermédiaire et des transitions dans l'arbre using (etatInfosIntermediaire.Lockeur.RecupererLockEcriture()) { Ajouter( etatInfosIntermediaire); etatIntermediaireTransitionsSortantes .Ajouter(transitionVersEtatCibleOrigine) .Ajouter(transitionVersEtatCible); etatSourceTransitionsSortantes .Supprimer(transitionEquivalente) .Ajouter(transitionIntermediaire); } return(transitionVersEtatCible); } else { // Transition avec symbole, le symbole n'est pas encore déclaré => ajout } } else { // Transition sans symbole vers un état pas encore ciblé => ajout } // Ajout de la transition etatSourceTransitionsSortantes .Ajouter(transition); return(transition); } } } } catch (Exception ex) { throw EncapsulerEtGererException <ExceptionTechniqueArbreConstruction>( ex); } }
protected Exception EncapsulerEtGererException <T>( string message, Exception ex, bool forcerEncapsulation = false) where T : ExceptionBase { try { if (null == ex) { return(EncapsulerEtGererException <ExceptionTechnique>( new ArgumentNullException(nameof(ex)))); } var exEncapsulee = (ex as ExceptionBase); if (null != exEncapsulee) { // Exception déjà encapsulée => trace le message (si existe) + retourne l'exception // Traces du message if (StringHelper.EstNonNullEtNonVideEtNonEspaces(message)) { FabriqueInstance ?.RecupererGestionnaireTraces() ?.PublierErreur( ExceptionBase.RecupererLibelleMessage(message, -1)); } // Relancer exception encapsulée if (forcerEncapsulation) { return((T)Activator.CreateInstance( typeof(T), ExceptionBase.RecupererLibelleMessage(message, -1), exEncapsulee)); } else { return(exEncapsulee); } } else { // Exception non encapsulée => encapsulation => trace l'exception encapsulée + la retourne // Encapsulation exEncapsulee = (T)Activator.CreateInstance( typeof(T), ExceptionBase.RecupererLibelleMessage(message, -1), ex); // Traces FabriqueInstance ?.RecupererGestionnaireTraces() ?.PublierException( exEncapsulee); // Retourne exception encapsulée return(exEncapsulee); } } #if DEBUG catch (Exception ex_) { Debug .WriteLine( ex_.Message); Debugger .Break(); throw; } #else catch (Exception) { throw; } #endif }