public bool TryProcess(IDocumentProcessor docProcessor, XmlNode node, bool isRoot, ITemplate template, IRenderFunction currentRenderFunction) { string name = node.Name; if (node.NodeType == XmlNodeType.Element && name == "def-fragment") { if (isRoot) { throw ParserUtils.TemplateErrorException("Fragment definitions must be inside the template."); } ProcessDefFragment(docProcessor, node, template); return(true); } else if (node.NodeType == XmlNodeType.Element && name == "call-fragment") { if (isRoot) { throw ParserUtils.TemplateErrorException("Fragment instantiations must be inside the template."); } currentRenderFunction.AddFragment(ProcessCallFragment(docProcessor, node)); return(true); } else { return(false); } }
private void Save(IDocumentProcessor processor, HostService hostService, DocumentBuildContext context) { hostService.Models.RunAll( m => { try { if (m.Type != DocumentType.Override) { using (new LoggerFileScope(m.OriginalFileAndType.File)) { Logger.LogVerbose($"Plug-in {processor.Name}: Saving..."); m.BaseDir = context.BuildOutputFolder; var result = processor.Save(m); if (result != null) { HandleSaveResult(context, hostService, m, result); } } } } finally { m.Dispose(); } }); }
private bool CanProcessorIncremental(IDocumentProcessor processor, string versionName) { if (!ShouldTraceIncrementalInfo) { return(false); } if (!(processor is ISupportIncrementalBuild) || !processor.BuildSteps.All(step => step is ISupportIncrementalBuild)) { return(false); } var cpi = GetProcessorInfo(processor, versionName); var lpi = LastBuildInfo ?.Versions ?.Find(v => v.VersionName == versionName) ?.Processors ?.Find(p => p.Name == processor.Name); if (lpi == null) { return(false); } if (cpi.IncrementalContextHash != lpi.IncrementalContextHash) { return(false); } return(new HashSet <ProcessorStepInfo>(cpi.Steps).SetEquals(lpi.Steps)); }
private void BuildCore( IDocumentProcessor processor, IEnumerable <FileAndType> files, ImmutableDictionary <string, object> metadata, FileMetadata fileMetadata, DocumentBuildContext context) { Logger.LogInfo($"Plug-in {processor.Name}: Loading document..."); using (var hostService = new HostService( from file in files select Load(processor, metadata, fileMetadata, file))) { hostService.SourceFiles = context.AllSourceFiles; foreach (var m in hostService.Models) { if (m.LocalPathFromRepoRoot == null) { m.LocalPathFromRepoRoot = Path.Combine(m.BaseDir, m.File); } } Logger.LogInfo($"Plug-in {processor.Name}: Document loaded (count = {hostService.Models.Count})."); Logger.LogInfo($"Plug-in {processor.Name}: Preprocessing..."); Prebuild(processor, hostService); Logger.LogInfo($"Plug-in {processor.Name}: Building..."); BuildArticle(processor, hostService); Logger.LogInfo($"Plug-in {processor.Name}: Postprocessing..."); Postbuild(processor, hostService); Logger.LogInfo($"Plug-in {processor.Name}: Saving..."); Save(processor, hostService, context); } }
public bool TryProcess(IDocumentProcessor docProcessor, XmlNode node, bool isRoot, ITemplate template, IRenderFunction currentRenderFunction) { if (node.NodeType != XmlNodeType.ProcessingInstruction) { return(false); } string v = node.Value.Trim(); switch (node.Name) { case "x": if (v == "") { throw ParserUtils.TemplateErrorException("Empty embedded expression"); } currentRenderFunction.AddFragment(new CodeExpressionFragment(v)); return(true); case "c": if (v == "") { throw ParserUtils.TemplateErrorException("Empty embedded code"); } currentRenderFunction.AddFragment(new CodeFragment(v, 0)); return(true); default: return(false); } }
public virtual HostService CreateHostService( DocumentBuildParameters parameters, TemplateProcessor templateProcessor, IMarkdownService markdownService, IEnumerable<IInputMetadataValidator> metadataValidator, IDocumentProcessor processor, IEnumerable<FileAndType> files) { var hostService = new HostService( parameters.Files.DefaultBaseDir, files == null ? new FileModel[0] : from file in files select Load(processor, parameters.Metadata, parameters.FileMetadata, file) into model where model != null select model) { MarkdownService = markdownService, Processor = processor, Template = templateProcessor, Validators = metadataValidator?.ToImmutableList(), ShouldTraceIncrementalInfo = ShouldProcessorTraceInfo(processor), CanIncrementalBuild = CanProcessorIncremental(processor), }; return hostService; }
private void Save(IDocumentProcessor processor, HostService hostService, DocumentBuildContext context) { hostService.Models.RunAll( m => { if (m.Type != DocumentType.Override) { using (new LoggerFileScope(m.OriginalFileAndType.File)) { Logger.LogVerbose($"Plug-in {processor.Name}: Saving..."); m.BaseDir = context.BuildOutputFolder; if (m.PathRewriter != null) { m.File = m.PathRewriter(m.File); } var result = processor.Save(m); if (result != null) { m.File = TemplateProcessor.UpdateFilePath(m.File, result.DocumentType, context.TemplateCollection); result.ModelFile = TemplateProcessor.UpdateFilePath(result.ModelFile, result.DocumentType, context.TemplateCollection); HandleSaveResult(context, hostService, m, result); } } } }); }
public override FileModel Load(IDocumentProcessor processor, ImmutableDictionary<string, object> metadata, FileMetadata fileMetadata, FileAndType file) { using (new LoggerFileScope(file.File)) { if (CanProcessorIncremental(processor)) { ChangeKindWithDependency ck; string fileKey = ((RelativePath)file.File).GetPathFromWorkingFolder().ToString(); if (IncrementalContext.ChangeDict.TryGetValue(fileKey, out ck)) { Logger.LogDiagnostic($"Processor {processor.Name}, File {file.FullPath}, ChangeType {ck}."); if (ck == ChangeKindWithDependency.Deleted) { return null; } if (ck == ChangeKindWithDependency.None) { Logger.LogDiagnostic($"Processor {processor.Name}, File {file.FullPath}: Check incremental..."); if (processor.BuildSteps.Cast<ISupportIncrementalBuildStep>().All(step => step.CanIncrementalBuild(file))) { Logger.LogDiagnostic($"Processor {processor.Name}, File {file.FullPath}: Skip build by incremental."); return null; } Logger.LogDiagnostic($"Processor {processor.Name}, File {file.FullPath}: Incremental not available."); } } } return base.Load(processor, metadata, fileMetadata, file); } }
private ProcessorInfo GetProcessorInfo(IDocumentProcessor processor, string versionName) { var cpi = new ProcessorInfo { Name = processor.Name, IncrementalContextHash = ((ISupportIncrementalBuild)processor).GetIncrementalContextHash(), }; foreach (var step in processor.BuildSteps) { cpi.Steps.Add(new ProcessorStepInfo { Name = step.Name, IncrementalContextHash = ((ISupportIncrementalBuild)step).GetIncrementalContextHash(), }); } var cvi = CurrentBuildInfo.Versions.Find(v => v.VersionName == versionName); if (cvi == null) { cvi = new BuildVersionInfo { VersionName = versionName }; CurrentBuildInfo.Versions.Add(cvi); } cvi.Processors.Add(cpi); return(cpi); }
/// <summary> /// Based on a supplied input stream, this method parses the data and constructs /// a new pipeline. /// </summary> /// <param name="sourceStream">The source stream to read from</param> /// <returns>The new pipeline of processors</returns> public IDocumentProcessorPipeline Parse(Stream sourceStream) { XDocument document = XDocument.Load(sourceStream); XElement root = document.Root; Precondition.Assert(() => root != null, "No root element found in XML data"); // ReSharper disable once PossibleNullReferenceException XElement processorsRootElement = root.Element("processors"); var pipeline = new DocumentProcessorPipeline(); if (processorsRootElement != null) { this.Variables = new VariableProvider(root.Element("variables")); var processorElements = processorsRootElement.Elements("processor"); foreach (var processorElement in processorElements) { IDocumentProcessor processor = LoadProcessorFromConfig(this.Variables, processorElement); if (processor != null) { pipeline.AddProcessor(processor); } } } return(pipeline); }
public virtual (FileModel model, bool valid) Load( IDocumentProcessor processor, ImmutableDictionary <string, object> metadata, FileMetadata fileMetadata, FileAndType file) { using (new LoggerFileScope(file.File)) { Logger.LogDiagnostic($"Processor {processor.Name}, File {file.FullPath}: Loading..."); var fileMeta = NeedApplyMetadata() ? ApplyFileMetadata(file.FullPath, metadata, fileMetadata) : ImmutableDictionary <string, object> .Empty; try { return(processor.Load(file, fileMeta), true); } catch (Exception e) { if (!(e is DocumentException)) { Logger.LogError( $"Unable to load file '{file.File}' via processor '{processor.Name}': {e.Message}", code: ErrorCodes.Build.InvalidInputFile); } return(null, false); } } bool NeedApplyMetadata() { return(file.Type != DocumentType.Resource); } }
public bool TryProcess(IDocumentProcessor docProcessor, XmlNode node, bool isRoot, ITemplate template, IRenderFunction currentRenderFunction) { if (node.NodeType != XmlNodeType.ProcessingInstruction || node.Name != "view") return false; if (!isRoot) throw ParserUtils.TemplateErrorException(string.Format("The view directive can only appear outside of the template.", node.Name)); string[] serverTypeArr = Utils.RegexExec(node.Value, "modelType=\"([^\"]*)\"", ""); string[] clientTypeArr = Utils.RegexExec(node.Value, "clientModelType=\"([^\"]*)\"", ""); if (serverTypeArr == null && clientTypeArr != null) throw ParserUtils.TemplateErrorException("You cannot specify a client type for the model if you don't specify a server type"); if (template.HasMember("Model") || template.HasMember("model") || template.HasMember("Saltarelle.Mvc.IView.Model")) throw ParserUtils.TemplateErrorException("The template already defines at least one of the members essential to use the view directive. Have you specified <?view?> more than once?"); string serverType = (serverTypeArr != null ? serverTypeArr[1] : "object"), clientType = (clientTypeArr != null ? clientTypeArr[1] : null); string viewInterface = "Saltarelle.Mvc.IView<" + serverType + ">"; if (template.ImplementsServerInterface(viewInterface)) throw ParserUtils.TemplateErrorException("The template already implements the interface " + viewInterface + "."); template.AddServerInterface(viewInterface); template.AddMember(new FieldMember("model", serverType, clientType)); template.AddMember(new PropertyMember("Model", serverType, null, AccessModifier._Public, "model", serverType, null, true, true, "ModelChanged", false)); template.AddMember(new PropertyMember("Saltarelle.Mvc.IView.Model", "object", null, AccessModifier._None, "model", serverType, null, true, true, "ModelChanged", false)); return true; }
internal static void ProcessDefFragment(IDocumentProcessor docProcessor, XmlNode node, ITemplate template) { XmlAttribute nameAttr = (XmlAttribute)node.Attributes.GetNamedItem("name"); XmlAttribute paramsAttr = (XmlAttribute)node.Attributes.GetNamedItem("params"); if (nameAttr == null) { throw ParserUtils.TemplateErrorException("The <def-fragment> element must have the name attribute specified."); } string name = nameAttr.Value; if (!ParserUtils.IsValidUnqualifiedName(name)) { throw ParserUtils.TemplateErrorException("The name " + name + " is not a valid unqualified identifier."); } if (template.HasMember(name)) { throw ParserUtils.TemplateErrorException("Duplicate definition of member " + name + "."); } RenderFunctionMember m = new RenderFunctionMember(nameAttr.Value, paramsAttr != null ? paramsAttr.Value : ""); Utils.DoForEachChild(node, delegate(XmlNode n) { docProcessor.ProcessRecursive(n, template, m); }); if (template.HasMember(name)) { throw ParserUtils.TemplateErrorException("Duplicate definition of member " + name + "."); // Just in case it has already been added during the recursive call. } template.AddMember(m); }
public override (FileModel model, bool valid) Load( IDocumentProcessor processor, ImmutableDictionary <string, object> metadata, FileMetadata fileMetadata, FileAndType file) { using (new LoggerFileScope(file.File)) { if (CanProcessorIncremental(processor)) { string fileKey = ((RelativePath)file.File).GetPathFromWorkingFolder().ToString(); if (IncrementalContext.ChangeDict.TryGetValue(fileKey, out ChangeKindWithDependency ck)) { Logger.LogDiagnostic($"Processor {processor.Name}, File {file.FullPath}, ChangeType {ck}."); if (ck == ChangeKindWithDependency.Deleted) { return(null, true); } if (ck == ChangeKindWithDependency.None) { Logger.LogDiagnostic($"Processor {processor.Name}, File {file.FullPath}: Check incremental..."); if (processor.BuildSteps.Cast <ISupportIncrementalBuildStep>().All(step => step.CanIncrementalBuild(file))) { Logger.LogDiagnostic($"Processor {processor.Name}, File {file.FullPath}: Skip build by incremental."); return(null, true); } Logger.LogDiagnostic($"Processor {processor.Name}, File {file.FullPath}: Incremental not available."); } } } return(base.Load(processor, metadata, fileMetadata, file)); } }
public virtual (FileModel model, bool valid) Load( IDocumentProcessor processor, ImmutableDictionary <string, object> metadata, FileMetadata fileMetadata, FileAndType file) { using (new LoggerFileScope(file.File)) { Logger.LogDiagnostic($"Processor {processor.Name}, File {file.FullPath}: Loading..."); var path = Path.Combine(file.BaseDir, file.File); metadata = ApplyFileMetadata(path, metadata, fileMetadata); try { return(processor.Load(file, metadata), true); } catch (Exception e) { Logger.LogError( $"Unable to load file: {file.File} via processor: {processor.Name}: {e.Message}", code: ErrorCodes.Build.InvalidInputFile); return(null, false); } } }
internal static void AddAttributeFragments(IDocumentProcessor docProcessor, XmlNode node, bool isRoot, ITemplate template, IRenderFunction fragments, GenericElementProcessorContext context) { bool hasStyle = false; Utils.DoForEachAttribute(node, delegate(XmlAttribute attr) { AddSingleAttributeFragments(docProcessor, attr.Name, attr.Value, isRoot, template, fragments, context); if (attr.Name == "style") { hasStyle = true; } }); if (isRoot) { fragments.AddFragment(new LiteralFragment(" id=\"")); fragments.AddFragment(new IdFragment()); fragments.AddFragment(new LiteralFragment("\"")); if (!hasStyle) { fragments.AddFragment(new LiteralFragment(" style=\"")); fragments.AddFragment(new PositionFragment()); fragments.AddFragment(new LiteralFragment("\"")); } } }
public LocalFileRepositoryTests() { var repo = new FileRepository(BASE_FOLDER); mappingProcessor = new MappingProcessor(repo); docProcessor = new DocumentProcessor(repo, null); }
public ManifestItemWithContext(ManifestItem item, FileModel model, IDocumentProcessor processor, TemplateBundle bundle) { Item = item; FileModel = model; Processor = processor; TemplateBundle = bundle; }
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env , IDocumentProcessor documentProcessor, IDocumentationSiteGenerator siteGenerator) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseStaticFiles(); //app.UseFileServer(); app.Run(async(context) => { siteGenerator.GenerateSite(); if (injectionState.Diagnostics.HasWarnings) { await context.Response.WriteAsync(injectionState.Diagnostics.ToString()); return; } (string document, string fragment) = GetRouteFromRequest(context.Request.Path.Value); string str = documentProcessor.ProcessDocument( document, fragment); await context.Response.WriteAsync(str); }); }
public virtual HostService CreateHostService( DocumentBuildParameters parameters, TemplateProcessor templateProcessor, IMarkdownService markdownService, IEnumerable <IInputMetadataValidator> metadataValidator, IDocumentProcessor processor, IEnumerable <FileAndType> files) { var hostService = new HostService( parameters.Files.DefaultBaseDir, files == null ? Enumerable.Empty <FileModel>() : from file in files select Load(processor, parameters.Metadata, parameters.FileMetadata, file) into model where model != null select model, parameters.VersionName, parameters.VersionDir, parameters.LruSize, parameters.GroupInfo) { MarkdownService = markdownService, Processor = processor, Template = templateProcessor, Validators = metadataValidator?.ToImmutableList(), ShouldTraceIncrementalInfo = ShouldProcessorTraceInfo(processor), CanIncrementalBuild = CanProcessorIncremental(processor), }; return(hostService); }
public virtual HostService CreateHostService( DocumentBuildParameters parameters, TemplateProcessor templateProcessor, IMarkdownService markdownService, IEnumerable <IInputMetadataValidator> metadataValidator, IDocumentProcessor processor, IEnumerable <FileAndType> files) { var(models, invalidFiles) = LoadModels(files, parameters, processor); var hostService = new HostService( parameters.Files.DefaultBaseDir, models, parameters.VersionName, parameters.VersionDir, parameters.LruSize, parameters.GroupInfo, new BuildParameters(parameters.TagParameters)) { MarkdownService = markdownService, Processor = processor, Template = templateProcessor, Validators = metadataValidator?.ToImmutableList(), ShouldTraceIncrementalInfo = ShouldProcessorTraceInfo(processor), CanIncrementalBuild = CanProcessorIncremental(processor), InvalidSourceFiles = invalidFiles.ToImmutableList(), }; return(hostService); }
public bool TryProcess(IDocumentProcessor docProcessor, XmlNode node, bool isRoot, ITemplate template, IRenderFunction currentRenderFunction) { if (node.NodeType != XmlNodeType.Element) return false; GenericElementProcessorContext context = new GenericElementProcessorContext(); currentRenderFunction.AddFragment(new LiteralFragment("<" + node.Name)); AddAttributeFragments(docProcessor, node, isRoot, template, currentRenderFunction, context); if (context.Id != null) { string tagName = node.Name; if (tagName.ToLowerCase() == "input" && context.Type != null) tagName += "/" + context.Type; template.AddMember(new NamedElementMember(tagName, context.Id)); } if (noContentTags.Contains(node.Name)) { if (Utils.GetNumChildNodes(node) > 0) throw ParserUtils.TemplateErrorException("The tag " + node.Name + " can not have children."); currentRenderFunction.AddFragment(new LiteralFragment("/>")); } else { currentRenderFunction.AddFragment(new LiteralFragment(">")); Utils.DoForEachChild(node, delegate(XmlNode child) { docProcessor.ProcessRecursive(child, template, currentRenderFunction); }); currentRenderFunction.AddFragment(new LiteralFragment("</" + node.Name + ">")); } return true; }
internal static void AddSingleAttributeFragments(IDocumentProcessor docProcessor, string attrName, string attrValue, bool isRoot, ITemplate template, IRenderFunction fragments, GenericElementProcessorContext context) { string actualName; if (attrName == "actualName") { // This will translate into "name", but not with our ID prefixed. We need this because for top-level templates we want the names undisturbed to allow for a nice form submission. // However, for nested forms which we won't submit using the normal techniques, we need to prefix it in order to make radio buttons work reliably. actualName = "name"; } else { actualName = attrName; } fragments.AddFragment(new LiteralFragment(" " + actualName + "=\"")); if (attrName == "id") { if (isRoot) { throw ParserUtils.TemplateErrorException("Can't specify an ID for the top level element."); } if (template.HasMember(attrValue)) { throw ParserUtils.TemplateErrorException("Duplicate member " + attrValue); } context.Id = attrValue; fragments.AddFragment(new IdFragment()); fragments.AddFragment(new LiteralFragment("_" + attrValue)); } else if (attrName.ToLowerCase() == "for" || attrName.ToLowerCase() == "name") { fragments.AddFragment(new IdFragment()); fragments.AddFragment(new LiteralFragment("_" + attrValue)); } else { IFragment f = docProcessor.ParseUntypedMarkup(attrValue); fragments.AddFragment(f); if (attrName.ToLowerCase() == "type") { if (f is LiteralFragment) { context.Type = ((LiteralFragment)f).Text; } } else if (isRoot && attrName.ToLowerCase() == "style") { if (!(f is LiteralFragment) || !((LiteralFragment)f).Text.Trim().EndsWith(";")) { fragments.AddFragment(new LiteralFragment(";")); } fragments.AddFragment(new PositionFragment()); } } fragments.AddFragment(new LiteralFragment("\"")); }
public virtual void SetupRepo() { mocks = new MockRepository(); template = mocks.StrictMock<ITemplate>(); docProcessor = mocks.StrictMock<IDocumentProcessor>(); renderFunction = mocks.StrictMock<IRenderFunction>(); fragments = new List<IFragment>(); Expect.Call(() => renderFunction.AddFragment(null)).Do((Action<IFragment>)(f => fragments.Add(f))).IgnoreArguments().Repeat.Any(); }
private bool CanProcessorIncrementalCore(IDocumentProcessor processor) { if (!ShouldProcessorTraceInfo(processor)) { return(false); } return(IncrementalContext.CanProcessorIncremental(processor)); }
public async Task <string> Get() { List <DocumentProcessors> docp = null; try { //Load data from SQL or any other db or config file. Here I am hardcoding to run my application and not using SQL. docp = new List <DocumentProcessors> { new DocumentProcessors() { ProcessorId = 1, Name = "SimpleDocProcessor", CurDirectory = @"c:\temp\simplefiles", Order = 1, ValidExtensions = new List <string> { ".Pdf", ".tif", ".txt", ".docx" } }, new DocumentProcessors() { ProcessorId = 2, Name = "ZipDocProcessor", CurDirectory = @"c:\temp\zipfiles", Order = 1, ValidExtensions = new List <string> { ".Pdf", ".tif", ".jpf", ".txt", ".docx" } } }; IDocumentProcessor docprocessor = null; foreach (DocumentProcessors prc in docp) { try { if (!Directory.Exists(utility.cmspath)) { Directory.CreateDirectory(utility.cmspath); } if (!Directory.Exists(prc.CurDirectory)) { Directory.CreateDirectory(prc.CurDirectory); } DocumentProcessorFactory dfactory = new DocumentProcessorFactory(prc.ProcessorId, prc.CurDirectory, prc.ValidExtensions); using (docprocessor = dfactory.GetDocumentProcessorObject()) { await docprocessor.ProcessFilesAsync(); } } catch (Exception ex) { utility.logFile("CallerApi", ex); } } } catch (Exception ex) { throw ex; } return("Success"); }
public virtual void SetupRepo() { mocks = new MockRepository(); template = mocks.StrictMock <ITemplate>(); docProcessor = mocks.StrictMock <IDocumentProcessor>(); renderFunction = mocks.StrictMock <IRenderFunction>(); fragments = new List <IFragment>(); Expect.Call(() => renderFunction.AddFragment(null)).Do((Action <IFragment>)(f => fragments.Add(f))).IgnoreArguments().Repeat.Any(); }
private void Prebuild(IDocumentProcessor processor, HostService hostService) { var models = processor.Prebuild(hostService.Models, hostService); if (!object.ReferenceEquals(models, hostService.Models)) { hostService.Reload(models); } }
private void Postbuild(IDocumentProcessor processor, HostService hostService) { RunBuildSteps( processor.BuildSteps, buildStep => { Logger.LogVerbose($"Plug-in {processor.Name}, build step {buildStep.Name}: Postprocessing..."); buildStep.Postbuild(hostService.Models, hostService); }); }
private void Postbuild(IDocumentProcessor processor, HostService hostService) { var models = processor.Postbuild(hostService.Models, hostService); if (!object.ReferenceEquals(models, hostService.Models)) { Logger.LogVerbose($"Plug-in {processor.Name}: Reloading models..."); hostService.Reload(models); } }
public ConcurrentPipelineObserverFacts() { _documentProcessor = Substitute.For <IDocumentProcessor>(); _tcs = new TaskCompletionSource <bool>( TaskCreationOptions.RunContinuationsAsynchronously); _onPipelineCompleted = () => { _tcs.SetResult(true); }; _onPipelineError = e => { _tcs.SetException(e); }; _testDocument = new TestDocument(Generate.Bytes()); _maxConcurrency = 100; _source = Observable.Repeat(_testDocument, _maxConcurrency); }
internal static void ProcessSwitchContent(IDocumentProcessor docProcessor, XmlNode switchNode, ITemplate template, IRenderFunction currentRenderFunction) { bool hasDefault = false; bool hasAny = false; Utils.DoForEachChild(switchNode, delegate(XmlNode child) { #if CLIENT if (((child.NodeType == XmlNodeType.Text || child.NodeType == XmlNodeType.CDATA) && child.Value.Trim() == "") || child.NodeType == XmlNodeType.Comment) { return; } #else if (child.NodeType == XmlNodeType.Whitespace || child.NodeType == XmlNodeType.SignificantWhitespace || child.NodeType == XmlNodeType.Comment) { return; } #endif if (child.NodeType == XmlNodeType.Element && child.Name == "case") { XmlAttribute valueAttr = (XmlAttribute)child.Attributes.GetNamedItem("value"); if (valueAttr == null) { throw ParserUtils.TemplateErrorException("The <case> element must have the value attribute specified."); } currentRenderFunction.AddFragment(new CodeFragment("case " + valueAttr.Value + ": {", 1)); } else if (child.NodeType == XmlNodeType.Element && child.Name == "default") { if (hasDefault) { throw ParserUtils.TemplateErrorException("There can only be one <default> element inside <switch>"); } hasDefault = true; currentRenderFunction.AddFragment(new CodeFragment("default: {", 1)); } else { throw ParserUtils.TemplateErrorException("The <switch> element can only have <case> and <default> elements as children."); } hasAny = true; Utils.DoForEachChild(child, delegate(XmlNode grandchild) { docProcessor.ProcessRecursive(grandchild, template, currentRenderFunction); }); currentRenderFunction.AddFragment(new CodeFragment("break;", -1)); currentRenderFunction.AddFragment(new CodeFragment("}", 0)); }); if (!hasAny) { throw ParserUtils.TemplateErrorException("The <switch> element must contain at least one <case> or <default>"); } }
private void BuildArticle(IDocumentProcessor processor, HostService hostService) { hostService.Models.RunAll(m => { using (new LoggerFileScope(m.OriginalFileAndType.File)) { Logger.LogVerbose($"Plug-in {processor.Name}: Building..."); processor.Build(m, hostService); } }); }
public bool CanProcessorIncremental(IDocumentProcessor processor) { if (!CanVersionIncremental) { IncrementalInfo.ReportProcessorStatus(processor.Name, false); return(false); } var cpi = CurrentBuildVersionInfo.Processors.Find(p => p.Name == processor.Name); if (cpi == null) { string message = $"Current BuildVersionInfo missed processor info for {processor.Name}."; IncrementalInfo.ReportProcessorStatus(processor.Name, false, message); Logger.LogWarning(message); return(false); } var lpi = LastBuildVersionInfo.Processors.Find(p => p.Name == processor.Name); if (lpi == null) { string message = $"Processor {processor.Name} disable incremental build because last build doesn't contain version {Version}."; IncrementalInfo.ReportProcessorStatus(processor.Name, false, message); Logger.LogVerbose(message); return(false); } if (cpi.IncrementalContextHash != lpi.IncrementalContextHash) { string message = $"Processor {processor.Name} disable incremental build because incremental context hash changed."; IncrementalInfo.ReportProcessorStatus(processor.Name, false, message); Logger.LogVerbose(message); return(false); } if (cpi.Steps.Count != lpi.Steps.Count) { string message = $"Processor {processor.Name} disable incremental build because steps count is different."; IncrementalInfo.ReportProcessorStatus(processor.Name, false, message); Logger.LogVerbose(message); return(false); } for (int i = 0; i < cpi.Steps.Count; i++) { if (!object.Equals(cpi.Steps[i], lpi.Steps[i])) { string message = $"Processor {processor.Name} disable incremental build because steps changed, from step {lpi.Steps[i].ToJsonString()} to {cpi.Steps[i].ToJsonString()}."; IncrementalInfo.ReportProcessorStatus(processor.Name, false, message); Logger.LogVerbose(message); return(false); } } IncrementalInfo.ReportProcessorStatus(processor.Name, true); Logger.LogVerbose($"Processor {processor.Name} enable incremental build."); return(true); }
private static void Postbuild(IDocumentProcessor processor, HostService hostService) { RunBuildSteps( processor.BuildSteps, buildStep => { Logger.LogVerbose($"Processor {processor.Name}, step {buildStep.Name}: Postprocessing..."); using (new LoggerPhaseScope(buildStep.Name)) { buildStep.Postbuild(hostService.Models, hostService); } }); }
public bool TryProcess(IDocumentProcessor docProcessor, XmlNode node, bool isRoot, ITemplate template, IRenderFunction currentRenderFunction) { if (node.NodeType != XmlNodeType.ProcessingInstruction) return false; switch (node.Name) { case "enableClientCreate": if (!isRoot) throw ParserUtils.TemplateErrorException("The enableClientCreate directive can only appear outside of the template."); template.EnableClientCreate = true; return true; default: return false; } }
internal static IFragment ProcessCallFragment(IDocumentProcessor docProcessor, XmlNode node) { XmlAttribute nameAttr = (XmlAttribute)node.Attributes.GetNamedItem("name"); XmlAttribute paramsAttr = (XmlAttribute)node.Attributes.GetNamedItem("params"); if (nameAttr == null) throw ParserUtils.TemplateErrorException("The <call-fragment> element must have the name attribute specified."); string name = nameAttr.Value; if (!ParserUtils.IsValidUnqualifiedName(name)) throw ParserUtils.TemplateErrorException("The name " + name + " is not a valid unqualified identifier."); if (Utils.GetNumChildNodes(node) != 0) throw ParserUtils.TemplateErrorException("The <call-fragment> element cannot have children."); return new CodeExpressionFragment(name + "(" + (paramsAttr != null ? paramsAttr.Value : "") + ")"); }
public MainForm(IAppInstance app, Func<AnalysisResultsForm> analysisResultsFormFactory, Func<AnalyzeWebPageForWordsForm> analyzeWebPageForWordsFormFactory, Func<ResolveReplaceAmbiguityForm> resolveAmbiguityFormFactory, IDocumentAnalyzer documentAnalyzer, IDocumentProcessor documentProcessor) { this.app = app; this.analysisResultsFormFactory = analysisResultsFormFactory; this.analyzeWebPageForWordsFormFactory = analyzeWebPageForWordsFormFactory; this.resolveAmbiguityFormFactory = resolveAmbiguityFormFactory; this.documentAnalyzer = documentAnalyzer; this.documentProcessor = documentProcessor; InitializeComponent(); }
public bool TryProcess(IDocumentProcessor docProcessor, XmlNode node, bool isRoot, ITemplate template, IRenderFunction currentRenderFunction) { if (node.NodeType != XmlNodeType.Element || node.Name != "copyright") return false; if (node.ChildNodes.Count != 1 || node.ChildNodes[0].NodeType != XmlNodeType.Text) throw new TemplateErrorException("The copyright node must have a single text child."); CopyrightMember m = new CopyrightMember(); if (template.HasMember(m.Name)) throw new TemplateErrorException("Duplicate definition of the member " + m.Name); template.AddMember(m); currentRenderFunction.AddFragment(new CopyrightFragment(node.ChildNodes[0].Value)); return true; }
public override HostService CreateHostService( DocumentBuildParameters parameters, TemplateProcessor templateProcessor, IMarkdownService markdownService, IEnumerable<IInputMetadataValidator> metadataValidator, IDocumentProcessor processor, IEnumerable<FileAndType> files) { if (ShouldProcessorTraceInfo(processor)) { IncrementalContext.CreateProcessorInfo(processor); } var hs = base.CreateHostService(parameters, templateProcessor, markdownService, metadataValidator, processor, files); PostCreate(hs, files); return hs; }
public bool TryProcess(IDocumentProcessor docProcessor, XmlNode node, bool isRoot, ITemplate template, IRenderFunction currentRenderFunction) { if (node.NodeType != XmlNodeType.ProcessingInstruction) return false; string v = node.Value.Trim(); switch (node.Name) { case "x": if (v == "") throw ParserUtils.TemplateErrorException("Empty embedded expression"); currentRenderFunction.AddFragment(new CodeExpressionFragment(v)); return true; case "c": if (v == "") throw ParserUtils.TemplateErrorException("Empty embedded code"); currentRenderFunction.AddFragment(new CodeFragment(v, 0)); return true; default: return false; } }
public bool TryProcess(IDocumentProcessor docProcessor, XmlNode node, bool isRoot, ITemplate template, IRenderFunction currentRenderFunction) { string name = node.Name; if (node.NodeType == XmlNodeType.Element && name == "def-fragment") { if (isRoot) throw ParserUtils.TemplateErrorException("Fragment definitions must be inside the template."); ProcessDefFragment(docProcessor, node, template); return true; } else if (node.NodeType == XmlNodeType.Element && name == "call-fragment") { if (isRoot) throw ParserUtils.TemplateErrorException("Fragment instantiations must be inside the template."); currentRenderFunction.AddFragment(ProcessCallFragment(docProcessor, node)); return true; } else return false; }
internal static void AddAttributeFragments(IDocumentProcessor docProcessor, XmlNode node, bool isRoot, ITemplate template, IRenderFunction fragments, GenericElementProcessorContext context) { bool hasStyle = false; Utils.DoForEachAttribute(node, delegate(XmlAttribute attr) { AddSingleAttributeFragments(docProcessor, attr.Name, attr.Value, isRoot, template, fragments, context); if (attr.Name == "style") hasStyle = true; }); if (isRoot) { fragments.AddFragment(new LiteralFragment(" id=\"")); fragments.AddFragment(new IdFragment()); fragments.AddFragment(new LiteralFragment("\"")); if (!hasStyle) { fragments.AddFragment(new LiteralFragment(" style=\"")); fragments.AddFragment(new PositionFragment()); fragments.AddFragment(new LiteralFragment("\"")); } } }
public virtual FileModel Load(IDocumentProcessor processor, ImmutableDictionary<string, object> metadata, FileMetadata fileMetadata, FileAndType file) { using (new LoggerFileScope(file.File)) { Logger.LogDiagnostic($"Processor {processor.Name}, File {file.FullPath}: Loading..."); var path = Path.Combine(file.BaseDir, file.File); metadata = ApplyFileMetadata(path, metadata, fileMetadata); try { return processor.Load(file, metadata); } catch (Exception) { Logger.LogError($"Unable to load file: {file.File} via processor: {processor.Name}."); throw; } } }
public bool TryProcess(IDocumentProcessor docProcessor, XmlNode node, bool isRoot, ITemplate template, IRenderFunction currentRenderFunction) { if (node.NodeType != XmlNodeType.ProcessingInstruction || node.Name != "using") return false; if (!isRoot) throw ParserUtils.TemplateErrorException(string.Format("The using directive can only appear outside of the template.", node.Name)); string[] sideArr = Utils.RegexExec(node.Value, "side=\"([^\"]*)\"", ""); string[] namespaceArr = Utils.RegexExec(node.Value, "namespace=\"([^\"]*)\"", ""); if (namespaceArr == null) throw ParserUtils.TemplateErrorException("Using directive must have the namespace specified."); string nmspace = namespaceArr[1].Trim(), side = (sideArr != null ? sideArr[1].Trim() : "both"); if (!ParserUtils.IsValidQualifiedName(nmspace)) throw ParserUtils.TemplateErrorException(string.Format("The identifier '{0}' is not a valid namespace name.", nmspace)); bool serverSide, clientSide; switch (side) { case "client": serverSide = false; clientSide = true; break; case "server": serverSide = true; clientSide = false; break; case "both": serverSide = true; clientSide = true; break; default: throw ParserUtils.TemplateErrorException("The side attribute of the using directive must be 'client', 'server', or 'both'."); } if (serverSide) template.AddServerUsingDirective(nmspace); if (clientSide) template.AddClientUsingDirective(nmspace); return true; }
public bool TryProcess(IDocumentProcessor docProcessor, XmlNode node, bool isRoot, ITemplate template, IRenderFunction currentRenderFunction) { if (node.NodeType != XmlNodeType.ProcessingInstruction || node.Name != "field") return false; if (!isRoot) throw ParserUtils.TemplateErrorException(string.Format("The {0} directive can only appear outside of the template.", node.Name)); string[] typeArr = Utils.RegexExec(node.Value, "type=\"([^\"]*)\"", ""); string[] serverTypeArr = Utils.RegexExec(node.Value, "serverType=\"([^\"]*)\"", ""); string[] clientTypeArr = Utils.RegexExec(node.Value, "clientType=\"([^\"]*)\"", ""); string[] nameArr = Utils.RegexExec(node.Value, "name=\"([^\"]*)\"", ""); string serverType, clientType; if (typeArr != null) { if (string.IsNullOrEmpty(typeArr[1].Trim())) throw ParserUtils.TemplateErrorException("No type was specified for the field"); if (serverTypeArr != null || clientTypeArr != null) throw ParserUtils.TemplateErrorException("field elements cannot have both server/client type and type specified."); serverType = clientType = typeArr[1].Trim(); } else if (serverTypeArr != null && clientTypeArr != null) { if (string.IsNullOrEmpty(serverTypeArr[1].Trim())) throw ParserUtils.TemplateErrorException("No server type was specified for the field"); if (string.IsNullOrEmpty(clientTypeArr[1].Trim())) throw ParserUtils.TemplateErrorException("No client type was specified for the field"); serverType = serverTypeArr[1].Trim(); clientType = clientTypeArr[1].Trim(); } else throw ParserUtils.TemplateErrorException("field elements must have the type specified (either 'type' or 'serverType' and 'clientType')."); string name = nameArr != null ? nameArr[1].Trim() : null; if (string.IsNullOrEmpty(name)) throw ParserUtils.TemplateErrorException("field elements must have a name specified."); if (template.HasMember(name)) throw ParserUtils.TemplateErrorException("Duplicate member " + name); template.AddMember(new FieldMember(name, serverType, clientType)); return true; }
internal static void AddSingleAttributeFragments(IDocumentProcessor docProcessor, string attrName, string attrValue, bool isRoot, ITemplate template, IRenderFunction fragments, GenericElementProcessorContext context) { string actualName; if (attrName == "actualName") { // This will translate into "name", but not with our ID prefixed. We need this because for top-level templates we want the names undisturbed to allow for a nice form submission. // However, for nested forms which we won't submit using the normal techniques, we need to prefix it in order to make radio buttons work reliably. actualName = "name"; } else actualName = attrName; fragments.AddFragment(new LiteralFragment(" " + actualName + "=\"")); if (attrName == "id") { if (isRoot) throw ParserUtils.TemplateErrorException("Can't specify an ID for the top level element."); if (template.HasMember(attrValue)) throw ParserUtils.TemplateErrorException("Duplicate member " + attrValue); context.Id = attrValue; fragments.AddFragment(new IdFragment()); fragments.AddFragment(new LiteralFragment("_" + attrValue)); } else if (attrName.ToLowerCase() == "for" || attrName.ToLowerCase() == "name") { fragments.AddFragment(new IdFragment()); fragments.AddFragment(new LiteralFragment("_" + attrValue)); } else { IFragment f = docProcessor.ParseUntypedMarkup(attrValue); fragments.AddFragment(f); if (attrName.ToLowerCase() == "type") { if (f is LiteralFragment) context.Type = ((LiteralFragment)f).Text; } else if (isRoot && attrName.ToLowerCase() == "style") { if (!(f is LiteralFragment) || !((LiteralFragment)f).Text.Trim().EndsWith(";")) fragments.AddFragment(new LiteralFragment(";")); fragments.AddFragment(new PositionFragment()); } } fragments.AddFragment(new LiteralFragment("\"")); }
public bool TryProcess(IDocumentProcessor docProcessor, XmlNode node, bool isRoot, ITemplate template, IRenderFunction currentRenderFunction) { switch (node.NodeType) { case XmlNodeType.CDATA: currentRenderFunction.AddFragment(new LiteralFragment(node.Value, true)); return true; case XmlNodeType.Text: #if !CLIENT case XmlNodeType.Whitespace: case XmlNodeType.SignificantWhitespace: #endif currentRenderFunction.AddFragment(new LiteralFragment(NormalizeSpaces(node.Value))); return true; case XmlNodeType.Comment: return true; default: return false; } }
public static ImmutableList<FileModel> Build(IDocumentProcessor processor, DocumentBuildParameters parameters, IMarkdownService markdownService) { var hostServiceCreator = new HostServiceCreator(null); var hostService = hostServiceCreator.CreateHostService( parameters, null, markdownService, null, processor, parameters.Files.EnumerateFiles()); var phaseProcessor = new PhaseProcessor { Handlers = { new PrebuildBuildPhaseHandler(null), new PostbuildPhaseHandler(null, null), } }; phaseProcessor.Process(new List<HostService> { hostService }, parameters.MaxParallelism); return hostService.Models; }
internal static void ProcessDefFragment(IDocumentProcessor docProcessor, XmlNode node, ITemplate template) { XmlAttribute nameAttr = (XmlAttribute)node.Attributes.GetNamedItem("name"); XmlAttribute paramsAttr = (XmlAttribute)node.Attributes.GetNamedItem("params"); if (nameAttr == null) throw ParserUtils.TemplateErrorException("The <def-fragment> element must have the name attribute specified."); string name = nameAttr.Value; if (!ParserUtils.IsValidUnqualifiedName(name)) throw ParserUtils.TemplateErrorException("The name " + name + " is not a valid unqualified identifier."); if (template.HasMember(name)) throw ParserUtils.TemplateErrorException("Duplicate definition of member " + name + "."); RenderFunctionMember m = new RenderFunctionMember(nameAttr.Value, paramsAttr != null ? paramsAttr.Value : ""); Utils.DoForEachChild(node, delegate(XmlNode n) { docProcessor.ProcessRecursive(n, template, m); }); if (template.HasMember(name)) throw ParserUtils.TemplateErrorException("Duplicate definition of member " + name + "."); // Just in case it has already been added during the recursive call. template.AddMember(m); }
private void BuildCore( IDocumentProcessor processor, IEnumerable<FileAndType> files, ImmutableDictionary<string, object> metadata, FileMetadata fileMetadata, DocumentBuildContext context) { Logger.LogInfo($"Plug-in {processor.Name}: Loading document..."); using (var hostService = new HostService( from file in files select Load(processor, metadata, fileMetadata, file))) { hostService.SourceFiles = context.AllSourceFiles; foreach (var m in hostService.Models) { if (m.LocalPathFromRepoRoot == null) { m.LocalPathFromRepoRoot = Path.Combine(m.BaseDir, m.File); } } Logger.LogInfo($"Plug-in {processor.Name}: Document loaded (count = {hostService.Models.Count})."); Logger.LogInfo($"Plug-in {processor.Name}: Preprocessing..."); Prebuild(processor, hostService); Logger.LogInfo($"Plug-in {processor.Name}: Building..."); BuildArticle(processor, hostService); Logger.LogInfo($"Plug-in {processor.Name}: Postprocessing..."); Postbuild(processor, hostService); Logger.LogInfo($"Plug-in {processor.Name}: Saving..."); Save(processor, hostService, context); } }
private bool IsProcessorSupportIncremental(IDocumentProcessor processor) { if (!ShouldTraceIncrementalInfo) { return false; } if (!(processor is ISupportIncrementalDocumentProcessor)) { Logger.LogVerbose($"Processor {processor.Name} cannot suppport incremental build because the processor doesn't implement {nameof(ISupportIncrementalDocumentProcessor)} interface."); return false; } if (!processor.BuildSteps.All(step => step is ISupportIncrementalBuildStep)) { Logger.LogVerbose($"Processor {processor.Name} cannot suppport incremental build because the following steps don't implement {nameof(ISupportIncrementalBuildStep)} interface: {string.Join(",", processor.BuildSteps.Where(step => !(step is ISupportIncrementalBuildStep)).Select(s => s.Name))}."); return false; } return true; }
public bool TryProcess(IDocumentProcessor docProcessor, XmlNode node, bool isRoot, ITemplate template, IRenderFunction currentRenderFunction) { if (node.NodeType != XmlNodeType.Element || node.Name != "control") return false; if (isRoot) throw ParserUtils.TemplateErrorException("The root element can not be a control."); string id = null; string type = null; bool customInstantiate = false; Dictionary<string, TypedMarkupData> additionalProperties = new Dictionary<string, TypedMarkupData>(); Utils.DoForEachAttribute(node, delegate(XmlAttribute attr) { if (attr.Name == "id") { if (!ParserUtils.IsValidUnqualifiedName(attr.Value)) throw ParserUtils.TemplateErrorException("The id '" + attr.Value + "' is not a valid identifier."); id = attr.Value; } else if (attr.Name == "type") { if (string.IsNullOrEmpty(attr.Value)) throw ParserUtils.TemplateErrorException("The control type '" + attr.Value + "' is invalid."); type = attr.Value; } else if (attr.Name == "customInstantiate") { string v = attr.Value.ToLowerCase(); customInstantiate = Utils.ParseBool(v); } else { additionalProperties[attr.Name] = docProcessor.ParseTypedMarkup(attr.Value); } }); if (customInstantiate && additionalProperties.Count > 0) throw ParserUtils.TemplateErrorException("There can not be any property assignments when customInstantiate is true."); if (type == null) throw ParserUtils.TemplateErrorException("The control '" + id + "' does not have a type specified."); if (id == null) id = template.GetUniqueId(); if (template.HasMember(id)) throw ParserUtils.TemplateErrorException("Duplicate definition of member " + id); var dependencies = new List<IMember>(); int numInnerFragments = 0; if (Utils.GetNumChildNodes(node) > 0) { Utils.DoForEachChild(node, delegate(XmlNode n) { if (n.OuterXml.Trim() != "") { numInnerFragments++; string innerName = id + "_inner" + Utils.ToStringInvariantInt(numInnerFragments); if (template.HasMember(innerName)) throw ParserUtils.TemplateErrorException("The internal name " + innerName + " is already in use."); IRenderFunction innerFunction = new RenderFunctionMember(innerName, ""); template.AddMember((IMember)innerFunction); docProcessor.ProcessRecursive(n, template, innerFunction); dependencies.Add(innerFunction); } }); } if (!template.HasMember("Container")) template.AddMember(new PropertyMember("Container", "IContainer", "IContainer", AccessModifier._Public, "_container", "IContainer", "IContainer", true, true, null, true)); IMember controlMember = new InstantiatedControlMember(id, type, customInstantiate, additionalProperties, dependencies); template.AddMember(controlMember); currentRenderFunction.AddFragment(new InstantiatedControlFragment(id, customInstantiate, numInnerFragments)); currentRenderFunction.AddDependency(controlMember); return true; }
private static FileModel Load( IDocumentProcessor processor, ImmutableDictionary<string, object> metadata, FileMetadata fileMetadata, FileAndType file) { using (new LoggerFileScope(file.File)) { Logger.LogVerbose($"Plug-in {processor.Name}: Loading..."); var path = Path.Combine(file.BaseDir, file.File); metadata = ApplyFileMetadata(path, metadata, fileMetadata); return processor.Load(file, metadata); } }
public ProcessorInfo CreateProcessorInfo(IDocumentProcessor processor) { var cpi = new ProcessorInfo { Name = processor.Name, IncrementalContextHash = ((ISupportIncrementalDocumentProcessor)processor).GetIncrementalContextHash(), }; foreach (var step in processor.BuildSteps) { cpi.Steps.Add(new ProcessorStepInfo { Name = step.Name, IncrementalContextHash = ((ISupportIncrementalBuildStep)step).GetIncrementalContextHash(), }); } CurrentBuildVersionInfo.Processors.Add(cpi); return cpi; }
public bool CanProcessorIncremental(IDocumentProcessor processor) { if (!CanVersionIncremental) { return false; } var cpi = CurrentBuildVersionInfo.Processors.Find(p => p.Name == processor.Name); if (cpi == null) { Logger.LogWarning($"Current BuildVersionInfo missed processor info for {processor.Name}."); return false; } var lpi = LastBuildVersionInfo.Processors.Find(p => p.Name == processor.Name); if (lpi == null) { Logger.LogVerbose($"Processor {processor.Name} disable incremental build because last build doesn't contain version {Version}."); return false; } if (cpi.IncrementalContextHash != lpi.IncrementalContextHash) { Logger.LogVerbose($"Processor {processor.Name} disable incremental build because incremental context hash changed."); return false; } if (cpi.Steps.Count != lpi.Steps.Count) { Logger.LogVerbose($"Processor {processor.Name} disable incremental build because steps count is different."); return false; } for (int i = 0; i < cpi.Steps.Count; i++) { if (!object.Equals(cpi.Steps[i], lpi.Steps[i])) { Logger.LogVerbose($"Processor {processor.Name} disable incremental build because steps changed, from step {lpi.Steps[i].ToJsonString()} to {cpi.Steps[i].ToJsonString()}."); return false; } } Logger.LogVerbose($"Processor {processor.Name} enable incremental build."); return true; }