private List <TemplateManifestItem> ProcessCore(List <ManifestItem> items, DocumentBuildContext context, ApplyTemplateSettings settings, IDictionary <string, object> globals) { var manifest = new ConcurrentBag <TemplateManifestItem>(); var systemAttributeGenerator = new SystemMetadataGenerator(context); var transformer = new TemplateModelTransformer(context, _templateCollection, settings, globals); items.RunAll( item => { var manifestItem = transformer.Transform(item); if (manifestItem.OutputFiles?.Count > 0) { manifest.Add(manifestItem); } }, context.MaxParallelism); var itemsToRemove = new List <string>(); foreach (var duplicates in from m in manifest from output in m.OutputFiles.Values group m.OriginalFile by output into g where g.Count() > 1 select g) { Logger.LogWarning($"Overwrite occurs while input files \"{string.Join(", ", duplicates)}\" writing to the same output file \"{duplicates.Key}\""); itemsToRemove.AddRange(duplicates.Skip(1)); } return(manifest.Where(m => !itemsToRemove.Contains(m.OriginalFile)).ToList()); }
public TemplateModelTransformer(DocumentBuildContext context, TemplateCollection templateCollection, ApplyTemplateSettings settings, IDictionary <string, object> globals) { if (context == null) { throw new ArgumentNullException(nameof(context)); } _context = context; _templateCollection = templateCollection; _settings = settings; _globalVariables = globals; _systemMetadataGenerator = new SystemMetadataGenerator(context); }
public TemplateModelTransformer(DocumentBuildContext context, TemplateCollection templateCollection, ApplyTemplateSettings settings, IDictionary<string, object> globals) { if (context == null) { throw new ArgumentNullException(nameof(context)); } _context = context; _templateCollection = templateCollection; _settings = settings; _globalVariables = globals; _systemMetadataGenerator = new SystemMetadataGenerator(context); }
private void ApplySystemMetadata() { Logger.LogVerbose("Applying system metadata to manifest..."); // Add system attributes var systemMetadataGenerator = new SystemMetadataGenerator(_context); var sharedObjects = new ConcurrentDictionary <string, object>(); _manifestWithContext.RunAll(m => { if (m.FileModel.Type == DocumentType.Resource) { return; } using (new LoggerFileScope(m.FileModel.LocalPathFromRoot)) { Logger.LogDiagnostic("Generating system metadata..."); // TODO: use weak type for system attributes from the beginning var systemAttrs = systemMetadataGenerator.Generate(m.Item); var metadata = (IDictionary <string, object>)ConvertToObjectHelper.ConvertStrongTypeToObject(systemAttrs); var model = (IDictionary <string, object>)m.Item.Model.Content; foreach (var pair in metadata) { if (!model.ContainsKey(pair.Key)) { model[pair.Key] = pair.Value; } } Logger.LogDiagnostic($"Load shared model from template for {m.Item.DocumentType}..."); if (m.Options?.IsShared == true) { // Take a snapshot of current model as shared object sharedObjects[m.Item.Key] = new Dictionary <string, object>(model); } } }, _context.MaxParallelism); _globalMetadata["_shared"] = sharedObjects; }
private List <ManifestItem> ProcessCore(List <InternalManifestItem> items, DocumentBuildContext context, ApplyTemplateSettings settings, IDictionary <string, object> globals) { var manifest = new ConcurrentBag <ManifestItem>(); var systemAttributeGenerator = new SystemMetadataGenerator(context); var transformer = new TemplateModelTransformer(context, _templateCollection, settings, globals); items.RunAll( item => { var manifestItem = transformer.Transform(item); if (manifestItem.OutputFiles?.Count > 0) { manifest.Add(manifestItem); } }, context.MaxParallelism); return(manifest.ToList()); }
private void ApplySystemMetadata() { Logger.LogVerbose("Applying system metadata to manifest..."); // Add system attributes var systemMetadataGenerator = new SystemMetadataGenerator(_context); _manifestWithContext.RunAll(m => { if (m.FileModel.Type == DocumentType.Resource) { return; } using (new LoggerFileScope(m.FileModel.LocalPathFromRoot)) { Logger.LogDiagnostic("Generating system metadata..."); // TODO: use weak type for system attributes from the beginning var systemAttrs = systemMetadataGenerator.Generate(m.Item); var metadata = (JObject)ConvertToObjectHelper.ConvertStrongTypeToJObject(systemAttrs); // Change file model to weak type var model = m.Item.Model.Content; var modelAsObject = (JToken)ConvertToObjectHelper.ConvertStrongTypeToJObject(model); if (modelAsObject is JObject) { foreach (var pair in (JObject)modelAsObject) { // Overwrites the existing system metadata if the same key is defined in document model metadata[pair.Key] = pair.Value; } } else { Logger.LogWarning("Input model is not an Object model, it will be wrapped into an Object model. Please use --exportRawModel to view the wrapped model"); metadata["model"] = modelAsObject; } // Append system metadata to model m.Item.Model.Serializer = null; m.Item.Model.Content = metadata; } }, _context.MaxParallelism); }
private void ApplySystemMetadata(List <ManifestItemWithContext> manifest, IDocumentBuildContext context) { Logger.LogVerbose($"Applying system metadata to manifest..."); // Add system attributes var systemMetadataGenerator = new SystemMetadataGenerator(context); manifest.RunAll(m => { using (new LoggerFileScope(m.FileModel.LocalPathFromRepoRoot)) { Logger.LogVerbose($"Generating system metadata..."); // TODO: use weak type for system attributes from the beginning var systemAttrs = systemMetadataGenerator.Generate(m.Item); var metadata = (IDictionary <string, object>)ConvertToObjectHelper.ConvertStrongTypeToObject(systemAttrs); // Change file model to weak type var model = m.Item.Model.Content; var modelAsObject = ConvertToObjectHelper.ConvertStrongTypeToObject(model) as IDictionary <string, object>; if (modelAsObject != null) { foreach (var token in modelAsObject) { // Overwrites the existing system metadata if the same key is defined in document model metadata[token.Key] = token.Value; } } else { Logger.LogWarning("Input model is not an Object model, it will be wrapped into an Object model. Please use --exportRawModel to view the wrapped model"); metadata["model"] = model; } // Append system metadata to model m.Item.Model.Content = metadata; } }); }
public List <TemplateManifestItem> Transform(List <ManifestItem> items, DocumentBuildContext context, ApplyTemplateSettings settings) { var documentTypes = items.Select(s => s.DocumentType).Distinct().Where(s => s != "Resource" && Templates[s] == null); if (documentTypes.Any()) { Logger.LogWarning($"There is no template processing document type(s): {documentTypes.ToDelimitedString()}"); } var manifest = new ConcurrentBag <TemplateManifestItem>(); var systemAttributeGenerator = new SystemMetadataGenerator(context); items.RunAll( item => { var manifestItem = TransformItem(item, context, settings, systemAttributeGenerator); if (manifestItem != null) { manifest.Add(manifestItem); } }, context.MaxParallelism); // todo : set parallelism. return(manifest.ToList()); }
private List<ManifestItem> ProcessCore(List<InternalManifestItem> items, DocumentBuildContext context, ApplyTemplateSettings settings, IDictionary<string, object> globals) { var manifest = new ConcurrentBag<ManifestItem>(); var systemAttributeGenerator = new SystemMetadataGenerator(context); var transformer = new TemplateModelTransformer(context, _templateCollection, settings, globals); items.RunAll( item => { using (new LoggerFileScope(item.LocalPathFromRoot)) { var manifestItem = transformer.Transform(item); if (manifestItem.OutputFiles?.Count > 0) { manifest.Add(manifestItem); } } }, context.MaxParallelism); return manifest.ToList(); }
private void ApplySystemMetadata(List<ManifestItemWithContext> manifest, IDocumentBuildContext context) { Logger.LogVerbose("Applying system metadata to manifest..."); // Add system attributes var systemMetadataGenerator = new SystemMetadataGenerator(context); manifest.RunAll(m => { using (new LoggerFileScope(m.FileModel.LocalPathFromRoot)) { Logger.LogDiagnostic("Generating system metadata..."); // TODO: use weak type for system attributes from the beginning var systemAttrs = systemMetadataGenerator.Generate(m.Item); var metadata = (IDictionary<string, object>)ConvertToObjectHelper.ConvertStrongTypeToObject(systemAttrs); // Change file model to weak type var model = m.Item.Model.Content; var modelAsObject = ConvertToObjectHelper.ConvertStrongTypeToObject(model) as IDictionary<string, object>; if (modelAsObject != null) { foreach (var token in modelAsObject) { // Overwrites the existing system metadata if the same key is defined in document model metadata[token.Key] = token.Value; } } else { Logger.LogWarning("Input model is not an Object model, it will be wrapped into an Object model. Please use --exportRawModel to view the wrapped model"); metadata["model"] = model; } // Append system metadata to model m.Item.Model.Content = metadata; } }); }
private TemplateManifestItem TransformItem(ManifestItem item, IDocumentBuildContext context, ApplyTemplateSettings settings, SystemMetadataGenerator systemAttributeGenerator) { if (settings.Options.HasFlag(ApplyTemplateOptions.ExportRawModel)) { ExportModel(item.Model.Content, item.ModelFile, settings.RawModelExportSettings); } if (item.Model == null || item.Model.Content == null) { throw new ArgumentNullException("Content for item.Model should not be null!"); } var manifestItem = new TemplateManifestItem { DocumentType = item.DocumentType, OriginalFile = item.LocalPathFromRepoRoot, OutputFiles = new Dictionary <string, string>() }; var outputDirectory = settings.OutputFolder ?? Environment.CurrentDirectory; if (!IsEmpty) { HashSet <string> missingUids = new HashSet <string>(); // Must convert to JObject first as we leverage JsonProperty as the property name for the model var model = ConvertToObjectHelper.ConvertStrongTypeToJObject(item.Model.Content); var templates = Templates[item.DocumentType]; // 1. process model if (templates != null) { var systemAttrs = systemAttributeGenerator.Generate(item); foreach (var template in templates) { var extension = template.Extension; string outputFile = Path.ChangeExtension(item.ModelFile, extension); string outputPath = Path.Combine(outputDirectory, outputFile); var dir = Path.GetDirectoryName(outputPath); if (!string.IsNullOrEmpty(dir)) { Directory.CreateDirectory(dir); } object viewModel = null; try { viewModel = template.TransformModel(model, systemAttrs, _global); } catch (Exception e) { // save raw model for further investigation: var exportSettings = ApplyTemplateSettings.RawModelExportSettingsForDebug; var rawModelPath = ExportModel(model, item.ModelFile, exportSettings); throw new DocumentException($"Error transforming model \"{rawModelPath}\" generated from \"{item.LocalPathFromRepoRoot}\" using \"{template.ScriptName}\": {e.Message}"); } string result; try { result = template.Transform(viewModel); } catch (Exception e) { // save view model for further investigation: var exportSettings = ApplyTemplateSettings.ViewModelExportSettingsForDebug; var viewModelPath = ExportModel(viewModel, outputFile, exportSettings); throw new DocumentException($"Error applying template \"{template.Name}\" to view model \"{viewModelPath}\" generated from \"{item.LocalPathFromRepoRoot}\": {e.Message}"); } if (settings.Options.HasFlag(ApplyTemplateOptions.ExportViewModel)) { ExportModel(viewModel, outputFile, settings.ViewModelExportSettings); } if (settings.Options.HasFlag(ApplyTemplateOptions.TransformDocument)) { if (string.IsNullOrWhiteSpace(result)) { // TODO: WHAT to do if is transformed to empty string? STILL creat empty file? Logger.LogWarning($"Model \"{item.ModelFile}\" is transformed to empty string with template \"{template.Name}\""); File.WriteAllText(outputPath, string.Empty); } else { TransformDocument(result, extension, context, outputPath, item.ModelFile, missingUids); Logger.Log(LogLevel.Verbose, $"Transformed model \"{item.LocalPathFromRepoRoot}\" to \"{outputPath}\"."); } manifestItem.OutputFiles.Add(extension, outputFile); } } } if (missingUids.Count > 0) { var uids = string.Join(", ", missingUids.Select(s => $"\"{s}\"")); Logger.LogWarning($"Unable to resolve cross-reference {uids} for \"{manifestItem.OriginalFile.ToDisplayPath()}\""); } } // 2. process resource if (item.ResourceFile != null) { // Resource file has already been processed in its plugin manifestItem.OutputFiles.Add("resource", item.ResourceFile); } return(manifestItem); }