Exemplo n.º 1
0
        /// <summary>
        /// Assembles a document from the given template, answers and settings.
        /// </summary>
        /// <param name="template">The template to assemble.</param>
        /// <param name="answers">The answers to use during the assembly.</param>
        /// <param name="settings">The settings for the assembly.</param>
        /// <include file="../../Shared/Help.xml" path="Help/string/param[@name='logRef']"/>
        /// <returns>An <c>AssembleDocumentResult</c> that contains the results of the assembly.</returns>
        public AssembleDocumentResult AssembleDocument(Template template, System.IO.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(@"Cloud.Services.AssembleDocument: the ""template"" parameter passed in was null, logRef: {0}", logStr));
            }

            if (settings == null)
            {
                settings = new AssembleDocumentSettings();
            }

            AssembleDocumentResult result    = null;
            AssemblyResult         asmResult = null;

            using (var client = new SoapClient(_subscriberID, _signingKey, HostAddress, ProxyAddress))
            {
                asmResult = client.AssembleDocument(
                    template,
                    answers == null ? "" : answers.ReadToEnd(),
                    settings,
                    logRef
                    );
            }

            if (asmResult != null)
            {
                result = Util.ConvertAssemblyResult(template, asmResult, settings.Format);
            }

            return(result);
        }
        /// <summary>
        /// <c>AssembleDocument</c> assembles (creates) a document from the given template, answers and settings.
        /// </summary>
        /// <param name="template">An instance of the Template class, from which the document will be assembled.</param>
        /// <param name="answers">The set of answers that will be applied to the template to assemble the document</param>
        /// <param name="settings">settings that will be used to assemble the document. 
        /// These settings include the assembled document format (file extension), markup syntax, how to display fields with unanswered variables, etc</param>
        /// <param name="logRef">A string to display in logs related to this request.</param>
        /// <returns>returns information about the assembled document, the document type, the unanswered variables, the resulting answers, etc.</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(@"WebService.Services.AssembleDocument: the ""template"" parameter passed in was null, logRef: {0}", logStr));

            if (settings == null)
                settings = new AssembleDocumentSettings();

            AssembleDocumentResult result = null;
            AssemblyResult asmResult = null;

            using (Proxy client = new Proxy(_endPointName))
            {
                OutputFormat outputFormat = ConvertFormat(settings.Format);
                AssemblyOptions assemblyOptions = ConvertOptions(settings);
                string fileName = GetRelativePath(template.GetFullPath());
                asmResult = client.AssembleDocument(
                    fileName,
                    answers == null ? null : new BinaryObject[] { Util.GetBinaryObjectFromTextReader(answers) }, // answers
                    outputFormat,
                    assemblyOptions,
                    null);
                SafeCloseClient(client, logRef);
            }

            if (asmResult != null)
            {
                result = Util.ConvertAssemblyResult(template, asmResult, settings.Format);
            }

            return result;
        }
Exemplo n.º 3
0
        /// <summary>
        /// Assembles a document from the given template, answers and settings.
        /// </summary>
        /// <param name="template">The template to assemble.</param>
        /// <param name="answers">The answers to use during the assembly.</param>
        /// <param name="settings">The settings for the assembly.</param>
        /// <include file="../../Shared/Help.xml" path="Help/string/param[@name='logRef']"/>
        /// <returns>An <c>AssembleDocumentResult</c> that contains the results of the assembly.</returns>
        public AssembleDocumentResult AssembleDocument(Template template, System.IO.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(@"Cloud.Services.AssembleDocument: the ""template"" parameter passed in was null, logRef: {0}", logStr));

            if (settings == null)
                settings = new AssembleDocumentSettings();

            AssembleDocumentResult result = null;
            AssemblyResult asmResult = null;

            using (var client = new SoapClient(_subscriberID, _signingKey, HostAddress, ProxyAddress))
            {
                asmResult = client.AssembleDocument(
                    template,
                    answers == null ? "" : answers.ReadToEnd(),
                    settings,
                    logRef
                );
            }

            if (asmResult != null)
            {
                result = Util.ConvertAssemblyResult(template, asmResult, settings.Format);
            }

            return result;
        }
Exemplo n.º 4
0
 /// <summary>
 /// Creates a WorkSession object that a host application can use to step through the process of presenting
 /// all the interviews and assembling all the documents that may result from the given template.
 ///
 /// Allows the default interview settings to be specified instead of being read from config file
 /// </summary>
 /// <param name="service">An object implementing the IServices interface, encapsulating the instance of
 /// HotDocs Server with which the host app is communicating.</param>
 /// <param name="template">The template upon which this WorkSession is based. The initial interview and/or
 /// document work items in the WorkSession will be based on this template (including its Switches property).</param>
 /// <param name="answers">A collection of XML answers to use as a starting point for the work session.
 /// The initial interview (if any) will be pre-populated with these answers, and the subsequent generation
 /// of documents will have access to these answers as well.</param>
 /// <param name="defaultInterviewSettings">The default interview settings to be used throughout the session</param>
 public WorkSession(IServices service, Template template, TextReader answers, InterviewSettings defaultInterviewSettings)
 {
     _service         = service;
     AnswerCollection = new AnswerCollection();
     if (answers != null)
     {
         AnswerCollection.ReadXml(answers);
     }
     DefaultAssemblySettings = new AssembleDocumentSettings();
     if (defaultInterviewSettings != null)
     {
         DefaultInterviewSettings = defaultInterviewSettings;
     }
     else
     {
         DefaultInterviewSettings = new InterviewSettings();
     }
     // add the work items
     _workItems = new List <WorkItem>();
     if (template.HasInterview)
     {
         _workItems.Add(new InterviewWorkItem(template));
     }
     if (template.GeneratesDocument)
     {
         _workItems.Add(new DocumentWorkItem(template));
     }
 }
Exemplo n.º 5
0
        /// <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());
        }
Exemplo n.º 6
0
        private static AssembleDocumentResult AssembleDocument()
        {
            var template = GetTemplate();
            var answers  = GetAnswers();
            var assembleDocumentSettings = new AssembleDocumentSettings();

            var service = new OnPremiseServices("http://localhost:80/hdswebapi/api/HDCS");

            return(service.AssembleDocument(template, answers, assembleDocumentSettings, "ExampleLogRef"));
        }
Exemplo n.º 7
0
        private static void AssembleDocument(string encodedAnswers)
        {
            var template = CreateTemplate();
            var answers  = new StringReader(encodedAnswers);
            var assembleDocumentSettings = new AssembleDocumentSettings();

            var service = new OnPremiseServices("http://localhost:80/hdswebapi/api/hdcs");
            var assembledDocumentResult = service.AssembleDocument(template, answers, assembleDocumentSettings, "ExampleLogRef");

            SaveAssembledDocument(assembledDocumentResult);
        }
        AssemblyOptions ConvertOptions(AssembleDocumentSettings settings)
        {
            AssemblyOptions assemblyOptions = new AssemblyOptions();

            assemblyOptions = AssemblyOptions.None;
            if (settings.UseMarkupSyntax == Tristate.True)
            {
                assemblyOptions |= AssemblyOptions.MarkupView;
            }
            return(assemblyOptions);
        }
Exemplo n.º 9
0
        private static AssembleDocumentResult CreateAssembleDocumentResult()
        {
            var template = CreateTemplate();
            var answers  = GetAnswers();
            var assembleDocumentSettings = new AssembleDocumentSettings();

            var service = CreateHotDocsService();
            var assembledDocumentResult = service.AssembleDocument(template, answers, assembleDocumentSettings, "Example Assemble Document Log Text");

            return(assembledDocumentResult);
        }
Exemplo n.º 10
0
        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);
        }
Exemplo n.º 11
0
        private static void AssembleDocument(string encryptedAnswers)
        {
            var service  = CreateHotDocsService();
            var template = CreateTemplate();
            var assembleDocumentSettings = new AssembleDocumentSettings();

            using (var answers = new StringReader(encryptedAnswers))
            {
                var assembledDocumentResult = service.AssembleDocument(template, answers, assembleDocumentSettings, "logref");

                using (var fileStream = System.IO.File.Create(@"c:\temp\output" + assembledDocumentResult.Document.FileExtension))
                {
                    assembledDocumentResult.Document.Content.CopyTo(fileStream);
                }
            }
        }
        /// <summary>
        /// <c>AssembleDocument</c> assembles (creates) a document from the given template, answers and settings.
        /// </summary>
        /// <param name="template">An instance of the Template class, from which the document will be assembled.</param>
        /// <param name="answers">The set of answers that will be applied to the template to assemble the document.</param>
        /// <param name="settings">Settings that will be used to assemble the document.
        /// These settings include the assembled document format (file extension), markup syntax, how to display fields with unanswered variables, etc</param>
        /// <param name="logRef">A string to display in logs related to this request.</param>
        /// <returns>returns information about the assembled document, the document type, the unanswered variables, the resulting answers, etc.</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(@"WebService.Services.AssembleDocument: The ""template"" parameter passed in was null, logRef: {0}.", logStr));
            }

            if (settings == null)
            {
                settings = new AssembleDocumentSettings();
            }

            AssembleDocumentResult result    = null;
            AssemblyResult         asmResult = null;

            using (Proxy client = GetProxy())
            {
                OutputFormat outputFormat;
                if (template.GeneratesDocument)
                {
                    outputFormat = ConvertFormat(settings.Format);
                }
                else                 // avoid requesting any output other than answers from interview templates! (for the HDS web service)
                {
                    outputFormat = OutputFormat.Answers;
                }
                AssemblyOptions assemblyOptions = ConvertOptions(settings);
                string          fileName        = GetRelativePath(template.GetFullPath());
                asmResult = client.AssembleDocument(
                    fileName,
                    answers == null ? null : new BinaryObject[] { Util.GetBinaryObjectFromTextReader(answers) },                     // answers
                    outputFormat,
                    assemblyOptions,
                    null);
                SafeCloseClient(client, logRef);
            }

            if (asmResult != null)
            {
                result = Util.ConvertAssemblyResult(template, asmResult, settings.Format);
            }

            return(result);
        }
Exemplo n.º 13
0
        /// <summary>
        /// Called by the host application when answers have been posted back from a browser interview.
        /// </summary>
        /// <param name="interviewAnswers">The answers that were posted back from the interview.</param>
        public void FinishInterview(TextReader interviewAnswers)
        {
            // overlay interviewAnswers over the session answer set,
            AnswerCollection.OverlayXml(interviewAnswers);

            // 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;
            }
            if (workItem != null && workItem is InterviewWorkItem)
            {
                // if the current template is an interview template
                if (workItem.Template.TemplateType == TemplateType.InterviewOnly)
                {
                    //     "assemble" it...
                    AssembleDocumentSettings asmOpts = new AssembleDocumentSettings(DefaultAssemblySettings);
                    asmOpts.Format = DocumentType.Native;
                    // if this is not the last work item in the queue, force retention of transient answers
                    asmOpts.RetainTransientAnswers |= (itemIndex < _workItems.Count - 1);

                    // assemble the item
                    using (var asmResult = _service.AssembleDocument(workItem.Template, new StringReader(AnswerCollection.XmlAnswers), asmOpts, ""))
                    {
                        // replace the session answers with the post-assembly answers
                        AnswerCollection.ReadXml(asmResult.Answers);
                        // add pendingAssemblies to the queue as necessary
                        InsertNewWorkItems(asmResult.PendingAssemblies, itemIndex);
                    }
                }
                // mark this interview workitem as complete.  (This will cause the WorkSession to advance to the next workItem.)
                CurrentWorkItem.IsCompleted = true;
            }
        }
Exemplo n.º 14
0
        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);
        }
Exemplo n.º 15
0
 /// <summary>
 /// Assembles a document from the specified template and answersets.
 /// </summary>
 /// <param name="template">The template to use with the request.</param>
 /// <param name="answers">The answers to use with the request.</param>
 /// <param name="settings">The options to use when assembling the document.</param>
 /// <param name="billingRef">This parameter lets you specify information that will be included in usage logs for this call. For example, you can use a string to uniquely identify the end user that initiated the request and/or the context in which the call was made. When you review usage logs, you can then see which end users initiated each request. That information could then be used to pass costs on to those end users if desired.</param>
 /// <returns>An <c>AssemblyResult</c>, which contains the assembled documents, pending assemblies, and unanswered variables from the assembly.</returns>
 public AssemblyResult AssembleDocument(Template template, string answers = null, AssembleDocumentSettings settings = null, string billingRef = null)
 {
     return((AssemblyResult)TryWithoutAndWithPackage(
                uploadPackage => AssembleDocumentImpl(template, answers, settings, billingRef, uploadPackage)));
 }
Exemplo n.º 16
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="template"></param>
 /// <param name="answers"></param>
 /// <param name="settings"></param>
 /// <param name="billingRef">This parameter lets you specify information that will be included in usage logs for this call. For example, you can use a string to uniquely identify the end user that initiated the request and/or the context in which the call was made. When you review usage logs, you can then see which end users initiated each request. That information could then be used to pass costs on to those end users if desired.</param>
 /// <param name="uploadPackage">Indicates if the package should be uploaded (forcefully) or not. This should only be true if the package does not already exist in the Cloud Services cache.</param>
 /// <returns></returns>
 protected internal abstract AssemblyResult AssembleDocumentImpl(
     Template template,
     string answers,
     AssembleDocumentSettings settings,
     string billingRef,
     bool uploadPackage);
Exemplo n.º 17
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="template">The template to assemble.</param>
        /// <param name="answers">The answers to use when assembling the document.</param>
        /// <param name="settings">The settings to use when assembling the document.</param>
        /// <param name="billingRef">This parameter lets you specify information that will be included in usage logs for this call. For example, you can use a string to uniquely identify the end user that initiated the request and/or the context in which the call was made. When you review usage logs, you can then see which end users initiated each request. That information could then be used to pass costs on to those end users if desired.</param>
        /// <param name="uploadPackage">Indicates if the package should be uploaded (forcefully) or not. This should only be true if the package does not already exist in the Cloud Services cache.</param>
        /// <returns></returns>
        protected internal override AssemblyResult AssembleDocumentImpl(
            Template template,
            string answers,
            AssembleDocumentSettings settings,
            string billingRef,
            bool uploadPackage)
        {
            var timestamp = DateTime.UtcNow;

            if (!(template.Location is PackageTemplateLocation))
            {
                throw new Exception("HotDocs Cloud Services requires the use of template packages. Please use a PackageTemplateLocation derivative.");
            }
            PackageTemplateLocation packageTemplateLocation = (PackageTemplateLocation)template.Location;

            // Determine the output format to use (e.g., translate settings.Type to Contracts.InterviewFormat)
            OutputFormat outputFormat;

            switch (settings.Format)
            {
            case DocumentType.HFD:
                outputFormat = OutputFormat.HFD;
                break;

            case DocumentType.HPD:
                outputFormat = OutputFormat.HPD;
                break;

            case DocumentType.HTML:
                outputFormat = OutputFormat.HTML;
                break;

            case DocumentType.HTMLwDataURIs:
                outputFormat = OutputFormat.HTMLwDataURIs;
                break;

            case DocumentType.MHTML:
                outputFormat = OutputFormat.MHTML;
                break;

            case DocumentType.Native:
                outputFormat = OutputFormat.Native;
                break;

            case DocumentType.PDF:
                outputFormat = OutputFormat.PDF;
                break;

            case DocumentType.PlainText:
                outputFormat = OutputFormat.PlainText;
                break;

            case DocumentType.WordDOC:
                outputFormat = OutputFormat.DOCX;
                break;

            case DocumentType.WordDOCX:
                outputFormat = OutputFormat.DOCX;
                break;

            case DocumentType.WordPerfect:
                outputFormat = OutputFormat.WPD;
                break;

            case DocumentType.WordRTF:
                outputFormat = OutputFormat.RTF;
                break;

            default:
                outputFormat = OutputFormat.None;
                break;
            }

            // Always include the Answers output
            outputFormat |= OutputFormat.Answers;

            string hmac = HMAC.CalculateHMAC(
                SigningKey,
                timestamp,
                SubscriberId,
                packageTemplateLocation.PackageID,
                template.FileName,
                uploadPackage,
                billingRef,
                outputFormat,
                settings.Settings);

            return(_proxy.AssembleDocument(
                       SubscriberId,
                       packageTemplateLocation.PackageID,
                       template.FileName,
                       GetBinaryObjectArrayFromString(answers),
                       outputFormat,
                       settings.OutputOptions,
                       settings.Settings,
                       billingRef,
                       timestamp,
                       GetPackageIfNeeded(packageTemplateLocation, uploadPackage),
                       hmac));
        }
Exemplo n.º 18
0
        public AssembleDocumentResult AssembleDocument(Template template, TextReader answers, AssembleDocumentSettings settings, string logRef)
        {
            using (var client = new HttpClient())
            {
                AssembleDocumentResult adr = null;
                var stringContent = new StringContent(answers.ReadToEnd());
                var packageTemplateLocation = (PackageTemplateLocation)template.Location;
                var packageId = packageTemplateLocation.PackageID;

                OutputFormat of = ConvertFormat(settings.Format);

                var urlBuilder = new StringBuilder(string.Format(HostAddress + "/assemble/0/{0}/?templatename={1}&format={2}", packageId, HttpUtility.UrlEncode(template.FileName), of));

                if (settings.Settings != null)
                {
                    foreach (KeyValuePair<string, string> kv in settings.Settings)
                    {
                        urlBuilder.AppendFormat("&{0}={1}", kv.Key, kv.Value ?? "");
                    }
                }

                var result = client.PostAsync(urlBuilder.ToString(), stringContent).Result;

                var _parser = new MultipartMimeParser();

                HandleErrorStream(result, result.IsSuccessStatusCode);
                var streamResult = result.Content.ReadAsStreamAsync().Result;

                var outputDir = Path.GetTempPath();
                Directory.CreateDirectory(outputDir);
                using (var resultsStream = new MemoryStream())
                {
                    // Each part is written to a file whose name is specified in the content-disposition
                    // header, except for the AssemblyResult part, which has a file name of "meta0.xml",
                    // and is parsed into an AssemblyResult object.
                    _parser.WritePartsToStreams(
                        streamResult,
                        h =>
                        {
                            string fileName = GetFileNameFromHeaders(h);
                            if (fileName != null)
                            {
                                if (fileName.Equals("meta0.xml", StringComparison.OrdinalIgnoreCase))
                                {
                                    return resultsStream;
                                }

                                return new FileStream(Path.Combine(outputDir, fileName), FileMode.Create);
                            }
                            return Stream.Null;
                        },
                        (new ContentType(result.Content.Headers.ContentType.ToString())).Boundary);

                    if (resultsStream.Position > 0)
                    {
                        resultsStream.Position = 0;
                        var serializer = new XmlSerializer(typeof(AssemblyResult));
                        var asmResult = (AssemblyResult)serializer.Deserialize(resultsStream);
                        if (asmResult != null)
                            adr = Util.ConvertAssemblyResult(template, asmResult, settings.Format);
                    }
                }
                return adr;
            }
        }
Exemplo n.º 19
0
 /// <summary>
 /// Assembles a document from the specified template and answersets.
 /// </summary>
 /// <param name="template">The template to use with the request.</param>
 /// <param name="answers">The answers to use with the request.</param>
 /// <param name="settings">The options to use when assembling the document.</param>
 /// <param name="billingRef">This parameter lets you specify information that will be included in usage logs for this call. For example, you can use a string to uniquely identify the end user that initiated the request and/or the context in which the call was made. When you review usage logs, you can then see which end users initiated each request. That information could then be used to pass costs on to those end users if desired.</param>
 /// <returns>An <c>AssemblyResult</c>, which contains the assembled documents, pending assemblies, and unanswered variables from the assembly.</returns>
 public AssemblyResult AssembleDocument(Template template, string answers=null, AssembleDocumentSettings settings=null, string billingRef=null)
 {
     return (AssemblyResult)TryWithoutAndWithPackage(
         uploadPackage => AssembleDocumentImpl(template, answers, settings, billingRef, uploadPackage));
 }
Exemplo n.º 20
0
        /// <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))
                {
                    result.Add(asmResult.ExtractDocument());
                    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
                }
                // mark the current workitem as complete
                docWorkItem.IsCompleted = true;
                // advance to the next workitem
                workItem = (++itemIndex >= _workItems.Count) ? null : _workItems[itemIndex];
            }
            return result.ToArray();
        }
Exemplo n.º 21
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="template">The template to assemble.</param>
        /// <param name="answers">The answers to use when assembling the document.</param>
        /// <param name="settings">The settings to use when assembling the document.</param>
        /// <param name="billingRef">This parameter lets you specify information that will be included in usage logs for this call. For example, you can use a string to uniquely identify the end user that initiated the request and/or the context in which the call was made. When you review usage logs, you can then see which end users initiated each request. That information could then be used to pass costs on to those end users if desired.</param>
        /// <param name="uploadPackage">Indicates if the package should be uploaded (forcefully) or not. This should only be true if the package does not already exist in the Cloud Services cache.</param>
        /// <returns></returns>
        protected internal override AssemblyResult AssembleDocumentImpl(
			Template template,
			string answers,
			AssembleDocumentSettings settings,
			string billingRef,
			bool uploadPackage)
        {
            var timestamp = DateTime.UtcNow;
            if (!(template.Location is PackageTemplateLocation))
                throw new Exception("HotDocs Cloud Services requires the use of template packages. Please use a PackageTemplateLocation derivative.");
            PackageTemplateLocation packageTemplateLocation = (PackageTemplateLocation)template.Location;

            // Determine the output format to use (e.g., translate settings.Type to Contracts.InterviewFormat)
            OutputFormat outputFormat;
            switch (settings.Format)
            {
                case DocumentType.HFD:
                    outputFormat = OutputFormat.HFD;
                    break;
                case DocumentType.HPD:
                    outputFormat = OutputFormat.HPD;
                    break;
                case DocumentType.HTML:
                    outputFormat = OutputFormat.HTML;
                    break;
                case DocumentType.HTMLwDataURIs:
                    outputFormat = OutputFormat.HTMLwDataURIs;
                    break;
                case DocumentType.MHTML:
                    outputFormat = OutputFormat.MHTML;
                    break;
                case DocumentType.Native:
                    outputFormat = OutputFormat.Native;
                    break;
                case DocumentType.PDF:
                    outputFormat = OutputFormat.PDF;
                    break;
                case DocumentType.PlainText:
                    outputFormat = OutputFormat.PlainText;
                    break;
                case DocumentType.WordDOC:
                    outputFormat = OutputFormat.DOCX;
                    break;
                case DocumentType.WordDOCX:
                    outputFormat = OutputFormat.DOCX;
                    break;
                case DocumentType.WordPerfect:
                    outputFormat = OutputFormat.WPD;
                    break;
                case DocumentType.WordRTF:
                    outputFormat = OutputFormat.RTF;
                    break;
                default:
                    outputFormat = OutputFormat.None;
                    break;
            }

            // Always include the Answers output
            outputFormat |= OutputFormat.Answers;

            string hmac = HMAC.CalculateHMAC(
                SigningKey,
                timestamp,
                SubscriberId,
                packageTemplateLocation.PackageID,
                template.FileName,
                uploadPackage,
                billingRef,
                outputFormat,
                settings.Settings);

            return _proxy.AssembleDocument(
                SubscriberId,
                packageTemplateLocation.PackageID,
                template.FileName,
                GetBinaryObjectArrayFromString(answers),
                outputFormat,
                settings.OutputOptions,
                settings.Settings,
                billingRef,
                timestamp,
                GetPackageIfNeeded(packageTemplateLocation, uploadPackage),
                hmac);
        }
Exemplo n.º 22
0
        /// <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);
        }
Exemplo n.º 23
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="template"></param>
        /// <param name="answers"></param>
        /// <param name="settings"></param>
        /// <param name="billingRef">This parameter lets you specify information that will be included in usage logs for this call. For example, you can use a string to uniquely identify the end user that initiated the request and/or the context in which the call was made. When you review usage logs, you can then see which end users initiated each request. That information could then be used to pass costs on to those end users if desired.</param>
        /// <param name="uploadPackage">Indicates if the package should be uploaded (forcefully) or not. This should only be true if the package does not already exist in the Cloud Services cache.</param>
        /// <returns></returns>
        protected internal override AssemblyResult AssembleDocumentImpl(
            Template template,
            string answers,
            AssembleDocumentSettings settings,
            string billingRef,
            bool uploadPackage)
        {
            if (!(template.Location is PackageTemplateLocation))
                throw new Exception("HotDocs Cloud Services requires the use of template packages. Please use a PackageTemplateLocation derivative.");
            PackageTemplateLocation packageTemplateLocation = (PackageTemplateLocation)template.Location;

            if (uploadPackage)
            {
                UploadPackage(packageTemplateLocation.PackageID, billingRef, packageTemplateLocation.GetPackageStream());
            }

            var timestamp = DateTime.UtcNow;

            string hmac = HMAC.CalculateHMAC(
                SigningKey,
                timestamp,
                SubscriberId,
                packageTemplateLocation.PackageID,
                template.FileName,
                false,
                billingRef,
                settings.Format,
                settings.Settings);

            StringBuilder urlBuilder = new StringBuilder(string.Format(
                "{0}/RestfulSvc.svc/assemble/{1}/{2}/{3}?format={4}&billingref={5}",
                EndpointAddress, SubscriberId, packageTemplateLocation.PackageID, template.FileName ?? "",
                settings.Format.ToString(), billingRef));

            if (settings.Settings != null)
            {
                foreach (KeyValuePair<string, string> kv in settings.Settings)
                {
                    urlBuilder.AppendFormat("&{0}={1}", kv.Key, kv.Value ?? "");
                }
            }

            var outputOptionsPairs = GetOutputOptionsPairs(settings.OutputOptions);
            foreach (KeyValuePair<string, string> kv in outputOptionsPairs)
            {
                urlBuilder.AppendFormat("&{0}={1}", kv.Key, kv.Value ?? "");
            }

            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(urlBuilder.ToString());
            request.Method = "POST";
            request.ContentType = "text/xml";
            request.Headers["x-hd-date"] = timestamp.ToString("r");
            request.Headers[HttpRequestHeader.Authorization] = hmac;
            request.Timeout = 10 * 60 * 1000; // Ten minute timeout
            request.ContentLength = answers != null ? answers.Length : 0L;

            if (!string.IsNullOrEmpty(ProxyServerAddress))
            {
                request.Proxy = new WebProxy(ProxyServerAddress);
            }

            if (answers != null)
            {
                byte[] data = Encoding.UTF8.GetBytes(answers);
                request.GetRequestStream().Write(data, 0, data.Length);
            }
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();

            Directory.CreateDirectory(OutputDir);
            using (var resultsStream = new MemoryStream())
            {
                // Each part is written to a file whose name is specified in the content-disposition
                // header, except for the AssemblyResult part, which has a file name of "meta0.xml",
                // and is parsed into an AssemblyResult object.
                _parser.WritePartsToStreams(
                    response.GetResponseStream(),
                    h =>
                    {
                        string fileName = GetFileNameFromHeaders(h);
                        if (fileName != null)
                        {
                            if (fileName.Equals("meta0.xml", StringComparison.OrdinalIgnoreCase))
                            {
                                return resultsStream;
                            }

                            return new FileStream(Path.Combine(OutputDir, fileName), FileMode.Create);
                        }
                        return Stream.Null;
                    },
                    (new ContentType(response.ContentType)).Boundary);

                if (resultsStream.Position > 0)
                {
                    resultsStream.Position = 0;
                    var serializer = new XmlSerializer(typeof(AssemblyResult));
                    return (AssemblyResult)serializer.Deserialize(resultsStream);
                }
                return null;
            }
        }
Exemplo n.º 24
0
        /// <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 = "")
        {
            if (template == null)
            {
                throw new ArgumentNullException("template");
            }

            using (var client = new HttpClient())
            {
                AssembleDocumentResult adr  = null;
                var packageTemplateLocation = (PackageTemplateLocation)template.Location;
                var packageId = packageTemplateLocation.PackageID;
                var of        = ConvertFormat(settings.Format);
                var timestamp = DateTime.UtcNow;

                var hmac = HMAC.CalculateHMAC(
                    SigningKey,
                    timestamp,
                    SubscriberId,
                    packageId,
                    template.FileName,
                    false,
                    logRef,
                    of,
                    settings.Settings);

                var urlBuilder =
                    new StringBuilder().AppendFormat("{0}/assemble/{1}/{2}/{3}?" +
                                                     "format={4}&" +
                                                     "encodefilenames={5}&" +
                                                     "billingref={6}{7}",
                                                     HostAddress, SubscriberId, packageId, Uri.EscapeDataString(template.FileName),
                                                     of,
                                                     true,
                                                     Uri.EscapeDataString(logRef),
                                                     GetRetrieveFromHubParam());

                if (settings.Settings != null)
                {
                    foreach (var kv in settings.Settings)
                    {
                        urlBuilder.AppendFormat("&{0}={1}", kv.Key, kv.Value ?? "");
                    }
                }

                var request = new HttpRequestMessage
                {
                    RequestUri = new Uri(urlBuilder.ToString()),
                    Method     = HttpMethod.Post
                };

                request.Headers.Add("x-hd-date", timestamp.ToString("yyyy-MM-ddTHH:mm:ssZ"));
                request.Headers.Authorization = new AuthenticationHeaderValue("basic", hmac);

                var stringContent = answers == null
                    ? new StringContent(string.Empty)
                    : new StringContent(answers.ReadToEnd());

                request.Content = stringContent;

                request.Content.Headers.TryAddWithoutValidation("Content-Type", "text/xml");

                var result = client.SendAsync(request).Result;

                var parser = new MultipartMimeParser();

                HandleStatusCode(result);

                var streamResult = result.Content.ReadAsStreamAsync().Result;

                var streams = new List <MemoryStream>();

                using (var resultsStream = new MemoryStream())
                {
                    // Each part is written to a file whose name is specified in the content-disposition
                    // header, except for the AssemblyResult part, which has a file name of "meta0.xml",
                    // and is parsed into an AssemblyResult object.
                    parser.WritePartsToStreams(
                        streamResult,
                        h =>
                    {
                        var fileName = GetFileNameFromHeaders(h);
                        if (fileName == null)
                        {
                            return(Stream.Null);
                        }

                        if (fileName.Equals("meta0.xml", StringComparison.OrdinalIgnoreCase))
                        {
                            return(resultsStream);
                        }

                        var stream = new MemoryStream();
                        streams.Add(stream);
                        return(stream);
                    },
                        (new ContentType(result.Content.Headers.ContentType.ToString())).Boundary);

                    if (resultsStream.Position <= 0)
                    {
                        return(null);
                    }

                    resultsStream.Position = 0;
                    var serializer = new XmlSerializer(typeof(AssemblyResult));
                    var asmResult  = (AssemblyResult)serializer.Deserialize(resultsStream);

                    if (asmResult == null)
                    {
                        return(adr);
                    }

                    for (var i = 0; i < asmResult.Documents.Length; i++)
                    {
                        asmResult.Documents[i].Data = streams[i].ToArray();
                        streams[i].Dispose();
                    }

                    adr = Util.ConvertAssemblyResult(template, asmResult, settings.Format);
                }

                return(adr);
            }
        }
 AssemblyOptions ConvertOptions(AssembleDocumentSettings settings)
 {
     AssemblyOptions assemblyOptions = new AssemblyOptions();
     assemblyOptions = AssemblyOptions.None;
     if (settings.UseMarkupSyntax)
         assemblyOptions |= AssemblyOptions.MarkupView;
     return assemblyOptions;
 }
Exemplo n.º 26
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="template"></param>
        /// <param name="answers"></param>
        /// <param name="settings"></param>
        /// <param name="billingRef">This parameter lets you specify information that will be included in usage logs for this call. For example, you can use a string to uniquely identify the end user that initiated the request and/or the context in which the call was made. When you review usage logs, you can then see which end users initiated each request. That information could then be used to pass costs on to those end users if desired.</param>
        /// <param name="uploadPackage">Indicates if the package should be uploaded (forcefully) or not. This should only be true if the package does not already exist in the Cloud Services cache.</param>
        /// <returns></returns>
        protected internal override AssemblyResult AssembleDocumentImpl(
            Template template,
            string answers,
            AssembleDocumentSettings settings,
            string billingRef,
            bool uploadPackage)
        {
            if (!(template.Location is PackageTemplateLocation))
            {
                throw new Exception("HotDocs Cloud Services requires the use of template packages. Please use a PackageTemplateLocation derivative.");
            }
            PackageTemplateLocation packageTemplateLocation = (PackageTemplateLocation)template.Location;

            if (uploadPackage)
            {
                UploadPackage(packageTemplateLocation.PackageID, billingRef, packageTemplateLocation.GetPackageStream());
            }

            var timestamp = DateTime.UtcNow;

            string hmac = HMAC.CalculateHMAC(
                SigningKey,
                timestamp,
                SubscriberId,
                packageTemplateLocation.PackageID,
                template.FileName,
                false,
                billingRef,
                settings.Format,
                settings.Settings);

            StringBuilder urlBuilder = new StringBuilder(string.Format(
                                                             "{0}/assemble/{1}/{2}/{3}?format={4}&billingref={5}",
                                                             EndpointAddress, SubscriberId, packageTemplateLocation.PackageID, template.FileName ?? "",
                                                             settings.Format.ToString(), billingRef));

            if (settings.Settings != null)
            {
                foreach (KeyValuePair <string, string> kv in settings.Settings)
                {
                    urlBuilder.AppendFormat("&{0}={1}", kv.Key, kv.Value ?? "");
                }
            }

            // Note that the Comments and/or Keywords values, and therefore the resulting URL, could
            // be extremely long.  Consumers should be aware that overly-long URLs could be rejected
            // by Cloud Services.  If the Comments and/or Keywords values cannot be truncated, the
            // consumer should use the SOAP version of the client.
            var outputOptionsPairs = GetOutputOptionsPairs(settings.OutputOptions);

            foreach (KeyValuePair <string, string> kv in outputOptionsPairs)
            {
                urlBuilder.AppendFormat("&{0}={1}", kv.Key, kv.Value ?? "");
            }

            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(urlBuilder.ToString());

            request.Method               = "POST";
            request.ContentType          = "text/xml";
            request.Headers["x-hd-date"] = timestamp.ToString("r");
            request.Headers[HttpRequestHeader.Authorization] = hmac;
            request.Timeout       = 10 * 60 * 1000;       // Ten minute timeout
            request.ContentLength = answers != null ? answers.Length : 0L;

            if (!string.IsNullOrEmpty(ProxyServerAddress))
            {
                request.Proxy = new WebProxy(ProxyServerAddress);
            }

            if (answers != null)
            {
                byte[] data = Encoding.UTF8.GetBytes(answers);
                request.GetRequestStream().Write(data, 0, data.Length);
            }
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();

            Directory.CreateDirectory(OutputDir);
            using (var resultsStream = new MemoryStream())
            {
                // Each part is written to a file whose name is specified in the content-disposition
                // header, except for the AssemblyResult part, which has a file name of "meta0.xml",
                // and is parsed into an AssemblyResult object.
                _parser.WritePartsToStreams(
                    response.GetResponseStream(),
                    h =>
                {
                    string fileName = GetFileNameFromHeaders(h);
                    if (fileName != null)
                    {
                        if (fileName.Equals("meta0.xml", StringComparison.OrdinalIgnoreCase))
                        {
                            return(resultsStream);
                        }

                        return(new FileStream(Path.Combine(OutputDir, fileName), FileMode.Create));
                    }
                    return(Stream.Null);
                },
                    (new ContentType(response.ContentType)).Boundary);

                if (resultsStream.Position > 0)
                {
                    resultsStream.Position = 0;
                    var serializer = new XmlSerializer(typeof(AssemblyResult));
                    return((AssemblyResult)serializer.Deserialize(resultsStream));
                }
                return(null);
            }
        }
Exemplo n.º 27
0
        /// <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;
        }
Exemplo n.º 28
0
 /// <summary>
 /// Creates a WorkSession object that a host application can use to step through the process of presenting
 /// all the interviews and assembling all the documents that may result from the given template.
 /// </summary>
 /// <param name="service">An object implementing the IServices interface, encapsulating the instance of
 /// HotDocs Server with which the host app is communicating.</param>
 /// <param name="template">The template upon which this WorkSession is based. The initial interview and/or
 /// document work items in the WorkSession will be based on this template (including its Switches property).</param>
 /// <param name="answers">A collection of XML answers to use as a starting point for the work session.
 /// The initial interview (if any) will be pre-populated with these answers, and the subsequent generation
 /// of documents will have access to these answers as well.</param>
 public WorkSession(IServices service, Template template, TextReader answers)
 {
     _service = service;
     AnswerCollection = new AnswerCollection();
     if (answers != null)
         AnswerCollection.ReadXml(answers);
     DefaultAssemblySettings = new AssembleDocumentSettings();
     DefaultInterviewSettings = new InterviewSettings();
     // add the work items
     _workItems = new List<WorkItem>();
     if (template.HasInterview)
         _workItems.Add(new InterviewWorkItem(template));
     if (template.GeneratesDocument)
         _workItems.Add(new DocumentWorkItem(template));
 }
Exemplo n.º 29
0
 /// <summary>
 /// 
 /// </summary>
 /// <param name="template"></param>
 /// <param name="answers"></param>
 /// <param name="settings"></param>
 /// <param name="billingRef">This parameter lets you specify information that will be included in usage logs for this call. For example, you can use a string to uniquely identify the end user that initiated the request and/or the context in which the call was made. When you review usage logs, you can then see which end users initiated each request. That information could then be used to pass costs on to those end users if desired.</param>
 /// <param name="uploadPackage">Indicates if the package should be uploaded (forcefully) or not. This should only be true if the package does not already exist in the Cloud Services cache.</param>
 /// <returns></returns>
 protected internal abstract AssemblyResult AssembleDocumentImpl(
     Template template,
     string answers,
     AssembleDocumentSettings settings,
     string billingRef,
     bool uploadPackage);
Exemplo n.º 30
0
        public AssembleDocumentResult AssembleDocument(Template template, TextReader answers,
                                                       AssembleDocumentSettings settings, string logRef)
        {
            using (var client = new HttpClient())
            {
                AssembleDocumentResult adr     = null;
                var    stringContent           = new StringContent(answers.ReadToEnd());
                var    packageTemplateLocation = (PackageTemplateLocation)template.Location;
                string packageId = packageTemplateLocation.PackageID;

                OutputFormat of = ConvertFormat(settings.Format);

                var urlBuilder =
                    new StringBuilder(string.Format(HostAddress + "/assemble/0/{0}/{1}?format={2}&encodefilenames={3}", packageId,
                                                    HttpUtility.UrlEncode(template.FileName), of, true));

                if (settings.Settings != null)
                {
                    foreach (var kv in settings.Settings)
                    {
                        urlBuilder.AppendFormat("&{0}={1}", kv.Key, kv.Value ?? "");
                    }
                }

                HttpResponseMessage result = client.PostAsync(urlBuilder.ToString(), stringContent).Result;

                var _parser = new MultipartMimeParser();

                HandleErrorStream(result, result.IsSuccessStatusCode);
                Stream streamResult = result.Content.ReadAsStreamAsync().Result;

                string outputDir = Path.GetTempPath();
                Directory.CreateDirectory(outputDir);
                using (var resultsStream = new MemoryStream())
                {
                    // Each part is written to a file whose name is specified in the content-disposition
                    // header, except for the AssemblyResult part, which has a file name of "meta0.xml",
                    // and is parsed into an AssemblyResult object.
                    _parser.WritePartsToStreams(
                        streamResult,
                        h =>
                    {
                        string fileName = GetFileNameFromHeaders(h);
                        if (fileName != null)
                        {
                            if (fileName.Equals("meta0.xml", StringComparison.OrdinalIgnoreCase))
                            {
                                return(resultsStream);
                            }

                            return(new FileStream(Path.Combine(outputDir, fileName), FileMode.Create));
                        }
                        return(Stream.Null);
                    },
                        (new ContentType(result.Content.Headers.ContentType.ToString())).Boundary);

                    if (resultsStream.Position > 0)
                    {
                        resultsStream.Position = 0;
                        var serializer = new XmlSerializer(typeof(AssemblyResult));
                        var asmResult  = (AssemblyResult)serializer.Deserialize(resultsStream);
                        if (asmResult != null)
                        {
                            adr = Util.ConvertAssemblyResult(template, asmResult, settings.Format);
                        }
                    }
                }
                return(adr);
            }
        }