/// <summary> /// Helper method for instantiating the Xslt Transform options (e.g. XmlUrlResolver, XmlWriterSettings, etc.) for use /// during the execution of the Xslt Transform. /// This can be overridden by implementing classes to customize this behaviour as needed. /// </summary> /// <returns></returns> protected virtual XslTransformEngineOptions CreateXsltTransformEngineOptions() { var xmlUrlResolver = new XmlUrlExtendedResolver(this.XsltFileInfo.Directory); var xsltTransformOptions = new XslTransformEngineOptions() { XsltDocumentResolver = xmlUrlResolver, XsltLoadResolver = xmlUrlResolver }; return(xsltTransformOptions); }
public void LoadXslt(XDocument xXmlInputDoc, XDocument xXslFOXsltDoc, XslFOPdfOptions pdfOptions) { TriggerLoadStart(); //NOTE: We Lock this entire method because it is the Core method for the UI Control and we don't want this Control // to allow primary processing by more than one Thread at a time. Though Background threads are launched // to not block the UI thread, this is not intended to process multiple items at a Time and this // block contains code where critical values are being modified. lock (_threadLock) { ClearLog(); var uiTaskFactory = new TaskFactory(_uiThreadScheduler); LogItem("XslFO Pdf Render Process Starting."); var timerOverall = Stopwatch.StartNew(); //Execute the Work Async, with a Continuation back on the UI Thread when completed. var workerTask = Task.Factory.StartNew <XslFORenderFileOutput>(() => { //*********************************************************** //Initialize and Compile the XsltTransformer //*********************************************************** LogItem("Xslt Compile Starting."); var timer = Stopwatch.StartNew(); var xmlResolver = new XmlUrlExtendedResolver(pdfOptions.BaseDirectory); XslTransformEngine xslTransformer = xXslFOXsltDoc.CreateXslTransformEngine(new XslTransformEngineOptions() { XsltDocumentResolver = xmlResolver, XsltLoadResolver = xmlResolver }); LogItem("Xslt Compile Completed in [{0}] seconds.", timer.Elapsed.TotalSeconds); //*********************************************************** //Execute the Xslt Transformation //*********************************************************** LogItem("Xslt Execution Starting."); timer.Restart(); var xXslFOResultsDoc = xslTransformer.TransformToXDocument(xXmlInputDoc); LogItem("Xslt Execution Completed in [{0}] seconds.", timer.Elapsed.TotalSeconds); //*********************************************************** //Render the XslFO results into a Pdf //*********************************************************** //return xXmlInputDoc.TransformToPdfFile(xslTransformer, tempPdfFileInfo, pdfOptions, _fnFonetEventHandler, _fnFonetEventHandler, _fnXsltEventHandler); LogItem("Pdf Render Starting."); timer.Restart(); var XslFORenderedOutput = xXslFOResultsDoc.RenderXslFOToPdfFile(GetTempFileHelper(), new XslFORenderOptions() { PdfOptions = pdfOptions, RenderErrorHandler = GetFONetErrorHandler(), RenderEventHandler = GetFONetEventHandler() }); LogItem("Pdf Render Completed in [{0}] seconds.", timer.Elapsed.TotalSeconds); //*********************************************************** //Finally Return the Renderd Output from the the Background //Thread so that the results can be processed on the UI! //*********************************************************** return(XslFORenderedOutput); }).ContinueWith((workTask) => { //NOTE: Since this is the Followup Thread executing we must check to see if the Background Thread Faulted and handle it correctly. //This allows us to process the Exception back on the UI Thread instead of loosing it on the background thread. if (workTask.IsFaulted) { String renderSource = String.Empty; var innerException = workTask.Exception.InnerException; if (innerException is XslTransformEngineException) { renderSource = innerException.As <XslTransformEngineException>().XsltOutput; } else if (innerException is XslFORenderException) { renderSource = innerException.As <XslFORenderException>().RenderSource; } this.LoadStatus = XslFOViewerControlState.Unloaded; RaiseViewerError(new XslFOViewerEventArgs("Exception Occurred Processing the Transformer. Inner Exception Details: {0}".FormatArgs(workTask.Exception.GetMessages()), renderSource)); } else { //Halt and Wait for the workerTask's result! //NOTE: This DOES NOT Halt our UI, because this is only invoked within our ContinueWith continuation of the Parallel Task // which will handle the coordination and usher our results back to the UI Thread via the ThreadScheduler parameter below! LogItem("XslFO Pdf Render Process Completed in [{0}] seconds.", timerOverall.Elapsed.TotalSeconds); TriggerLoadFile(workTask.Result); } //Cleanup Temp File once loaded because Acrobat ActiveX Control no longer needs it //NOTE: Acrobot can browse the file after it is loaded, however Find/Search functionality is broken // so we cannot delete the file pre-maturely. //CleanupTempFileHelper(); }, _uiThreadScheduler); } }