Rework RunFopSaxon to not need file name and to work with Saxon 5.
authorTony Graham
Sat, 08 Feb 2014 22:33:52 +0000
changeset 26 606b0bf30b17
parent 25 506709a9527e
child 27 c34d37f2d7a1
Rework RunFopSaxon to not need file name and to work with Saxon 5.
FOPRunXSLTExt/examples/example5_saxon9_fop10.xsl
FOPRunXSLTExt/src/org/w3c/ppl/xslt/ext/fop/RunFOP.java
FOPRunXSLTExt/src/org/w3c/ppl/xslt/ext/fop/saxon/RunFOPSaxon.java
--- a/FOPRunXSLTExt/examples/example5_saxon9_fop10.xsl	Tue Dec 17 22:35:08 2013 +0000
+++ b/FOPRunXSLTExt/examples/example5_saxon9_fop10.xsl	Sat Feb 08 22:33:52 2014 +0000
@@ -14,25 +14,36 @@
     xmlns:fo="http://www.w3.org/1999/XSL/Format"
     xmlns:xs="http://www.w3.org/2001/XMLSchema"
     xmlns:runfop="http://org.w3c.ppl.xslt/saxon-extension"
-    exclude-result-prefixes="xs runfop">
+    xmlns:ahf="http://www.antennahouse.com/names/XSL/AreaTree"
+    exclude-result-prefixes="xs ahf runfop">
 
 <!-- Common templates for formatting FOPRunXSLTExt examples -->
 <xsl:import href="formatting.xsl" />
 
 <xsl:key name="boxes" match="box" use="true()" />
 
+<!-- FOP -->
 <xsl:key name="blocks" match="block[exists(@prod-id)]" use="@prod-id" />
+<!-- Antenna House -->
+<xsl:key name="blocks" match="ahf:BlockViewportArea[exists(@id)]" use="@id" />
 
 <xsl:param name="font-size" select="12" as="xs:double" />
 
 <!-- Where to write the output files. -->
 <xsl:param name="dest_dir" select="out" as="xs:string"/>
-<xsl:param name="area_tree_filename" />
-
+<!-- Allowed difference in height between outer box and formatted
+     paragraph text to be able to say paragraph fits within box and
+     stop further iterations. -->
 <xsl:param name="tolerance" select="1" as="xs:double" />
+<!-- Difference between font-size.minimum and font-size.maximum below
+     which it's not worth continuing. -->
+<xsl:param name="font-size-tolerance" select="0.01" as="xs:double" />
 
 <!-- Initial template -->
 <xsl:template name="main">
+  <xsl:message select="concat('tolerance: ', $tolerance)" />
+  <xsl:message select="concat('font-size-tolerance: ', $font-size-tolerance)" />
+
   <xsl:call-template name="do-box">
     <xsl:with-param name="font-size" select="$font-size" as="xs:double" />
     <xsl:with-param
@@ -42,6 +53,7 @@
     <xsl:with-param name="iteration" select="1" as="xs:integer" />
     <xsl:with-param name="iteration-max" select="30" as="xs:integer" tunnel="yes" />
     <xsl:with-param name="tolerance" select="$tolerance" as="xs:double" tunnel="yes" />
+    <xsl:with-param name="font-size-tolerance" select="$font-size-tolerance" as="xs:double" tunnel="yes" />
   </xsl:call-template>
 </xsl:template>
 
@@ -52,28 +64,12 @@
   <xsl:param name="iteration" select="1" as="xs:integer" />
   <xsl:param name="iteration-max" select="5" as="xs:integer" tunnel="yes" />
   <xsl:param name="tolerance" select="$tolerance" as="xs:double" tunnel="yes" />
-
-  <xsl:variable name="area_tree_filename_basename"
-                select="replace($area_tree_filename, '\.[^.]+$', '')"
-                as="xs:string" />
-  <xsl:variable name="area_tree_filename_suffix"
-                select="tokenize($area_tree_filename, '\.')[last()]"
-                as="xs:string" />
-  <xsl:variable name="area_tree_file"
-		select="concat($dest_dir,
-                               '/',
-                               $area_tree_filename_basename,
-                               '-',
-                               $iteration,
-                               '.',
-                               $area_tree_filename_suffix)"
-                as="xs:string" />
+  <xsl:param name="font-size-tolerance" select="$font-size-tolerance" as="xs:double" tunnel="yes" />
 
   <xsl:message>iteration = <xsl:value-of select="$iteration" /></xsl:message>
   <xsl:message>font-size = <xsl:value-of select="$font-size" /></xsl:message>
   <xsl:message>font-size.minimum = <xsl:value-of select="$font-size.minimum" /></xsl:message>
   <xsl:message>font-size.maximum = <xsl:value-of select="$font-size.maximum" /></xsl:message>
-  <xsl:message>Area tree filename = <xsl:value-of select="$area_tree_file" /></xsl:message>
 
   <xsl:variable name="overrides">
     <overrides>
@@ -93,13 +89,8 @@
   </xsl:variable>
 
   <xsl:variable
-      name="url"
-      select="runfop:area-tree-url($fo_tree, $area_tree_file)"
-      as="xs:string" />
-
-  <xsl:variable
       name="area-tree"
-      select="document($url)"
+      select="runfop:area-tree($fo_tree)"
       as="document-node()?" />
 
   <xsl:variable
@@ -112,6 +103,8 @@
       select="xs:double(substring-before(key('boxes', true())[1]/@height, 'pt'))"
       as="xs:double" />
 
+  <xsl:message select="concat('bpd: ', $bpd)" />
+  <xsl:message select="concat('target-height: ', $target-height)" />
   <xsl:choose>
     <xsl:when test="$iteration eq $iteration-max">
       <xsl:message>Maximum iterations.</xsl:message>
@@ -137,17 +130,6 @@
         <xsl:with-param name="iteration" select="$iteration + 1" as="xs:integer" />
       </xsl:call-template>
     </xsl:when>
-    <xsl:when test="$target-height - ($bpd div 1000) &lt;
-                    $target-height * $tolerance div $target-height">
-      <xsl:message>It fits.</xsl:message>
-      <xsl:apply-templates select="/">
-        <xsl:with-param
-            name="overrides"
-            select="$overrides"
-            as="document-node()"
-            tunnel="yes" />
-      </xsl:apply-templates>
-    </xsl:when>
     <xsl:otherwise>
       <xsl:call-template name="do-box">
         <xsl:with-param
--- a/FOPRunXSLTExt/src/org/w3c/ppl/xslt/ext/fop/RunFOP.java	Tue Dec 17 22:35:08 2013 +0000
+++ b/FOPRunXSLTExt/src/org/w3c/ppl/xslt/ext/fop/RunFOP.java	Sat Feb 08 22:33:52 2014 +0000
@@ -3,6 +3,7 @@
 import java.io.BufferedOutputStream;
 import java.io.File;
 import java.io.FileOutputStream;
+import java.io.InputStream;
 import java.io.OutputStream;
 import java.net.URI;
 import javax.xml.transform.Result;
@@ -11,6 +12,7 @@
 import javax.xml.transform.TransformerFactory;
 import javax.xml.transform.dom.DOMSource;
 import javax.xml.transform.sax.SAXResult;
+import javax.xml.transform.stream.StreamSource;
 import org.apache.fop.apps.Fop;
 import org.apache.fop.apps.FopFactory;
 import org.apache.fop.apps.MimeConstants;
@@ -24,21 +26,19 @@
  */
 public class RunFOP {
 
-    public String executeFop(String ifName, Document foTree)
+    public void executeFop(InputStream isFo, OutputStream osAt)
             throws Exception {
 
         FopFactory fopFactory = FopFactoryFactory.createFopFactory();
         if (fopFactory == null) {
             throw new Exception("Cannot create FopFactory");
         }
-        OutputStream out = new BufferedOutputStream(new FileOutputStream(new File(ifName)));
-        Fop fop = fopFactory.newFop(MimeConstants.MIME_FOP_AREA_TREE, out);
+        Fop fop = fopFactory.newFop(MimeConstants.MIME_FOP_AREA_TREE, osAt);
         TransformerFactory tf = new TransformerFactoryImpl();
         Transformer transformer = tf.newTransformer();
-        Source src = new DOMSource(foTree);
+	Source src = new StreamSource(isFo);
         Result res = new SAXResult(fop.getDefaultHandler());
-        transformer.transform(src, res);
-        return ifName;
+	transformer.transform(src, res);
     }
 
     public String executeFop(String ifName, Node foTree)
--- a/FOPRunXSLTExt/src/org/w3c/ppl/xslt/ext/fop/saxon/RunFOPSaxon.java	Tue Dec 17 22:35:08 2013 +0000
+++ b/FOPRunXSLTExt/src/org/w3c/ppl/xslt/ext/fop/saxon/RunFOPSaxon.java	Sat Feb 08 22:33:52 2014 +0000
@@ -5,15 +5,31 @@
 import net.sf.saxon.lib.ExtensionFunctionCall;
 import net.sf.saxon.lib.ExtensionFunctionDefinition;
 import net.sf.saxon.om.Item;
+import net.sf.saxon.om.NodeInfo;
+import net.sf.saxon.om.Sequence;
 import net.sf.saxon.om.SequenceIterator;
 import net.sf.saxon.om.StructuredQName;
+import net.sf.saxon.query.QueryResult;
 import net.sf.saxon.trans.XPathException;
 import net.sf.saxon.tree.tiny.TinyDocumentImpl;
+import net.sf.saxon.value.AtomicValue;
 import net.sf.saxon.value.SequenceType;
+import net.sf.saxon.value.SingletonItem;
 import net.sf.saxon.value.StringValue;
-import net.sf.saxon.value.Value;
+import net.sf.saxon.value.ObjectValue;
 import org.w3c.dom.Document;
 import org.w3c.ppl.xslt.ext.fop.RunFOP;
+import org.w3c.dom.Node;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import javax.xml.transform.TransformerFactory;
+import java.io.StringWriter;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
 
 /**
  * @author arvedhs
@@ -22,38 +38,40 @@
 
     @Override
     public StructuredQName getFunctionQName() {
-        return new StructuredQName("runfop", "http://org.w3c.ppl.xslt/saxon-extension", "area-tree-url");
+        return new StructuredQName("runfop", "http://org.w3c.ppl.xslt/saxon-extension", "area-tree");
     }
 
     @Override
     public SequenceType[] getArgumentTypes() {
-        return new SequenceType[]{SequenceType.SINGLE_NODE, SequenceType.SINGLE_STRING};
+        return new SequenceType[]{SequenceType.SINGLE_NODE};
     }
 
     @Override
     public SequenceType getResultType(SequenceType[] sts) {
-        return SequenceType.SINGLE_STRING;
+        return SequenceType.SINGLE_NODE;
     }
 
     @Override
     public ExtensionFunctionCall makeCallExpression() {
         return new ExtensionFunctionCall() {
             @Override
-            public SequenceIterator<? extends Item> call(SequenceIterator<? extends Item>[] sis,
-                    XPathContext xpc) throws XPathException {
+            public Sequence call(XPathContext context, Sequence[] arguments) throws XPathException {
                 
-                TinyDocumentImpl item = (TinyDocumentImpl) sis[0].next();
-                Document foTree = (Document) DocumentOverNodeInfo.wrap(item);
-                String ifName = ((StringValue) sis[1].next()).getStringValue();
+                NodeInfo item = (NodeInfo)arguments[0].head();
+                ByteArrayInputStream isFo = null;
+                ByteArrayOutputStream osAt = null;
 
-                String result = null;
                 try {
-                    result = new RunFOP().executeFop(ifName, foTree);
+                    isFo = new ByteArrayInputStream(QueryResult.serialize(item).getBytes("UTF-8"));
+                    osAt = new ByteArrayOutputStream();
+
+                    new RunFOP().executeFop(isFo, osAt);
+                    StreamSource sAt = new StreamSource(new ByteArrayInputStream(osAt.toByteArray()));
+                    return context.getConfiguration().buildDocument(sAt);
                 } catch (Exception ex) {
                     ex.printStackTrace();
                     throw new XPathException(ex);
                 }
-                return Value.asIterator(StringValue.makeStringValue(result));
             }
         };
     }