/// <summary> /// This method overlays any answer collections passed into it, into a single XML answer collection. /// It has two primary uses: it can be used to combine multiple answer collections into a single /// answer collection; and/or it can be used to "resolve" or standardize an answer collection /// submitted from a browser interview (which may be specially encoded) into standard XML answers. /// </summary> /// <param name="answers">A sequence of answer collections. Each member of this sequence /// must be either an (encoded) interview answer collection or a regular XML answer collection. /// Each member will be successively overlaid (overlapped) on top of the prior members to /// form one consolidated answer collection.</param> /// <include file="../Shared/Help.xml" path="Help/string/param[@name='logRef']"/> /// <returns>The consolidated XML answer collection.</returns> public string GetAnswers(IEnumerable <TextReader> answers, string logRef) { // Validate input parameters, creating defaults as appropriate. string logStr = logRef == null ? string.Empty : logRef; if (answers == null) { throw new ArgumentNullException("answers", @"Local.Services.GetAnswers: The ""answers"" parameter must not be null, logRef: " + logStr); } string result = ""; using (HotDocs.Server.AnswerCollection hdsAnsColl = new HotDocs.Server.AnswerCollection()) { foreach (TextReader tr in answers) { hdsAnsColl.OverlayXMLAnswers(tr.ReadToEnd()); } result = hdsAnsColl.XmlAnswers; } return(result); }
/// <summary> /// Assemble a document from the given template, answers and settings. /// </summary> /// <param name="template">An instance of the Template class.</param> /// <param name="answers">Either an XML answer string, or a string containing encoded /// interview answers as posted from a HotDocs browser interview.</param> /// <param name="settings">An instance of the AssembleDocumentResult class.</param> /// <include file="../Shared/Help.xml" path="Help/string/param[@name='logRef']"/> /// <returns>An AssemblyResult object containing all the files and data resulting from the request.</returns> public AssembleDocumentResult AssembleDocument(Template template, TextReader answers, AssembleDocumentSettings settings, string logRef) { // Validate input parameters, creating defaults as appropriate. string logStr = logRef == null ? string.Empty : logRef; if (template == null) throw new ArgumentNullException("template", string.Format(@"Local.Services.AssembleDocument: the ""template"" parameter passed in was null, logRef: {0}", logStr)); if (settings == null) settings = new AssembleDocumentSettings(); HotDocs.Server.AnswerCollection ansColl = new HotDocs.Server.AnswerCollection(); ansColl.OverlayXMLAnswers(answers == null ? "" : answers.ReadToEnd()); HotDocs.Server.OutputOptions outputOptions = ConvertOutputOptions(settings.OutputOptions); string docPath = CreateTempDocDirAndPath(template, settings.Format); _app.AssembleDocument( template.GetFullPath(),//Template path settings.UseMarkupSyntax ? hdsi.HDAssemblyOptions.asmOptMarkupView : hdsi.HDAssemblyOptions.asmOptNone, ansColl, docPath, outputOptions); //Prepare the post-assembly answer set (dropping transient ("don't save") answers when appropriate) HotDocs.Sdk.AnswerCollection resultAnsColl = new AnswerCollection(); resultAnsColl.ReadXml(new StringReader(ansColl.XmlAnswers)); string resultAnsXml = resultAnsColl.GetXMLString(false, settings.RetainTransientAnswers || _app.PendingAssemblyCmdLineStrings.Count > 0); //Build the list of pending assemblies. List<Template> pendingAssemblies = new List<Template>(); for (int i = 0; i < _app.PendingAssemblyCmdLineStrings.Count; i++) { string cmdLine = _app.PendingAssemblyCmdLineStrings[i]; string path, switches; Util.ParseHdAsmCmdLine(cmdLine, out path, out switches); pendingAssemblies.Add(new Template(Path.GetFileName(path), template.Location.Duplicate(), switches)); } //Prepare the document stream and image information for the browser. DocumentType docType = settings.Format; List<NamedStream> supportingFiles = new List<NamedStream>(); MemoryStream docStream; if (docType == DocumentType.Native) { docType = Document.GetDocumentType(docPath); docStream = LoadFileIntoMemStream(docPath); } else if (docType == DocumentType.HTMLwDataURIs) { //If the consumer requested both HTML and HTMLwDataURIs, they'll only get the latter. string content = Util.EmbedImagesInURIs(docPath); docStream = new MemoryStream(Encoding.UTF8.GetBytes(content)); } else if (docType == DocumentType.MHTML) { string content = Util.HtmlToMultiPartMime(docPath); docStream = new MemoryStream(Encoding.UTF8.GetBytes(content)); } else if (docType == DocumentType.HTML) { string targetFilenameNoExtention = Path.GetFileNameWithoutExtension(docPath); foreach (string img in Directory.EnumerateFiles(Path.GetDirectoryName(docPath))) { string ext = Path.GetExtension(img).ToLower(); if (Path.GetFileName(img).StartsWith(targetFilenameNoExtention) && (ext == ".jpg" || ext == ".jpeg" || ext == ".gif" || ext == ".png" || ext == ".bmp")) supportingFiles.Add(LoadFileIntoNamedStream(img)); } docStream = LoadFileIntoMemStream(docPath); } else { docStream = LoadFileIntoMemStream(docPath); } //Now that we've loaded all of the assembly results into memory, remove the assembly files. FreeTempDocDir(docPath); //Return the results. Document document = new Document(template, docStream, docType, supportingFiles.ToArray(), _app.UnansweredVariablesList.ToArray()); AssembleDocumentResult result = new AssembleDocumentResult(document, resultAnsXml, pendingAssemblies.ToArray(), _app.UnansweredVariablesList.ToArray()); return result; }
///<summary> /// GetInterview returns an HTML fragment suitable for inclusion in any standards-mode web page, which embeds a HotDocs interview /// directly in that web page. ///</summary> /// <param name="template">The template for which to return an interview.</param> /// <param name="answers">The answers to use when building an interview.</param> /// <param name="settings">The <see cref="InterviewSettings"/> to use when building an interview.</param> /// <param name="markedVariables">The variables to highlight to the user as needing special attention. /// This is usually populated with <see cref="AssembleDocumentResult.UnansweredVariables" /> /// from <see cref="AssembleDocument" />.</param> /// <include file="../Shared/Help.xml" path="Help/string/param[@name='logRef']"/> /// <returns>Returns the results of building the interview as an <see cref="InterviewResult"/> object.</returns> public InterviewResult GetInterview(Template template, TextReader answers, InterviewSettings settings, IEnumerable<string> markedVariables, string logRef) { // Validate input parameters, creating defaults as appropriate. string logStr = logRef == null ? string.Empty : logRef; if (template == null) throw new ArgumentNullException("template", string.Format(@"Local.Services.GetInterview: the ""template"" parameter passed in was null, logRef: {0}", logStr)); if (settings == null) settings = new InterviewSettings(); // HotDocs Server reads the following settings out of the registry all the time; therefore these items are ignored when running against Server: // settings.AddHdMainDiv // settings.AnswerSummary.* // settings.DefaultDateFormat // settings.DefaultUnansweredFormat // settings.HonorCmpUnansweredFormat // settings.DisableAnswerSummary // HotDocs Server does not include the following settings in its .NET or COM APIs, so Util.AppendSdkScriptBlock (below) // includes them with the interview script block: // settings.Locale // settings.NextFollowsOutline // settings.ShowAllResourceButtons hdsi.interviewFormat fmt; switch (settings.Format) { case InterviewFormat.JavaScript: fmt = hdsi.interviewFormat.javascript; break; case InterviewFormat.Silverlight: fmt = hdsi.interviewFormat.Silverlight; break; default: fmt = hdsi.interviewFormat.Unspecified; break; } // Configure the interview options hdsi.HDInterviewOptions itvOpts = hdsi.HDInterviewOptions.intOptNoImages; // Instructs HDS not to return images used by the interview; we'll get them ourselves from the template folder. if (settings.DisableDocumentPreview) itvOpts |= hdsi.HDInterviewOptions.intOptNoPreview; // Disables (omits) the Document Preview button on the interview toolbar. if (settings.DisableSaveAnswers) itvOpts |= hdsi.HDInterviewOptions.intOptNoSave; // Disables (omits) the Save Answers button on the interview toolbar. if (settings.RoundTripUnusedAnswers) itvOpts |= hdsi.HDInterviewOptions.intOptStateless; // Prevents original answer file from being encrypted and sent to the interview and then posted back at the end. // Get the interview. InterviewResult result = new InterviewResult(); StringBuilder htmlFragment; using (var ansColl = new HotDocs.Server.AnswerCollection()) { if (answers != null) { if (answers.Peek() == 0xFEFF) answers.Read(); // discard BOM if present ansColl.XmlAnswers = answers.ReadToEnd(); } if (markedVariables == null) _app.UnansweredVariablesList = new string[0]; else _app.UnansweredVariablesList = markedVariables; htmlFragment = new StringBuilder( _app.GetInterview( template.GetFullPath(), template.Key, fmt, itvOpts, settings.InterviewRuntimeUrl, settings.StyleSheetUrl + "/" + settings.ThemeName + ".css", ansColl, settings.PostInterviewUrl, settings.Title, Util.GetInterviewDefinitionUrl(settings, template), null, // the path to which HDS should copy interview images; also the path that may become part of the DocumentPreviewStateString & passed to document preview handler Util.GetInterviewImageUrl(settings, template), settings.SaveAnswersUrl, settings.DocumentPreviewUrl) ); } Util.AppendSdkScriptBlock(htmlFragment, template, settings); result.HtmlFragment = htmlFragment.ToString(); return result; }
/// <summary> /// This method overlays any answer collections passed into it, into a single XML answer collection. /// It has two primary uses: it can be used to combine multiple answer collections into a single /// answer collection; and/or it can be used to "resolve" or standardize an answer collection /// submitted from a browser interview (which may be specially encoded) into standard XML answers. /// </summary> /// <param name="answers">A sequence of answer collections. Each member of this sequence /// must be either an (encoded) interview answer collection or a regular XML answer collection. /// Each member will be successively overlaid (overlapped) on top of the prior members to /// form one consolidated answer collection.</param> /// <include file="../Shared/Help.xml" path="Help/string/param[@name='logRef']"/> /// <returns>The consolidated XML answer collection.</returns> public string GetAnswers(IEnumerable<TextReader> answers, string logRef) { // Validate input parameters, creating defaults as appropriate. string logStr = logRef == null ? string.Empty : logRef; if (answers == null) throw new ArgumentNullException("answers", @"Local.Services.GetAnswers: The ""answers"" parameter must not be null, logRef: " + logStr); string result = ""; using (HotDocs.Server.AnswerCollection hdsAnsColl = new HotDocs.Server.AnswerCollection()) { foreach (TextReader tr in answers) hdsAnsColl.OverlayXMLAnswers(tr.ReadToEnd()); result = hdsAnsColl.XmlAnswers; } return result; }
/// <summary> /// Assemble a document from the given template, answers and settings. /// </summary> /// <param name="template">An instance of the Template class.</param> /// <param name="answers">Either an XML answer string, or a string containing encoded /// interview answers as posted from a HotDocs browser interview.</param> /// <param name="settings">An instance of the AssembleDocumentResult class.</param> /// <include file="../Shared/Help.xml" path="Help/string/param[@name='logRef']"/> /// <returns>An AssemblyResult object containing all the files and data resulting from the request.</returns> public AssembleDocumentResult AssembleDocument(Template template, TextReader answers, AssembleDocumentSettings settings, string logRef) { // Validate input parameters, creating defaults as appropriate. string logStr = logRef == null ? string.Empty : logRef; if (template == null) { throw new ArgumentNullException("template", string.Format(@"Local.Services.AssembleDocument: the ""template"" parameter passed in was null, logRef: {0}", logStr)); } if (settings == null) { settings = new AssembleDocumentSettings(); } HotDocs.Server.AnswerCollection ansColl = new HotDocs.Server.AnswerCollection(); ansColl.OverlayXMLAnswers(answers == null ? "" : answers.ReadToEnd()); HotDocs.Server.OutputOptions outputOptions = ConvertOutputOptions(settings.OutputOptions); string docPath = CreateTempDocDirAndPath(template, settings.Format); _app.AssembleDocument( template.GetFullPath(), //Template path hdsi.HDAssemblyOptions.asmOptMarkupView, ansColl, docPath, outputOptions); //Prepare the post-assembly answer set. HotDocs.Sdk.AnswerCollection resultAnsColl = new AnswerCollection(); resultAnsColl.ReadXml(new StringReader(ansColl.XmlAnswers)); if (!settings.RetainTransientAnswers && _app.PendingAssemblyCmdLineStrings.Count == 0) { // Create a list of all "transient" answers to remove. IEnumerable <Answer> transAnswers = from a in resultAnsColl where !a.Save select a; List <string> answersToRemove = new List <string>(); foreach (Answer ans in transAnswers) { answersToRemove.Add(ans.Name); } // Iterate through the list of answers to remove and remove them from the result answer collection. // This is done as a separate step so we are not modifying the collecion over which we are iterating. foreach (string s in answersToRemove) { resultAnsColl.RemoveAnswer(s); } } //Build the list of pending assemblies. List <Template> pendingAssemblies = new List <Template>(); for (int i = 0; i < _app.PendingAssemblyCmdLineStrings.Count; i++) { string cmdLine = _app.PendingAssemblyCmdLineStrings[i]; string path, switches; Util.ParseHdAsmCmdLine(cmdLine, out path, out switches); pendingAssemblies.Add(new Template(Path.GetFileName(path), template.Location.Duplicate(), switches)); } //Prepare the document stream and image information for the browser. DocumentType docType = settings.Format; List <NamedStream> supportingFiles = new List <NamedStream>(); MemoryStream docStream; if (docType == DocumentType.Native) { docType = Document.GetDocumentType(docPath); docStream = LoadFileIntoMemStream(docPath); } else if (docType == DocumentType.HTMLwDataURIs) { //If the consumer requested both HTML and HTMLwDataURIs, they'll only get the latter. string content = Util.EmbedImagesInURIs(docPath); docStream = new MemoryStream(Encoding.UTF8.GetBytes(content)); } else if (docType == DocumentType.MHTML) { string content = Util.HtmlToMultiPartMime(docPath); docStream = new MemoryStream(Encoding.UTF8.GetBytes(content)); } else if (docType == DocumentType.HTML) { string targetFilenameNoExtention = Path.GetFileNameWithoutExtension(docPath); foreach (string img in Directory.EnumerateFiles(Path.GetDirectoryName(docPath))) { string ext = Path.GetExtension(img).ToLower(); if (Path.GetFileName(img).StartsWith(targetFilenameNoExtention) && (ext == ".jpg" || ext == ".jpeg" || ext == ".gif" || ext == ".png" || ext == ".bmp")) { supportingFiles.Add(LoadFileIntoNamedStream(img)); } } docStream = LoadFileIntoMemStream(docPath); } else { docStream = LoadFileIntoMemStream(docPath); } //Now that we've loaded all of the assembly results into memory, remove the assembly files. FreeTempDocDir(docPath); //Return the results. Document document = new Document(template, docStream, docType, supportingFiles.ToArray(), _app.UnansweredVariablesList.ToArray()); AssembleDocumentResult result = new AssembleDocumentResult(document, resultAnsColl.XmlAnswers, pendingAssemblies.ToArray(), _app.UnansweredVariablesList.ToArray()); return(result); }
///<summary> /// GetInterview returns an HTML fragment suitable for inclusion in any standards-mode web page, which embeds a HotDocs interview /// directly in that web page. ///</summary> /// <param name="template">The template for which to return an interview.</param> /// <param name="answers">The answers to use when building an interview.</param> /// <param name="settings">The <see cref="InterviewSettings"/> to use when building an interview.</param> /// <param name="markedVariables">The variables to highlight to the user as needing special attention. /// This is usually populated with <see cref="AssembleDocumentResult.UnansweredVariables" /> /// from <see cref="AssembleDocument" />.</param> /// <include file="../Shared/Help.xml" path="Help/string/param[@name='logRef']"/> /// <returns>Returns the results of building the interview as an <see cref="InterviewResult"/> object.</returns> public InterviewResult GetInterview(Template template, TextReader answers, InterviewSettings settings, IEnumerable <string> markedVariables, string logRef) { // Validate input parameters, creating defaults as appropriate. string logStr = logRef == null ? string.Empty : logRef; if (template == null) { throw new ArgumentNullException("template", string.Format(@"Local.Services.GetInterview: the ""template"" parameter passed in was null, logRef: {0}", logStr)); } if (settings == null) { settings = new InterviewSettings(); } // HotDocs Server reads the following settings out of the registry all the time; therefore these items are ignored when running against Server: // settings.AddHdMainDiv // settings.AnswerSummary.* // settings.DefaultDateFormat // settings.DefaultUnansweredFormat // settings.HonorCmpUnansweredFormat // settings.DisableAnswerSummary // HotDocs Server does not include the following settings in its .NET or COM APIs, so Util.AppendSdkScriptBlock (below) // includes them with the interview script block: // settings.Locale // settings.NextFollowsOutline // settings.ShowAllResourceButtons hdsi.interviewFormat fmt; switch (settings.Format) { case InterviewFormat.JavaScript: fmt = hdsi.interviewFormat.javascript; break; case InterviewFormat.Silverlight: fmt = hdsi.interviewFormat.Silverlight; break; default: fmt = hdsi.interviewFormat.Unspecified; break; } // Configure the interview options hdsi.HDInterviewOptions itvOpts = hdsi.HDInterviewOptions.intOptNoImages; // Instructs HDS not to return images used by the interview; we'll get them ourselves from the template folder. if (settings.DisableDocumentPreview) { itvOpts |= hdsi.HDInterviewOptions.intOptNoPreview; // Disables (omits) the Document Preview button on the interview toolbar. } if (settings.DisableSaveAnswers) { itvOpts |= hdsi.HDInterviewOptions.intOptNoSave; // Disables (omits) the Save Answers button on the interview toolbar. } if (settings.RoundTripUnusedAnswers) { itvOpts |= hdsi.HDInterviewOptions.intOptStateless; // Prevents original answer file from being encrypted and sent to the interview and then posted back at the end. } // Get the interview. InterviewResult result = new InterviewResult(); StringBuilder htmlFragment; using (var ansColl = new HotDocs.Server.AnswerCollection()) { if (answers != null) { if (answers.Peek() == 0xFEFF) { answers.Read(); // discard BOM if present } ansColl.XmlAnswers = answers.ReadToEnd(); } if (markedVariables == null) { _app.UnansweredVariablesList = new string[0]; } else { _app.UnansweredVariablesList = markedVariables; } htmlFragment = new StringBuilder( _app.GetInterview( template.GetFullPath(), template.Key, fmt, itvOpts, settings.InterviewRuntimeUrl, settings.StyleSheetUrl + "/" + settings.ThemeName + ".css", ansColl, settings.PostInterviewUrl, settings.Title, Util.GetInterviewDefinitionUrl(settings, template), null, // the path to which HDS should copy interview images; also the path that may become part of the DocumentPreviewStateString & passed to document preview handler Util.GetInterviewImageUrl(settings, template), settings.SaveAnswersUrl, settings.DocumentPreviewUrl) ); } Util.AppendSdkScriptBlock(htmlFragment, template, settings); result.HtmlFragment = htmlFragment.ToString(); return(result); }