Saving PDF files to the server file system


Suppose we need to save a PDF file to the file system instead of sending it to the user's browser. I will explain later why we would need this.

The SourceWritingTransformer could be used for this, but pipeline components having side effects aren't considered to be a good practice. So we describe here a more "modern" and correct solution using the cocoon.processPipelineTo method from flowscript, to save the result of a pipeline to a file.


<map:pipeline internal-only="false">
  <map:match pattern="**/*.do">
    <map:generate src="{1}/{2}.xml"/>
    <map:transform src="convert.xsl" label="content"/>
    <map:serialize type="fo2pdf"/>

<map:flow language="javascript">
  <map:script src="pdf.flow"/>

<map:match pattern="**/*.pdf">
  <map:call function="makepdf">
    <map:parameter name="folder" value="{realpath:/}"/>

function makepdf() {
   var xml_file;
   var pdf_file;
   var outstreamPDF;

   // the parameter passed to the script from the pipeline. 
   // This is the real path to the application context
   var folder =["folder"]);           

   try {      
      // creating links to files
      pdf_file = folder + "/target_folder/book.pdf");
      xml_file = folder + "/source_folder/book.xml");

      // creating outputstream to dump the results of conversion to the file
      outstreamPDF = new pdf_file );

      // calling cocoon pipeline using processPipelineTo() method and dumping the results to the outputstream
      cocoon.processPipelineTo( "blablabla/", null, outstreamPDF );

      // do not forget to close the outputstream

      // since the result is dumped to the filesystem we need to send smth. to the browser
      // to make it happy. So let's send just a usual .txt file with OK message
      cocoon.sendPage("yes.txt", null);

   } catch( ex ) {
      // Smth. went wrong. Sending a error.txt file to the browser
      cocoon.sendPage("error.txt", null);

<map:pipeline internal-only="true">

Points of further improvement

<map:match pattern="">
  <map:call function="makepdf">
   <map:parameter name="folder" value="{realpath:/}"/>

This match will not take the name of the file to convert and it is not supposed to be called from browser (though you can type http://<host>/blablabla/ and run the flow script). Instead this match will be called from cron.

SavingFilesToFileSystem (last edited 2009-09-20 23:40:50 by localhost)