private void AddPluginAttributes(OrganizationServiceContext ctx, CodeParser parser, string pluginType) { // Get existing Steps var steps = ServiceLocator.Queries.GetPluginSteps(ctx, pluginType); // Check that there are no duplicates var duplicateNames = steps.GroupBy(s => s.Name).SelectMany(grp => grp.Skip(1)); if (duplicateNames.Count() > 0) { throw new SparkleTaskException(SparkleTaskException.ExceptionTypes.DUPLICATE_STEP, String.Format("More than one step found with the same name for plugin type {0} - {1}", pluginType, string.Join(",", duplicateNames.Select(a => a.Name)))); } if (steps != null) { _trace.WriteLine("Found Plugin Type Registration {0}", pluginType); // Get the steps foreach (var step in steps) { SdkMessageFilter filter = null; // If there is an entity filter then get it if (step.SdkMessageFilterId != null) { filter = ServiceLocator.Queries.GetMessageFilter(ctx, step.SdkMessageFilterId.Id); } // Get the images List <SdkMessageProcessingStepImage> images = ServiceLocator.Queries.GetPluginStepImages(ctx, step); // Only support two images - Why would you need more?! if (images.Count > 2) { throw new Exception(String.Format("More than 2 images found on step {0}", step.Name)); } // Create attribute CrmPluginRegistrationAttribute attribute; if (step.Stage == sdkmessageprocessingstep_stage.MainOperation_Forinternaluseonly) { // Custom API - output message name only attribute = new CrmPluginRegistrationAttribute( step.sdkmessageid_sdkmessageprocessingstep.Name ); } else { // Plugin Step // we output the ID so that we can be independant of name - but it's not neededed for new attributes attribute = new CrmPluginRegistrationAttribute( step.sdkmessageid_sdkmessageprocessingstep.Name, filter == null ? "none" : filter.PrimaryObjectTypeCode, (StageEnum)Enum.ToObject(typeof(StageEnum), step.Stage.Value), step.Mode.Value == 0 ? ExecutionModeEnum.Synchronous : ExecutionModeEnum.Asynchronous, step.FilteringAttributes, step.Name, step.Rank.HasValue ? step.Rank.Value : 1, step.plugintypeid_sdkmessageprocessingstep.pluginassembly_plugintype.IsolationMode == pluginassembly_isolationmode.Sandbox ? IsolationModeEnum.Sandbox : IsolationModeEnum.None ) { Id = step.Id.ToString(), DeleteAsyncOperation = step.Mode.Value != 0 && step.AsyncAutoDelete.Value, }; } // Image 1 if (images.Count >= 1) { var image = images[0]; attribute.Image1Type = (ImageTypeEnum)Enum.ToObject(typeof(ImageTypeEnum), image.ImageType.Value); attribute.Image1Name = image.EntityAlias; attribute.Image1Attributes = image.Attributes1; } // Image 2 if (images.Count >= 2) { var image = images[1]; attribute.Image2Type = (ImageTypeEnum)Enum.ToObject(typeof(ImageTypeEnum), image.ImageType.Value); attribute.Image2Name = image.EntityAlias; attribute.Image2Attributes = image.Attributes1; } // Add config if (step.Configuration != null) { attribute.UnSecureConfiguration = step.Configuration; } if (step.Description != null) { attribute.Description = step.Description; } // Add attribute to code parser.AddAttribute(attribute, step.plugintypeid_sdkmessageprocessingstep.TypeName); } } }
protected override void ExecuteInternal(string filePath, OrganizationServiceContext ctx) { _trace.WriteLine("Searching for classes in '{0}'", filePath); var targetFolder = new DirectoryInfo(filePath); var matches = ServiceLocator.DirectoryService.Search(filePath, "*.cs"); if (matches == null) { return; } var pluginRegistration = new PluginRegistraton(_service, ctx, _trace); int codeFilesUpdated = 0; // Create a spkl.json file here (or load an existing one) var files = ServiceLocator.ConfigFileFactory.FindConfig(filePath, false); var file = files[0]; foreach (var codeFile in matches) { try { string customClassRegex = null; // Support for custom base class regex var profile = file.GetPluginsConfig(this.Profile); if (profile != null && profile.Length > 0 && !String.IsNullOrEmpty(profile[0].classRegex)) { customClassRegex = profile[0].classRegex; } // Find if it contains any plugin/workflow classes CodeParser parser = new CodeParser(new Uri(codeFile), customClassRegex); if (parser.PluginCount > 0) { // Backup File.WriteAllText(parser.FilePath + DateTime.Now.ToString("yyyyMMddHHmmss") + ".bak", parser.Code, parser.CurEncoding); foreach (var pluginType in parser.ClassNames) { // Remove existing attributes parser.RemoveExistingAttributes(); if (parser.IsPlugin(pluginType)) { AddPluginAttributes(ctx, parser, pluginType); } else if (parser.IsWorkflowActivity(pluginType)) { AddWorkflowActivityAttributes(ctx, parser, pluginType); } else { _trace.WriteLine("Cannot find Type Registration {0}", pluginType); } } // Update File.WriteAllText(parser.FilePath, parser.Code, parser.CurEncoding); codeFilesUpdated++; } } catch (ReflectionTypeLoadException ex) { throw new Exception(ex.LoaderExceptions.First().Message); } } _trace.WriteLine("{0} classes decorated with deployment attributes!", codeFilesUpdated); if (file.plugins == null) { file.plugins = new List <PluginDeployConfig>(); } if (file.plugins.Where(a => a.assemblypath == @"bin\Debug").FirstOrDefault() == null) { file.plugins.Add(new PluginDeployConfig() { assemblypath = @"bin\Debug" }); } file.filePath = filePath; file.Save(); }
protected override void ExecuteInternal(string filePath, OrganizationServiceContext ctx) { _trace.WriteLine("Searching for plugin classes in '{0}'", filePath); var targetFolder = new DirectoryInfo(filePath); var matches = DirectoryEx.Search(filePath, "*.cs", null); if (matches == null) { return; } var pluginRegistration = new PluginRegistraton(_service, ctx, _trace); int codeFilesUpdated = 0; foreach (var codeFile in matches) { try { // Find if it contains any IPlugin files CodeParser parser = new CodeParser(new Uri(codeFile)); if (parser.PluginCount > 0) { // Backup File.WriteAllText(parser.FilePath + DateTime.Now.ToString("yyyyMMddHHmmss") + ".bak", parser.Code); foreach (var pluginType in parser.ClassNames) { // Remove existing attributes parser.RemoveExistingAttributes(); if (parser.IsPlugin(pluginType)) { AddPluginAttributes(ctx, parser, pluginType); } else if (parser.IsWorkflowActivity(pluginType)) { AddWorkflowActivityAttributes(ctx, parser, pluginType); } else { _trace.WriteLine("Cannot find Plugin Type Registration {0}", pluginType); } } // Update File.WriteAllText(parser.FilePath, parser.Code); codeFilesUpdated++; } } catch (ReflectionTypeLoadException ex) { throw new Exception(ex.LoaderExceptions.First().Message); } } _trace.WriteLine("{0} plugins decorated with deployment attributes!", codeFilesUpdated); // Create a spkl.json file here var files = ConfigFile.FindConfig(filePath, false); var file = files[0]; if (file.plugins == null) { file.plugins = new List <PluginDeployConfig>(); } if (file.plugins.Where(a => a.assemblypath == @"bin\Debug").FirstOrDefault() == null) { file.plugins.Add(new PluginDeployConfig() { assemblypath = @"bin\Debug" }); } file.filePath = filePath; file.Save(); }