/// <summary> /// Generates the specified service provider. /// </summary> /// <param name="serviceProvider">The service provider.</param> /// <param name="modelFileName">Name of the model file.</param> /// <param name="selectedElement">The selected element.</param> public static void Generate(IServiceProvider serviceProvider, string modelFileName, ICustomizableElement selectedElement) { if (modelFileName == null) { throw new ArgumentNullException("modelFileName"); } ILogger logger = ServiceLocator.Instance.GetService <ILogger>(); IIDEHelper ide = ServiceLocator.Instance.IDEHelper; Generator.s_serviceProvider = serviceProvider; try { // Sauvegarde de tous les documents ServiceLocator.Instance.ShellHelper.Solution.DTE.Documents.SaveAll(); CandleModel model = CandleModel.GetModelFromCurrentSolution(modelFileName); // Chargement du modèle //ModelLoader loader = ModelLoader.GetLoader(modelFileName, false); //if (loader == null || loader.Model == null) //{ // if (logger != null) // logger.Write("Generator", "unable to load the model", LogType.Error); // return; //} //CandleModel model = loader.Model; if (model.Component == null) { if (logger != null) { logger.Write("Generator", "model contains no software component.", LogType.Error); } return; } if (StrategyManager.GetInstance(model.Store).GetStrategies(null, true).Count == 0) { if (logger != null) { logger.Write("Generator", "No strategies configured.", LogType.Error); } return; } // CandleModel model = loader.Model; s_context = new GenerationContext(model, modelFileName, selectedElement != null ? selectedElement.Id : Guid.Empty); GenerationPass generationPassesSelected = GenerationPass.CodeGeneration | GenerationPass.MetaModelUpdate; try { // Demande des stratégies à executer if (selectedElement != null) { RunningStrategiesForm dlg = new RunningStrategiesForm(selectedElement.StrategiesOwner); if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.Cancel) { return; } s_context.SelectedStrategies = dlg.SelectedStrategies; generationPassesSelected = dlg.SelectedGenerationPasses; } if (logger != null) { logger.BeginProcess(true, true); } // Préparation de l'IDE ide.SetWaitCursor(); ide.DisplayProgress("Generate...", 1, 3); Microsoft.VisualStudio.Modeling.Validation.ValidationContext vc = new Microsoft.VisualStudio.Modeling.Validation.ValidationContext(Microsoft.VisualStudio.Modeling.Validation.ValidationCategories.Save, model); if (vc.CurrentViolations.Count > 0) { if (ide != null) { if (ide.ShowMessageBox("There is validation errors, continue generate ?", "Generation", MessageBoxButtons.YesNo) == DialogResult.No) { return; } } } // Au cas ou cette passe a été forcé dans la boite de dialogue if ((generationPassesSelected & GenerationPass.ElementAdded) == GenerationPass.ElementAdded) { if (logger != null) { logger.BeginStep("Code Generation for the ElementAdded event", LogType.Info); } s_context.GenerationPass = GenerationPass.ElementAdded; using (Transaction transaction = model.Store.TransactionManager.BeginTransaction("Update metamodel")) { model.Component.GenerateCode(s_context); transaction.Commit(); } if (logger != null) { logger.EndStep(); } } // Mise à jour du méta modèle if ((generationPassesSelected & GenerationPass.MetaModelUpdate) == GenerationPass.MetaModelUpdate) { if (logger != null) { logger.BeginStep("1) Meta Model Update", LogType.Info); } s_context.GenerationPass = GenerationPass.MetaModelUpdate; using (Transaction transaction = model.Store.TransactionManager.BeginTransaction("Update metamodel")) { // On ne veut pas que les wizards soient appelés model.Store.TransactionManager.CurrentTransaction.TopLevelTransaction.Context.ContextInfo[StrategyManager.IgnoreStrategyWizards] = true; model.Component.GenerateCode(s_context); if (transaction.HasPendingChanges) { transaction.Commit(); } } if (logger != null) { logger.EndStep(); } } if (logger != null) { logger.BeginStep("1) Check references", LogType.Info); } // Vérification des dépendances ReferencesHelper.CheckReferences(true, vc, new ConfigurationMode(), ReferenceScope.Compilation, model); if (logger != null) { logger.EndStep(); } ide.DisplayProgress("Generate...", 2, 3); // Génération de code if ((generationPassesSelected & GenerationPass.CodeGeneration) == GenerationPass.CodeGeneration) { if (logger != null) { logger.BeginStep("2) Code Generation", LogType.Info); } s_context.GenerationPass = GenerationPass.CodeGeneration; model.Component.GenerateCode(s_context); if (logger != null) { logger.EndStep(); } } } finally { Mapper.Instance.Save(); } //if (logger != null) // logger.BeginStep("Generation epilogue", LogType.Debug); //if (logger != null) // logger.EndStep(); } catch (Exception ex) { if (logger != null) { logger.WriteError("Generator", "Generator", ex); } } finally { // On s'assure de faire disparaitre la progress bar ide.DisplayProgress("", 2, 0); if (logger != null) { logger.EndProcess(); } if (ide != null) { ide.ShowErrorList(); } } }
/// <summary> /// Récupère les stratégies du modèle courant. /// </summary> /// <param name="store"></param> /// <remarks> /// Si un autre modèle est ouvert dans la solution, on retourne un manager ne contenant aucune strategie. /// </remarks> /// <returns></returns> public static IStrategyManager GetInstance(Store store) { // Modèle correspondant au store CandleModel model = CandleModel.GetInstance(store); if (model == null) // On a pas trouvé le modèle, on retourne un strategyManager vide { return(new StrategyManager()); } // Si on a dèja chargé les stratégies, on les retourne if (s_currentModelId != Guid.Empty && s_currentModelId == model.Id) { return(s_currentStrategyManager); } // Est ce que c'est le modèle courant CandleModel currentModel = CandleModel.GetModelFromCurrentSolution(); if (currentModel == null || currentModel.Id != model.Id) { return(new StrategyManager()); } // Sinon on va créer les stratégies SuspendWatcher(false); // Flag indiquant si on peut persister les stratégies ou seulement les initialiser. // On ne peut pas persister si on est dans le cas d'une initialisation du modèle puisqu'on ne connait pas // encore le nom du modèle bool canPersist = true; string strategyFileName = null; try { // Création d'un nouveau fichier de strategies ayant le même nom que le modèle mais avec // l'extension .strategies string modelFileName = model.FileName; // Dans le cas d'une création d'un modèle, on ne peut pas récupérer le filepath du modèle car // il n'y a pas encore de vue active. Dans ce cas, on essaye de le déduire. if (modelFileName == null) { string name = model.Name; // On est dans le cas d'une initialisation de modèle, on ne va crèer le fichier des stratégies tout de suite // on attend que le modèle soit initialisé if (name.Contains("?")) { canPersist = false; strategyFileName = Path.GetTempFileName(); // Fichier temporaire pour récupèrer les stratégies pré-initialisées Utils.DeleteFile(strategyFileName); // Obligé car GetTempFileName crée le fichier } else { IShellHelper shell = ServiceLocator.Instance.GetService <IShellHelper>(); if (shell != null) { string tmp = Path.GetFileNameWithoutExtension(shell.GetSolutionAssociatedModelName()); if (!String.IsNullOrEmpty(tmp)) { name = tmp; } else { tmp = shell.Solution.FullName; if (!String.IsNullOrEmpty(tmp)) { name = Path.GetFileNameWithoutExtension(tmp); } } } strategyFileName = String.Concat(Path.Combine(ServiceLocator.Instance.ShellHelper.SolutionFolder, name), DefaultStrategiesFileNameExtension); } } else { strategyFileName = Path.ChangeExtension(modelFileName, DefaultStrategiesFileNameExtension); } // Initialisation du fichier de stratégies à partir d'un modèle if (!String.IsNullOrEmpty(model.StrategyTemplate)) { EnsureStrategiesFileExists(strategyFileName, model.StrategyTemplate, canPersist); } StrategyManager manager = null; if (File.Exists(strategyFileName)) { manager = Load(store, strategyFileName); } else { manager = new StrategyManager(); } if (canPersist) { manager.FileName = strategyFileName; // Cache pour éviter de le relire s_currentModelId = model.Id; s_currentStrategyManager = manager; } return(manager); } finally { SuspendWatcher(true); // Suppression du fichier temporaire if (!canPersist) { Utils.DeleteFile(strategyFileName); } } }
/// <summary> /// Called when [after save]. /// </summary> /// <param name="docCookie">The doc cookie.</param> /// <returns></returns> int IVsRunningDocTableEvents.OnAfterSave(uint docCookie) { if (_generating) { return(VSConstants.S_OK); } // Pour éviter de boucler, on ne regénére pas si la dernière génération s'est faite dans les dernières 2 sec TimeSpan ts = DateTime.Now - _lastGenerationTime; if (ts.TotalSeconds <= 2) { return(VSConstants.S_OK); } IVsRunningDocumentTable rdtEvents = GetService <IVsRunningDocumentTable>(typeof(SVsRunningDocumentTable)); uint pgrfRDTFlags; uint pdwReadLocks; uint pdwEditLocks; string filePath; IVsHierarchy ppHier; IntPtr ppunkDocData; uint itemId; if ( rdtEvents.GetDocumentInfo(docCookie, out pgrfRDTFlags, out pdwReadLocks, out pdwEditLocks, out filePath, out ppHier, out itemId, out ppunkDocData) == VSConstants.S_OK && filePath != null) { string folderPath = Path.GetDirectoryName(filePath).ToLower(); if (!_configFolders.Contains(folderPath) || Path.GetExtension(filePath).ToLower() != ".config") { return(VSConstants.S_OK); } try { _generating = true; // TODO recherche le modele à partir d'autre chose que la RDT car il faut que ça marche // même si le modèle n'a pas été ouvert. IShellHelper shell = GetService <IShellHelper>(); if (shell != null) { CandleModel model = CandleModel.GetModelFromCurrentSolution(); if (model != null && model.SoftwareComponent != null) { foreach (LayerPackage lp in model.SoftwareComponent.LayerPackages) { if (lp.IsHigherLevel()) { foreach (Layer layer in lp.Layers) { Project project = shell.FindProjectByName(layer.VSProjectName); if (project != null) { string projectFolder = Path.GetDirectoryName(project.FileName); GenerateConfigurationFile(layer, project, projectFolder, false); } } break; } } } } } catch (Exception) { return(VSConstants.S_FALSE); } finally { _lastGenerationTime = DateTime.Now; _generating = false; } } return(VSConstants.S_OK); }