// Ajout de l'élément /// <summary> /// Alerts listeners that a rule has been used. /// </summary> /// <param name="e">An ElementAddedEventArgs that contains the event data.</param> public override void ElementAdded(ElementAddedEventArgs e) { #region Condition // Test the element ICustomizableElement model = e.ModelElement as ICustomizableElement; if (model == null) { return; } if ( e.ModelElement.Store.TransactionManager.CurrentTransaction.TopLevelTransaction.TopLevelTransaction. IsSerializing || e.ModelElement.Store.InUndoRedoOrRollback || e.ModelElement.Store.TransactionManager.CurrentTransaction.TopLevelTransaction.Context.ContextInfo. ContainsKey(StrategyManager.IgnoreStrategyWizards)) { return; } #endregion #region Traitement // A ce stade, on est dans une transaction IStrategyWizard defaultWizard = GetDefaultWizard(e.ModelElement); if (!model.ExecuteWizard(e.ModelElement, defaultWizard)) { // L'utilisateur a annulé throw new CanceledByUser(); } #endregion }
public override bool IsModelGenerationExclusive(GenerationContext context, ICustomizableElement currentElement, string generatedFileName) { // On génére toutes les classes DA0 if (context.GenerationPass == GenerationPass.CodeGeneration) { if (currentElement is ClassImplementation && Utils.StringCompareEquals(Path.GetFileNameWithoutExtension(generatedFileName), currentElement.Name + "Base")) { return(((ClassImplementation)currentElement).Layer is DataAccessLayer); } } // Les enums if (currentElement is Enumeration) { return(true); } // Et toutes les entités persistables if (currentElement is Entity && EntityIsPersistableProperty.GetValue(currentElement)) { return(true); } return(base.IsModelGenerationExclusive(context, currentElement, generatedFileName)); }
/// <summary> /// Vérification si une stratégie n'a pas les droits de génération exclusif sur cet élément /// </summary> /// <param name="element">The element.</param> /// <param name="strategy">The strategy.</param> /// <param name="generatedFileName">Name of the generated file.</param> /// <returns> /// <c>true</c> if [is generation locked] [the specified element]; otherwise, <c>false</c>. /// </returns> public bool IsGenerationLocked(ICustomizableElement element, StrategyBase strategy, string generatedFileName) { ILogger logger = ServiceLocator.Instance.GetService <ILogger>(); if (logger != null) { logger.BeginStep("Check generation lock", LogType.Debug); logger.Write("Check generation lock", String.Concat("Current strategy ", strategy.StrategyId, " for outputfile ", generatedFileName ?? "(no file specified)"), LogType.Debug); } foreach (StrategyBase otherStrategy in element.GetStrategies(false)) { if (strategy.StrategyId != otherStrategy.StrategyId && otherStrategy.IsModelGenerationExclusive(this, element, generatedFileName)) { if (logger != null) { logger.Write("Check generation lock", String.Format("Element {0} generation locked by strategy {1}", element.Name, otherStrategy.StrategyId), LogType.Debug); logger.EndStep(); } return(true); } } if (logger != null) { logger.EndStep(); } return(false); }
/// <summary> /// Gets the parent for class uses operations. /// </summary> /// <param name="classUsesOperations">The class uses operations.</param> /// <returns></returns> private Microsoft.VisualStudio.Modeling.ModelElement GetParentForClassUsesOperations(ClassUsesOperations classUsesOperations) { ICustomizableElement clazz = classUsesOperations.Source as ICustomizableElement; System.Diagnostics.Debug.Assert(clazz != null); return(((SoftwareLayer)clazz.Owner).Component.Model); }
/// <summary> /// Tries the get value. /// </summary> /// <param name="element">The element.</param> /// <param name="strategyId">The strategy id.</param> /// <param name="propertyName">Name of the property.</param> /// <param name="value">The value.</param> /// <returns></returns> public static bool TryGetValue(ICustomizableElement element, string strategyId, string propertyName, out T value) { IDependencyProperty p = DependencyPropertyRegistry.Instance.FindDependencyProperty(strategyId, propertyName); if (p != null) { return(TryGetValue(p, element, strategyId, propertyName, out value)); } throw new Exception(String.Concat("Invalid property name ", propertyName, " for strategy ", strategyId)); }
T CheckHandlerEnabled <T>(DependencyProperty <T> property, ICustomizableElement element) where T : IPIABHandler { T handler = property.GetValue(element); if (handler != null && handler.Enabled) { return(handler); } return(default(T)); }
/// <summary> /// Détermine si cette propriété a été initialisée /// </summary> /// <param name="element">The element.</param> /// <returns> /// <c>true</c> if the specified element has value; otherwise, <c>false</c>. /// </returns> public bool HasValue(ICustomizableElement element) { if (element == null) { throw new ArgumentNullException("element"); } DependencyProperty property = element.GetStrategyCustomProperty(_strategyId, _name, false); return(property != null && property.Value != null); }
/// <summary> /// Runs the strategy internal. /// </summary> /// <param name="element">The element.</param> /// <param name="strategy">The strategy.</param> /// <param name="context">The context.</param> private static void RunStrategyInternal(ICustomizableElement element, StrategyBase strategy, GenerationContext context) { ILogger logger = ServiceLocator.Instance.GetService <ILogger>(); IStrategyCodeGenerator si = strategy as IStrategyCodeGenerator; if (si == null) { if (logger != null) { logger.Write("Running strategy", "Strategy ignored because this is not a code generation strategy", LogType.Debug); } return; } try { if (logger != null) { logger.Write("Running strategy", String.Concat("Execute strategy '", strategy.DisplayName, "' id : ", strategy.StrategyId), LogType.Debug); } strategy.InitializeContext(context, element); if (context.GenerationPass == GenerationPass.CodeGeneration) { Mapper.Instance.BeginGenerationTransaction(context, strategy.StrategyId, element.Id); } si.Execute(); if (context.GenerationPass == GenerationPass.CodeGeneration) { Mapper.Instance.CommitGenerationTransaction(context); } } catch (Exception ex) { if (context.GenerationPass == GenerationPass.CodeGeneration) { Mapper.Instance.RollbackGenerationTransaction(context); } if (logger != null) { logger.WriteError("Running strategy " + strategy.DisplayName, String.Concat("Strategy '", strategy.DisplayName, "' id : ", strategy.StrategyId), ex); } } finally { strategy.InitializeContext(null, null); } }
/// <summary> /// Génération du projet correspondant à cette couche /// </summary> /// <param name="elem">The elem.</param> public virtual void GenerateVSProject(ICustomizableElement elem) { _layer = elem as SoftwareLayer; if (_layer == null) { return; } Project project = null; if (Context.CanGenerate(_layer.Id)) { // Nom du dossier qui contient le projet string folderName = _layer.GetProjectFolderName(); // Template du projet string templateName = GetProjectTemplate(_layer); // Création du projet si il n'existe pas project = ServiceLocator.Instance.ShellHelper.CreateVSProject(folderName, _layer.VSProjectName, templateName); if (project != null) { ServiceLocator.Instance.ShellHelper.SetProperty(project, "DefaultNamespace", _layer.Namespace); ServiceLocator.Instance.ShellHelper.SetProperty(project, "AssemblyName", _layer.AssemblyName); // Ajout des références ServiceLocator.Instance.ShellHelper.AddProjectReferencesToProject(project, ReferencesHelper.GetReferences( Context.Mode, ReferenceScope.Compilation, ServiceLocator.Instance. ShellHelper.SolutionFolder, _layer)); if (_layer is Layer && ((Layer)_layer).StartupProject) { ServiceLocator.Instance.ShellHelper.Solution.SolutionBuild.StartupProjects = project.UniqueName; } } } else { // Si il y avait un élément sélectionné pour la génération, il faut quand même // initialisé le projet concerné project = GetProject(); } // ShellHelper.SetProjectProperty( project, ConfigurationMode.All, "OutputPath", ResolveRepositoryPath( DSLFactory.Candle.SystemModel.Repository.RepositoryManager.LATEST ) ); Context.Project = project; }
/// <summary> /// Execute les stratégies de génération de projet /// </summary> /// <param name="element">The element.</param> /// <param name="context">The context.</param> internal static void ApplyProjectGeneratorStrategies(ICustomizableElement element, GenerationContext context) { ILogger logger = ServiceLocator.Instance.GetService <ILogger>(); if (logger != null) { logger.BeginStep("Project generation " + element.Name, LogType.Info); logger.Write("Project generation", String.Concat("Current layer is ", element.Name, " (id=", element.Id, ")"), LogType.Debug); } IList <StrategyBase> strategies = element.GetStrategies(true); // D'abord exécution des stratégies générant les projets bool strategyFinding = false; foreach (StrategyBase strategy in strategies) { if (strategy is IStrategyProjectGenerator) { strategyFinding = true; try { strategy.InitializeContext(context, element); ((IStrategyProjectGenerator)strategy).GenerateVSProject(element); if (logger != null) { logger.Write("Project generation", String.Concat("Strategy '", strategy.DisplayName, "' id : ", strategy.StrategyId, " on layer ", element.Name), LogType.Debug); } } catch (Exception ex) { if (logger != null) { logger.WriteError("Project generation", String.Concat("Strategy '", strategy.DisplayName, "' id : ", strategy.StrategyId, " on layer ", element.Name, " See errors list"), ex); } } finally { strategy.InitializeContext(null, null); } } } if (logger != null) { if (!strategyFinding) { logger.Write("Project generation", "No project generation finding", LogType.Warning); } logger.EndStep(); } }
private bool CheckAllHandler(ICustomizableElement element, ICustomizableElement parent) { if (CheckHandler <LogCallHandler>(LogCallHandlerProperty, element, parent) != null) { return(true); } if (CheckHandler <CacheCallHandler>(CacheCallHandlerProperty, element, parent) != null) { return(true); } if (CheckHandler <PerformanceCounterCallHandler>(PerformanceCounterCallHandlerProperty, element, parent) != null) { return(true); } return(false); }
/// <summary> /// Mise à jour d'un paramètre personnalisé /// </summary> /// <param name="instance">The instance.</param> /// <param name="value">The value.</param> public virtual void SetValue(ICustomizableElement instance, T value) { if (instance == null) { throw new ArgumentNullException("instance"); } bool isDefaultValue = false; // HasDefaultValue && DefaultValue.Equals(value);// (Voir ShouldSerializeValue property) || (_shouldSerializeValueDelegate != null && !_shouldSerializeValueDelegate(value)); DependencyProperty property = instance.GetStrategyCustomProperty(_strategyId, _name, !isDefaultValue); if (property != null && value != null) { Transaction transaction = ((ModelElement)instance).Store.TransactionManager.BeginTransaction("Set custom value"); try { //property.Value = SerializationUtilities.GetString<T>(value); DependencyPropertyValue dpv = new DependencyPropertyValue(); dpv.SetValue(this, value); property.Value = dpv; transaction.Commit(); } catch (ArgumentOutOfRangeException exception) { if (transaction.IsActive) { transaction.Rollback(); } throw; } catch (Exception) { if (transaction.IsActive) { transaction.Rollback(); } throw; } } }
/// <summary> /// Execute une strategie /// </summary> /// <param name="element">The element.</param> /// <param name="context">The context.</param> /// <param name="strategy">The strategy.</param> private static void RunStrategy(ICustomizableElement element, GenerationContext context, StrategyBase strategy) { ILogger logger = ServiceLocator.Instance.GetService <ILogger>(); if (logger != null) { logger.Write("Running strategy", String.Concat("Strategy '", strategy.DisplayName, "' id : ", strategy.StrategyId), LogType.Debug); } if (context.SelectedStrategies != null && (context.SelectedStrategies != null && !context.SelectedStrategies.Contains(strategy))) { if (logger != null) { logger.Write("Running strategy", "Strategy skipped because this is not a selected strategy", LogType.Debug); } } else if (context.CanGenerate(element.Id)) { RunStrategyInternal(element, strategy, context); } }
/// <summary> /// Initializes a new instance of the <see cref="CandleTemplateHost"/> class. /// </summary> /// <param name="currentElement">The current element.</param> /// <param name="properties">The properties.</param> public CandleTemplateHost(ICustomizableElement currentElement, TemplateProperties properties) { s_templateProperties = properties; if (properties == null) { s_templateProperties = new TemplateProperties(); } _currentElement = currentElement; s_instance = this; standardAssemblyReferences = new List <string>(); standardAssemblyReferences.Add("System.dll"); standardAssemblyReferences.Add("Microsoft.VisualStudio.Modeling.SDK, Version=" + ModelConstants.VisualStudioVersion); standardAssemblyReferences.Add("Microsoft.VisualStudio.TextTemplating.VSHost, Version=" + ModelConstants.VisualStudioVersion); //if (type != null && type.Assembly.FullName != this.GetType().Assembly.FullName) // standardAssemblyReferences.Add(type.Assembly.FullName); }
T CheckHandler <T>(DependencyProperty <T> property, ICustomizableElement element, ICustomizableElement parent) where T : IPIABHandler { T handler; if (element is Operation) { handler = CheckHandlerEnabled <T>(property, element); if (handler != null) { return(handler); } element = parent; } if (element is ClassImplementation) { handler = CheckHandlerEnabled <T>(property, element); if (handler != null) { return(handler); } handler = CheckHandlerEnabled <T>(property, parent); if (handler != null) { return(handler); } element = ((ClassImplementation)element).Contract; } if (element is ServiceContract) { handler = CheckHandlerEnabled <T>(property, element); if (handler != null) { return(handler); } return(CheckHandlerEnabled <T>(property, parent)); } return(default(T)); }
/// <summary> /// Tries the get value. /// </summary> /// <param name="self">The self.</param> /// <param name="element">The element.</param> /// <param name="strategyId">The strategy id.</param> /// <param name="propertyName">Name of the property.</param> /// <param name="value">The value.</param> /// <returns></returns> protected static bool TryGetValue(IDependencyProperty self, ICustomizableElement element, string strategyId, string propertyName, out T value) { // Recherche si cette valeur est dans le modèle DependencyProperty property = element.GetStrategyCustomProperty(strategyId, propertyName, false); if (property != null) { if (property.Value != null) // Pas initialisée { value = property.Value.GetValue <T>(self); // if (SerializationUtilities.TryGetValue<T>(SerializationUtilities.UnescapeXmlString(property.Value), out value)) if (value != null) { return(true); } } } value = default(T); return(false); }
/// <summary> /// Applique les stratégies /// </summary> /// <param name="element">The element.</param> /// <param name="context">The context.</param> internal static void ApplyStrategies(ICustomizableElement element, GenerationContext context) { ILogger logger = ServiceLocator.Instance.GetService <ILogger>(); if (logger != null) { logger.BeginStep("Strategy generation", LogType.Debug); logger.Write("Strategy generation", String.Concat("Current element is ", element.Name, " (id=", element.Id, ")"), LogType.Debug); } IList <StrategyBase> strategies = element.GetStrategies(true); // Execution des stratégies StrategyBase cfgStrategy = null; foreach (StrategyBase strategy in strategies) { if (strategy is IStrategyProjectGenerator) { continue; } if (strategy is IStrategyConfigGenerator) { cfgStrategy = strategy; continue; } RunStrategy(element, context, strategy); } if (cfgStrategy != null) { RunStrategy(element, context, cfgStrategy); } if (logger != null) { logger.EndStep(); } }
//[Description("Generated assembly extension")] //public virtual string AssemblyExtension //{ // get { return extension; } // set { extension = value; } //} #region IStrategyProjectGenerator Members /// <summary> /// Génération du projet /// </summary> /// <param name="component">The component.</param> public virtual void GenerateVSProject(ICustomizableElement component) { if (component == null || Context.GenerationPass == GenerationPass.MetaModelUpdate) { return; } if (Context.CanGenerate(component.Id)) { // Si le projet existe, on ne fait rien if (ServiceLocator.Instance.ShellHelper.FindProjectByName(_projectName) == null) { string template = GetProjectTemplate(null); // Si le template n'est pas un fichier .zip, c'est qu'on a utilisé un répertoire temporaire if (Utils.StringCompareEquals(Path.GetExtension(template), ".vstemplate")) { Utils.RemoveDirectory(Path.GetDirectoryName(template)); } } } }
/// <summary> /// Récupére la valeur de la propriété /// </summary> /// <param name="instance">The instance.</param> /// <returns></returns> public virtual T GetValue(ICustomizableElement instance) { if (instance == null) { throw new ArgumentNullException("instance"); } T value; if (TryGetValue(this, instance, _strategyId, _name, out value)) { return(value); } // Valeur par défaut if (HasDefaultValue) { value = (T)DefaultValue; } //SetValue(instance, value); return(value); }
public void OnElementAdded(ICustomizableElement owner, StrategyElementElementAddedEventArgs e) { Transaction trans = e.ModelElement.Store.TransactionManager.CurrentTransaction; object obj; if (owner is Entity) { Entity entity = (Entity)owner; if (trans.Context.ContextInfo.TryGetValue(DatabaseImporter.ImportedTableInfo, out obj)) { DbTable table = obj as DbTable; EntityIsPersistableProperty.SetValue(owner, true); } } if (owner is Property) { } if (owner is Association) { Association association = owner as Association; if (trans.Context.ContextInfo.TryGetValue(DatabaseImporter.ImportedRelationInfo, out obj)) { //RelationShip relation = obj as RelationShip; //StringBuilder sb = new StringBuilder(); //for( int i =0; i<relation.TargetColumns.Count; i++ ) //{ // sb.Append( relation.TargetColumns[i].Name ); // if( i<relation.TargetColumns.Count-1 ) // sb.Append( ',' ); //} //AssociationFKColumnNameProperty.SetValue( owner, sb.ToString() ); } } }
/// <summary> /// Initializes the context. /// </summary> /// <param name="context">The context.</param> /// <param name="element">The element.</param> public void InitializeContext(GenerationContext context, ICustomizableElement element) { ILogger logger = ServiceLocator.Instance.GetService <ILogger>(); _context = context; _currentElement = element; if (context != null) { _context.CurrentStrategy = this; } if (logger != null) { if (element != null) { logger.Write("Initializaing strategy context", String.Concat("Strategy initialized with current element ", element.Name, " (id=", element.Id, ")"), LogType.Debug); } else { logger.Write("Initializaing strategy context", "Reset strategy context", LogType.Debug); } } }
/// <summary> /// Generation appelée lors de l'insertion d'un elément. /// Correspond à la phase GenerationPas.MetaModelElementAdded /// </summary> /// <param name="serviceProvider">The service provider.</param> /// <param name="model">The model.</param> /// <param name="selectedElement">The selected element.</param> public static void GenerateWhenElementAdded(IServiceProvider serviceProvider, CandleModel model, ICustomizableElement selectedElement) { Debug.Assert(model != null); Debug.Assert(model != null); if (selectedElement.StrategiesOwner == null) { return; } ILogger logger = ServiceLocator.Instance.GetService <ILogger>(); if (logger != null) { logger.BeginProcess(true, false); } Generator.s_serviceProvider = serviceProvider; try { s_context = new GenerationContext(model, String.Empty, selectedElement.Id); ServiceLocator.Instance.IDEHelper.SetWaitCursor(); if (logger != null) { logger.BeginStep("Element added", LogType.Debug); } ServiceLocator.Instance.IDEHelper.DisplayProgress("Generate...", 1, 2); // Mise à jour du méta modèle s_context.GenerationPass = GenerationPass.ElementAdded; using (Transaction transaction = model.Store.TransactionManager.BeginTransaction("Update metamodel")) { selectedElement.StrategiesOwner.GenerateCode(s_context); transaction.Commit(); } if (logger != null) { logger.EndStep(); } } catch (Exception ex) { if (logger != null) { logger.WriteError("Generator", "element added " + selectedElement.Name, ex); } } finally { // On s'assure de faire disparaitre la progress bar ServiceLocator.Instance.IDEHelper.DisplayProgress("", 2, 0); // [Comment] Pas d'affichage car pb quand on édite une fenetre détails // a chaque ajout il ne faut pas afficher la fenetre d'erreur //ServiceLocator.Instance.IDEHelper.ShowErrorList(); if (logger != null) { logger.EndProcess(); } } }
/// <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> /// Appel d'un autre template de transformation /// </summary> /// <param name="element">The element.</param> /// <param name="T4Template">The t4 template.</param> /// <param name="outputFile">Nom du fichier de sortie ou null</param> /// <param name="properties">Dictionnaire contenant des variables de remplacement sur le code T4 avant l'exécution ou null</param> /// <returns></returns> internal static string CallT4Template(ICustomizableElement element, string T4Template, string outputFile, TemplateProperties properties) { if (element == null) { throw new ArgumentNullException("element must not be null in CallT4Template"); } if (String.IsNullOrEmpty(T4Template)) { throw new ArgumentException("T4Template is required in CallT4Template"); } ILogger logger = ServiceLocator.Instance.GetService <ILogger>(); string data = null; Encoding encoding = Encoding.Default; try { RepositoryFile repFile = null; // Si le fichier n'est pas un chemin statique, on le récupére sur le repository if (!Path.IsPathRooted(T4Template)) { // On le prend dans le repository repFile = new RepositoryFile(CandleSettings.GetT4TemplateFileName(T4Template)); } string inputFileContent = null; try { if (repFile != null) { inputFileContent = repFile.ReadContent(out encoding); } else { encoding = RepositoryFile.FindEncodingFromFile(T4Template); inputFileContent = File.ReadAllText(T4Template); } } catch { } if (String.IsNullOrEmpty(inputFileContent)) { throw new ApplicationException(String.Format("Template {0} not found or incorrect.", T4Template)); } // Génération du code CandleTemplateHost host = new CandleTemplateHost(element, properties); Engine engine = new Engine(); data = engine.ProcessTemplate(inputFileContent, host); if (host.Errors.HasErrors) { StringBuilder sb = new StringBuilder(" ERRORS {"); sb.Append(T4Template); sb.Append("} \n"); foreach (CompilerError error in host.Errors) { if (!error.IsWarning) { sb.Append(error.ToString()); sb.AppendLine(); } } if (String.IsNullOrEmpty(data)) { data = sb.ToString(); } else { data = String.Concat(data, sb.ToString()); } foreach (CompilerError err in host.Errors) { err.FileName = T4Template; } ServiceLocator.Instance.IDEHelper.LogErrors(host.Errors); if (logger != null) { logger.Write("Calling T4", String.Format("Run T4 template ({0}) for element naming {1} (id={2}) - Output file = {3} - See errors list.", T4Template, element.Name, element.Id, outputFile ?? " in memory"), LogType.Error); } } else if (logger != null) { logger.Write("Calling T4", String.Format("Run T4 template ({0}) for element naming {1} (id={2}) - Output file = {3}", T4Template, element.Name, element.Id, outputFile ?? " in memory"), LogType.Info); } } catch (Exception ex) { data = ex.Message; if (logger != null) { logger.WriteError("Calling T4", T4Template, ex); } } // Si le fichier de sortie est null, on sort. // Utilise dans le cas d'un appel de template appelant d'autres templates // On ignore le code de la première génération if (!String.IsNullOrEmpty(outputFile) && !String.IsNullOrEmpty(data) && s_context.GenerationPass != GenerationPass.MetaModelUpdate) { WriteSafeOutputFile(outputFile, data, encoding); return(data); } return(data); }
/// <summary> /// Création du fichier dans le projet /// </summary> /// <param name="prj">Projet contenant le fichier</param> /// <param name="element">Elément concerné ou null</param> /// <param name="fileName">Nom du fichier ou null (default: element.Name)</param> /// <returns>Chemin complet du fichier</returns> protected string CreateOutputFileName(Project prj, ICustomizableElement element, string fileName) { if (String.IsNullOrEmpty(fileName)) { fileName = element.Name; } if (!Path.HasExtension(fileName)) { fileName = String.Format("{0}{1}", fileName, StrategyManager.GetInstance(_currentElement.Store).TargetLanguage.Extension); } // On le prend tel quel string tmpFileName = fileName; if (tmpFileName.Length > 0 && tmpFileName[0] == '~') { tmpFileName = tmpFileName.Substring(1); } else { // Si il n'y a que le nom du fichier, on prend le pattern par défaut if (Path.GetFileName(tmpFileName) == tmpFileName) { string pattern = DefaultGeneratedFilePathPattern; if (String.IsNullOrEmpty(pattern)) { pattern = StrategyManager.GetInstance(_currentElement.Store).NamingStrategy. DefaultGeneratedCodeFilePattern; } tmpFileName = String.Format(pattern, tmpFileName); } } tmpFileName = ResolvePattern(element, tmpFileName); // Suppression du '/' de debut if (tmpFileName.Length > 1 && (tmpFileName[0] == Path.AltDirectorySeparatorChar || tmpFileName[0] == Path.DirectorySeparatorChar)) { tmpFileName = tmpFileName.Substring(1); } string pathName = tmpFileName.Replace('/', '\\'); if (pathName.Length > 0 && pathName[0] == '\\') { pathName = pathName.Substring(1); } // Permet de surcharger pathName = CreateRelativeOutputFileName(element, pathName); Debug.Assert(pathName.Length > 0 && pathName[0] != '\\', "the file name must be relatif"); Debug.Assert(Path.HasExtension(pathName), "file name must have an extension"); Debug.Assert(pathName.IndexOf('{') < 0, "incorrect file name"); Context.RelativeGeneratedFileName = pathName; return(Context.ProjectFolder != null?Path.Combine(Context.ProjectFolder, pathName) : pathName); }
/// <summary> /// Récupére la liste des stratégies applicables et actives sur un modéle /// </summary> /// <param name="strategiesOwner">The strategies owner.</param> /// <param name="element">Elément concerné ou null pour tous</param> /// <returns></returns> internal static List <StrategyBase> GetStrategies(CandleElement strategiesOwner, ICustomizableElement element) { ILogger logger = ServiceLocator.Instance.GetService <ILogger>(); List <StrategyBase> strategies = new List <StrategyBase>(); if (strategiesOwner == null) { return(strategies); } if (element != null && logger != null) { logger.BeginStep(String.Concat("Get enabled strategies for element ", element.Name, " (id=", element.Id, ")"), LogType.Debug); } foreach (StrategyBase strategy in StrategyManager.GetInstance(strategiesOwner.Store).GetStrategies(strategiesOwner, true)) { if (strategy.IsEnabled) { strategies.Add(strategy); } else if (element != null && logger != null) { logger.Write("GetStrategies", String.Concat("Strategy ", strategy.StrategyId, " ignored because it is disabled"), LogType.Debug); } } if (element != null && logger != null) { logger.EndStep(); } return(strategies); }
/// <summary> /// Relative generated code file name /// </summary> /// <param name="element">Current element</param> /// <param name="fileName">Pre calculate file name</param> /// <returns></returns> protected virtual string CreateRelativeOutputFileName(ICustomizableElement element, string fileName) { return(fileName); }
/// <summary> /// Applique les stratégies d'injection de code /// </summary> /// <param name="projectItem">The project item.</param> /// <param name="element">The element.</param> /// <param name="context">The context.</param> public static void ApplyCodeInjectionStrategies(ProjectItem projectItem, ICustomizableElement element, GenerationContext context) { ILogger logger = ServiceLocator.Instance.GetService <ILogger>(); if (logger != null) { logger.BeginStep("Injection code generation", LogType.Info); logger.Write("Injection code generation", String.Concat("Current element is ", element.Name, " (id=", element.Id, ")"), LogType.Debug); } EnvDTE80.FileCodeModel2 fcm = null; if (projectItem != null) { fcm = projectItem.FileCodeModel as EnvDTE80.FileCodeModel2; if (fcm == null) { if (logger != null) { logger.Write("Injection code generation", "No code model associated with this element - exit", LogType.Debug); logger.EndStep(); } return; } //fcm.BeginBatch(); } try { CodeInjectionContext gc = new CodeInjectionContext(context); List <StrategyBase> strategies = new List <StrategyBase>(); // Execution des stratégies foreach (StrategyBase strategy in element.GetStrategies(false)) { if (!(strategy is IStrategyCodeInjector)) { continue; } if (logger != null) { logger.Write("Injection code generation", String.Concat("Strategy ", strategy.StrategyId), LogType.Debug); } if (context.SelectedStrategies != null && (context.SelectedStrategies != null && !context.SelectedStrategies.Contains(strategy))) { if (logger != null) { logger.Write("Injection code generation", "Strategy skipped because this is not a selected strategy", LogType.Debug); } continue; } strategies.Add(strategy); } // Tri dans l'ordre d'exécution // strategies.Sort(delegate(IStrategyCodeInjector a, IStrategyCodeInjector b) { return a.ExecutionOrder.CompareTo(b.ExecutionOrder); }); foreach (StrategyBase injector in strategies) { if (logger != null) { logger.BeginStep(String.Concat("Run strategy ", injector.DisplayName, " id=", injector.StrategyId), LogType.Debug); } gc.CurrentElement = element; gc.Strategy = (IStrategyCodeInjector)injector; try { if (gc.GenerationContext.GenerationPass == GenerationPass.MetaModelUpdate) { ((IStrategyCodeInjector)injector).OnMetaModelUpdate(gc); } else { CodeModelWalker walker = new CodeModelWalker(new CodeInjectorVisitor(gc)); walker.Traverse(fcm); } } catch (Exception ex) { if (logger != null) { logger.WriteError(injector.DisplayName, "Code Injection error", ex); } } finally { gc.Strategy = null; gc.CurrentElement = null; if (logger != null) { logger.EndStep(); } } } } finally { if (fcm != null) { // fcm.EndBatch(); // fcm.Synchronize(); } } if (logger != null) { logger.EndStep(); } }
/// <summary> /// Initializes a new instance of the <see cref="DependencyPropertyDescriptor<T>"/> class. /// </summary> /// <param name="model">The model.</param> /// <param name="propertyConfiguration">The property configuration.</param> public DependencyPropertyDescriptor(ICustomizableElement model, DependencyProperty <T> propertyConfiguration) : base(propertyConfiguration.Name, propertyConfiguration.Attributes.ToArray()) { _ownerModel = model; _propertyConfiguration = propertyConfiguration; }
/// <summary> /// Résolution du nom du fichier en remplacçant les mots-clés par leurs valeurs courantes. /// </summary> /// <param name="element">Element concerné par la génération</param> /// <param name="filePattern">Pattern du nom de fichier</param> /// <returns>Chaine résolue</returns> /// <remarks> /// Pattern dans le nom du fichier /// '~' : indique de mettre le fichier tel quel à la racine /// [codeFolder]|[code] : Répertoire de code (racine ou app_code) /// [namespace]|[nspc] : namespace hierarchie /// [strategyName]|[sn] : Nom de la strategie /// ex : [codeFolder]/[namespace]/xxx.cs /// </remarks> /// <exception cref="Exception">Erreur de syntaxe dans le pattern</exception> private string ResolvePattern(ICustomizableElement element, string filePattern) { // Pour que le replace marche dans tous les cas, on va d'abord parcourir la chaine // pour mettre tous les mot-clés en minuscules sans toucher aux autres caractères. char[] buffer = filePattern.ToCharArray(); bool inKeyword = false; for (int i = 0; i < buffer.Length; i++) { char ch = buffer[i]; if (ch == ']') { if (!inKeyword) { throw new Exception( String.Format("Syntax error in the generated file pattern '{1}' for element {0}", element.Name, filePattern)); } inKeyword = false; } else if (ch == '[') { if (inKeyword) { throw new Exception( String.Format("Syntax error in the generated file pattern '{1}' for element {0}", element.Name, filePattern)); } inKeyword = true; } else if (inKeyword) { buffer[i] = Char.ToLower(ch); } } if (inKeyword) { throw new Exception( String.Format("Syntax error in the generated file pattern '{1}' for element {0}", element.Name, filePattern)); } // Remplacement des mots-clés string tmpFileName = new String(buffer); tmpFileName = tmpFileName.Replace("[code]", "[codefolder]"); tmpFileName = tmpFileName.Replace("[sn]", "[strategyname]"); tmpFileName = tmpFileName.Replace("[nspc]", "[namespace]"); tmpFileName = tmpFileName.Replace("[codefolder]", Context.RelativeProjectCodeFolder); tmpFileName = tmpFileName.Replace("[strategyname]", DisplayName); if (tmpFileName.Contains("[namespace]")) { // Arborescence correspondant au namespace string ns = String.Empty; if (element != null) { ClassNameInfo cni = new ClassNameInfo(element.FullName); ns = cni.Namespace.Replace('.', Path.DirectorySeparatorChar); } tmpFileName = tmpFileName.Replace("[namespace]", ns); } return(tmpFileName); }