/// <summary> /// AssembleDocuments causes all contiguous pending document work items (from CurrentWorkItem onwards) /// to be assembled, and returns the assembled documents. /// </summary> /// <param name="preAssembleDocument">This delegate will be called immediately before each document is assembled.</param> /// <param name="postAssembleDocument">This delegate will be called immediately following assembly of each document.</param> /// <param name="userState">This object will be passed to the above delegates.</param> /// <include file="../Shared/Help.xml" path="Help/string/param[@name='logRef']"/> /// <returns>An array of Document, one item for each document that was assembled. Note that these items /// are of type Document, not AssemblyResult (see below).</returns> /// <remarks> /// <para>If AssembleDocuments is called when the current work item is not a document (i.e. when there are /// currently no documents to assemble), it will return an empty array of results without performing any work.</para> /// TODO: include a table that shows the relationship between members of Document, AssemblyResult, WorkSession and DocumentWorkItem. /// </remarks> public Document[] AssembleDocuments(PreAssembleDocumentDelegate preAssembleDocument, PostAssembleDocumentDelegate postAssembleDocument, object userState, string logRef) { var result = new List <Document>(); // skip past completed work items to get the current workItem WorkItem workItem = null; int itemIndex = 0; for (; itemIndex < _workItems.Count; itemIndex++) { workItem = _workItems[itemIndex]; if (!workItem.IsCompleted) { break; } workItem = null; } // while the current workItem != null && is a document (i.e. is not an interview) while (workItem != null && workItem is DocumentWorkItem) { var docWorkItem = workItem as DocumentWorkItem; // make a copy of the default assembly settings and pass it to the BeforeAssembleDocumentDelegate (if provided) AssembleDocumentSettings asmOpts = new AssembleDocumentSettings(DefaultAssemblySettings); asmOpts.Format = workItem.Template.NativeDocumentType; // if this is not the last work item in the queue, force retention of transient answers asmOpts.RetainTransientAnswers |= (workItem != _workItems[_workItems.Count - 1]); if (preAssembleDocument != null) { preAssembleDocument(docWorkItem.Template, AnswerCollection, asmOpts, userState); } // assemble the item using (var asmResult = _service.AssembleDocument(docWorkItem.Template, new StringReader(AnswerCollection.XmlAnswers), asmOpts, logRef)) { if (postAssembleDocument != null) { postAssembleDocument(docWorkItem.Template, asmResult, userState); } // replace the session answers with the post-assembly answers AnswerCollection.ReadXml(asmResult.Answers); // add pendingAssemblies to the queue as necessary InsertNewWorkItems(asmResult.PendingAssemblies, itemIndex); // store UnansweredVariables in the DocumentWorkItem docWorkItem.UnansweredVariables = asmResult.UnansweredVariables; // add an appropriate Document to a list being compiled for the return value of this method result.Add(asmResult.ExtractDocument()); } // mark the current workitem as complete docWorkItem.IsCompleted = true; // advance to the next workitem workItem = (++itemIndex >= _workItems.Count) ? null : _workItems[itemIndex]; } return(result.ToArray()); }
private void AssembleDocument(IServices svc, string logRef) { Template tmp = Util.OpenTemplate("d1f7cade-cb74-4457-a9a0-27d94f5c2d5b"); TextReader answers = new StringReader(""); AssembleDocumentSettings settings = new AssembleDocumentSettings(); AssembleDocumentResult result; // Verify that a null template throws the right exception. try { result = svc.AssembleDocument(null, answers, settings, logRef); Assert.Fail(); // We should not have reached this point. } catch (ArgumentNullException ex) { Assert.IsTrue(ex.Message.Contains("template")); } catch (Exception) { Assert.Fail(); // We are not expecting a generic exception. } // Pass a null for settings, answers, and logRef to ensure that defaults are used. result = svc.AssembleDocument(tmp, null, null, null); Assert.AreEqual(result.PendingAssembliesCount, 0); Assert.AreEqual(0, result.Document.SupportingFiles.Count <NamedStream>()); Assert.AreEqual(0, result.PendingAssembliesCount);; settings.Format = DocumentType.MHTML; result = svc.AssembleDocument(tmp, answers, settings, logRef); Assert.AreEqual(0, result.Document.SupportingFiles.Count <NamedStream>()); // The MHTML is a single file (no external images). settings.Format = DocumentType.HTMLwDataURIs; result = svc.AssembleDocument(tmp, answers, settings, logRef); Assert.AreEqual(0, result.Document.SupportingFiles.Count <NamedStream>()); // The HTML with Data URIs is a single file (no external images). settings.Format = DocumentType.HTML; result = svc.AssembleDocument(tmp, answers, settings, logRef); Assert.AreEqual(1, result.Document.SupportingFiles.Count <NamedStream>()); // The HTML contains one external image file. //Assemble a document with an answer file containing a transient answer. string transAnsPath = Path.Combine(Util.GetTestAnswersDir(), "TransAns.anx"); TextReader transAns = new StreamReader(new FileStream(transAnsPath, FileMode.Open)); result = svc.AssembleDocument(tmp, transAns, null, logRef); // Now try with another template, which contains an ASSEMBLE instruction. tmp = Util.OpenTemplate("TemplateWithAssemble"); result = svc.AssembleDocument(tmp, null, null, logRef); Assert.AreEqual(1, result.PendingAssembliesCount); }
private void AssembleDocument(IServices svc, string logRef) { Template tmp = Util.OpenTemplate("d1f7cade-cb74-4457-a9a0-27d94f5c2d5b"); TextReader answers = new StringReader(""); AssembleDocumentSettings settings = new AssembleDocumentSettings(); AssembleDocumentResult result; // Verify that a null template throws the right exception. try { result = svc.AssembleDocument(null, answers, settings, logRef); Assert.Fail(); // We should not have reached this point. } catch (ArgumentNullException ex) { Assert.IsTrue(ex.Message.Contains("template")); } catch (Exception) { Assert.Fail(); // We are not expecting a generic exception. } // Pass a null for settings, answers, and logRef to ensure that defaults are used. result = svc.AssembleDocument(tmp, null, null, null); Assert.AreEqual(result.PendingAssembliesCount, 0); Assert.AreEqual(0, result.Document.SupportingFiles.Count<NamedStream>()); Assert.AreEqual(0, result.PendingAssembliesCount); ; settings.Format = DocumentType.MHTML; result = svc.AssembleDocument(tmp, answers, settings, logRef); Assert.AreEqual(0, result.Document.SupportingFiles.Count<NamedStream>()); // The MHTML is a single file (no external images). settings.Format = DocumentType.HTMLwDataURIs; result = svc.AssembleDocument(tmp, answers, settings, logRef); Assert.AreEqual(0, result.Document.SupportingFiles.Count<NamedStream>()); // The HTML with Data URIs is a single file (no external images). settings.Format = DocumentType.HTML; result = svc.AssembleDocument(tmp, answers, settings, logRef); Assert.AreEqual(1, result.Document.SupportingFiles.Count<NamedStream>()); // The HTML contains one external image file. //Assemble a document with an answer file containing a transient answer. string transAnsPath = Path.Combine(Util.GetTestAnswersDir(), "TransAns.anx"); TextReader transAns = new StreamReader(new FileStream(transAnsPath, FileMode.Open)); result = svc.AssembleDocument(tmp, transAns, null, logRef); // Now try with another template, which contains an ASSEMBLE instruction. tmp = Util.OpenTemplate("TemplateWithAssemble"); result = svc.AssembleDocument(tmp, null, null, logRef); Assert.AreEqual(1, result.PendingAssembliesCount); }