]> granicus.if.org Git - docbook-dsssl/commitdiff
Support the textinsert extension; update all extensions to the Saxon 8.1.1 API
authorNorman Walsh <ndw@nwalsh.com>
Fri, 29 Oct 2004 13:14:12 +0000 (13:14 +0000)
committerNorman Walsh <ndw@nwalsh.com>
Fri, 29 Oct 2004 13:14:12 +0000 (13:14 +0000)
xsl/extensions/saxon8/com/nwalsh/saxon8/Text.java [new file with mode: 0644]
xsl/extensions/saxon8/com/nwalsh/saxon8/TextFactory.java [new file with mode: 0644]
xsl/extensions/saxon8/com/nwalsh/saxon8/Verbatim.java

diff --git a/xsl/extensions/saxon8/com/nwalsh/saxon8/Text.java b/xsl/extensions/saxon8/com/nwalsh/saxon8/Text.java
new file mode 100644 (file)
index 0000000..1ff2ca1
--- /dev/null
@@ -0,0 +1,249 @@
+// Text - Saxon extension element for inserting text
+
+package com.nwalsh.saxon8;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.FileNotFoundException;
+import java.net.URL;
+import java.net.MalformedURLException;
+
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.URIResolver;
+import javax.xml.transform.Source;
+
+import net.sf.saxon.Controller;
+import net.sf.saxon.instruct.ExtensionInstruction;
+import net.sf.saxon.event.Receiver;
+import net.sf.saxon.expr.Expression;
+import net.sf.saxon.instruct.Executable;
+import net.sf.saxon.expr.SimpleExpression;
+import net.sf.saxon.expr.XPathContext;
+import net.sf.saxon.om.Item;
+import net.sf.saxon.om.NodeInfo;
+import net.sf.saxon.om.NamePool;
+import net.sf.saxon.xpath.XPathException;
+
+/*
+import net.sf.saxon.value.AtomicValue;
+import net.sf.saxon.value.ObjectValue;
+*/
+
+import org.xml.sax.AttributeList;
+
+/**
+ * <p>Saxon extension element for inserting text
+ *
+ * <p>$Id$</p>
+ *
+ * <p>Copyright (C) 2000 Norman Walsh.</p>
+ *
+ * <p>This class provides a
+ * <a href="http://users.iclway.co.uk/mhkay/saxon/">Saxon</a>
+ * extension element for inserting text into a result tree.</p>
+ *
+ * <p><b>Change Log:</b></p>
+ * <dl>
+ * <dt>1.0</dt>
+ * <dd><p>Initial release.</p></dd>
+ * </dl>
+ *
+ * @author Norman Walsh
+ * <a href="mailto:ndw@nwalsh.com">ndw@nwalsh.com</a>
+ *
+ * @version $Id$
+ *
+ */
+public class Text extends ExtensionInstruction {
+  Expression hrefExpr;
+  Expression encodingExpr;
+
+  /**
+   * <p>Constructor for Text</p>
+   *
+   * <p>Does nothing.</p>
+   */
+  public Text() {
+  }
+
+  /**
+   * <p>Can this element contain a template-body?</p>
+   *
+   * <p>Yes, it can, but only so that it can contain xsl:fallback.</p>
+   *
+   * @return true
+   */
+  public boolean mayContainTemplateBody() {
+    return true;
+  }
+
+  /**
+   * <p>Validate the arguments</p>
+   *
+   * <p>The element must have an href attribute.</p>
+   */
+  public void prepareAttributes() throws TransformerConfigurationException {
+    // Get mandatory href attribute
+    String fnAtt = getAttribute("href");
+    if (fnAtt == null || "".equals(fnAtt)) {
+      reportAbsence("href");
+    }
+    hrefExpr = makeAttributeValueTemplate(fnAtt);
+
+    fnAtt = getAttribute("encoding");
+    if (fnAtt == null || "".equals(fnAtt)) {
+      encodingExpr = null;
+    } else {
+      encodingExpr = makeAttributeValueTemplate(fnAtt);
+    }
+  }
+
+  /** Validate that the element occurs in a reasonable place. */
+  public void validate() throws TransformerConfigurationException {
+    checkWithinTemplate();
+    hrefExpr = typeCheck("href", hrefExpr);
+    if (encodingExpr != null) {
+      encodingExpr = typeCheck("encoding", encodingExpr);
+    }
+  }
+
+  public Expression compile(Executable exec)
+    throws TransformerConfigurationException {
+    return new TextInstruction(hrefExpr, encodingExpr);
+  }
+
+  private static class TextInstruction extends SimpleExpression {
+    Expression hrefExpr;
+    Expression encodingExpr;
+
+    public TextInstruction(Expression hrefExpr, Expression encExpr) {
+      this.hrefExpr = hrefExpr;
+      encodingExpr = encExpr;
+    }
+
+    public int getImplementationMethod() {
+      return EVALUATE_METHOD;
+    }
+
+    public String getExpressionType() {
+      return "s8text:insertfile";
+    }
+
+    /**
+     * <p>Insert the text of the file into the result tree</p>
+     *
+     * <p>Processing this element inserts the contents of the URL named
+     * by the href attribute into the result tree as plain text.</p>
+     *
+     * <p>Optional encoding attribute can specify encoding of resource.
+     * If not specified default system encoding is used.</p>
+     *
+     */
+    public Item evaluateItem(XPathContext context) throws XPathException {
+      Controller controller = context.getController();
+      NamePool namePool = controller.getNamePool();
+      Receiver out = context.getReceiver();
+      String href = hrefExpr.evaluateAsString(context);
+
+      String encoding = "";
+      if (encodingExpr != null) {
+       encoding = encodingExpr.evaluateAsString(context);
+      }
+
+      String baseURI = ((NodeInfo) context.getContextItem()).getBaseURI();
+
+      URIResolver resolver = context.getController().getURIResolver();
+
+      if (resolver != null) {
+       try {
+         Source source = resolver.resolve(href, baseURI);
+         href = source.getSystemId();
+       } catch (TransformerException te) {
+         // nop
+       }
+      }
+
+      URL baseURL = null;
+      URL fileURL = null;
+
+      try {
+       baseURL = new URL(baseURI);
+      } catch (MalformedURLException e0) {
+       // what the!?
+       baseURL = null;
+      }
+
+      try {
+       try {
+         fileURL = new URL(baseURL, href);
+       } catch (MalformedURLException e1) {
+         try {
+           fileURL = new URL(baseURL, "file:" + href);
+         } catch (MalformedURLException e2) {
+           System.out.println("Cannot open " + href);
+           return null;
+         }
+       }
+
+       InputStreamReader isr = null;
+       if (encoding.equals("") == true)
+         isr = new InputStreamReader(fileURL.openStream());
+       else
+         isr = new InputStreamReader(fileURL.openStream(), encoding);
+
+       BufferedReader is = new BufferedReader(isr);
+
+       final int BUFFER_SIZE = 4096;
+       char chars[] = new char[BUFFER_SIZE];
+       char nchars[] = new char[BUFFER_SIZE];
+       int len = 0;
+       int i = 0;
+       int carry = -1;
+
+       while ((len = is.read(chars)) > 0) {
+         // various new lines are normalized to LF to prevent blank lines
+         // between lines
+
+         int nlen = 0;
+         for (i=0; i<len; i++) {
+           // is current char CR?
+           if (chars[i] == '\r') {
+             if (i < (len - 1)) {
+               // skip it if next char is LF
+               if (chars[i+1] == '\n') continue;
+               // single CR -> LF to normalize MAC line endings
+               nchars[nlen] = '\n';
+               nlen++;
+               continue;
+             } else {
+               // if CR is last char of buffer we must look ahead
+               carry = is.read();
+               nchars[nlen] = '\n';
+               nlen++;
+               if (carry == '\n') {
+                 carry = -1;
+               }
+               break;
+             }
+           }
+           nchars[nlen] = chars[i];
+           nlen++;
+         }
+
+         out.characters(String.valueOf(nchars), 0, 0);
+         // handle look aheaded character
+         if (carry != -1) out.characters(String.valueOf((char)carry), 0, 0);
+         carry = -1;
+       }
+       is.close();
+      } catch (Exception e) {
+       System.out.println("Cannot read " + href);
+      }
+
+      return null;
+    }
+  }
+}
diff --git a/xsl/extensions/saxon8/com/nwalsh/saxon8/TextFactory.java b/xsl/extensions/saxon8/com/nwalsh/saxon8/TextFactory.java
new file mode 100644 (file)
index 0000000..fff01d6
--- /dev/null
@@ -0,0 +1,67 @@
+// TextFactory - Saxon extension element factory
+
+package com.nwalsh.saxon8;
+
+import net.sf.saxon.style.ExtensionElementFactory;
+import org.xml.sax.SAXException;
+
+/**
+ * <p>Saxon extension element factory
+ *
+ * <p>$Id$</p>
+ *
+ * <p>Copyright (C) 2000 Norman Walsh.</p>
+ *
+ * <p>This class provides a
+ * <a href="http://users.iclway.co.uk/mhkay/saxon/">Saxon</a>
+ * extension element factory for the Text extension element
+ * family.</p>
+ *
+ * <p><b>Change Log:</b></p>
+ * <dl>
+ * <dt>1.0</dt>
+ * <dd><p>Initial release.</p></dd>
+ * </dl>
+ *
+ * @author Norman Walsh
+ * <a href="mailto:ndw@nwalsh.com">ndw@nwalsh.com</a>
+ *
+ * @version $Id$
+ *
+ * @see Text
+ *
+ */
+public class TextFactory implements ExtensionElementFactory {
+  /**
+   * <p>Constructor for TextFactory</p>
+   *
+   * <p>Does nothing.</p>
+   */
+  public TextFactory() {
+  }
+
+  /**
+   * <p>Return the class that implements a particular extension element.</p>
+   *
+   * @param localname The local name of the extension element.
+   *
+   * @return The class that handles that extension element.
+   *
+   * @exception SAXException("Unknown Text extension element")
+   */
+  public Class getExtensionClass(String localname) {
+    if (localname.equals("insertfile")) {
+      try {
+       return Class.forName("com.nwalsh.saxon8.Text");
+      } catch (ClassNotFoundException e) {
+       return null;
+      }
+    }
+    return null;
+  }
+}
+
+
+
+
+
index 680d7370371f28b94b10083a120eacc667580063..5b64d8ab6c4758fe64643326d5f3219f62880a13 100644 (file)
@@ -187,7 +187,8 @@ public class Verbatim {
 
     tree.setConfiguration(config);
     builder.setConfiguration(config);
-    tree.startDocument();
+    tree.open();
+    tree.startDocument(0);
 
     wrapper = findWrapper(wrapperns);
 
@@ -244,6 +245,7 @@ public class Verbatim {
     }
 
     tree.endDocument();
+    tree.close();
     return builder.getCurrentDocument();
   }
 
@@ -305,13 +307,13 @@ public class Verbatim {
     // Maybe node is an element, a text node, a comment, or a PI
     switch (node.getNodeKind()) {
     case Type.ELEMENT:
-      tree.startElement(node.getNameCode(), 0, 0);
+      tree.startElement(node.getNameCode(), 0, 0, 0);
 
       {
        AxisIterator attrIter = node.iterateAxis(Axis.ATTRIBUTE);
        NodeInfo attr = (NodeInfo) attrIter.next();
        while (attr != null) {
-         tree.attribute(attr.getNameCode(), 0, attr.getStringValue(), 0);
+         tree.attribute(attr.getNameCode(), 0, attr.getStringValue(), 0, 0);
          attr = (NodeInfo) attrIter.next();
        }
       }
@@ -336,7 +338,7 @@ public class Verbatim {
       String text = node.getStringValue();
       int pos = text.indexOf('\n');
       while (pos >= 0) {
-       tree.characters(text.substring(0, pos), 0);
+       tree.characters(text.substring(0, pos), 0, 0);
 
        // Close any open elements
        for (int openpos = 0; openpos < openElements.size(); openpos++) {
@@ -344,7 +346,7 @@ public class Verbatim {
        }
 
        // Output the line number
-       tree.characters("\n", 0);
+       tree.characters("\n", 0, 0);
        lineNumber++;
        formatLineNumber(pool, tree);
 
@@ -352,14 +354,14 @@ public class Verbatim {
        for (int openpos = 0; openpos < openElements.size(); openpos++) {
          NodeInfo onode = (NodeInfo) openElements.get(openpos);
 
-         tree.startElement(onode.getNameCode(), 0, 0);
+         tree.startElement(onode.getNameCode(), 0, 0, 0);
 
          AxisIterator oattrIter = onode.iterateAxis(Axis.ATTRIBUTE);
          NodeInfo attr = (NodeInfo) oattrIter.next();
          while (attr != null) {
            // Don't output {xml:}id attributes again
            if (!"id".equals(attr.getLocalPart())) {
-             tree.attribute(attr.getNameCode(), 0, attr.getStringValue(), 0);
+             tree.attribute(attr.getNameCode(), 0, attr.getStringValue(), 0, 0);
            }
            attr = (NodeInfo) oattrIter.next();
          }
@@ -370,14 +372,14 @@ public class Verbatim {
        text = text.substring(pos+1);
        pos = text.indexOf('\n');
       }
-      tree.characters(text, 0);
+      tree.characters(text, 0, 0);
       break;
     case Type.COMMENT:
-      tree.comment(node.getStringValue(), 0);
+      tree.comment(node.getStringValue(), 0, 0);
       break;
     case Type.PROCESSING_INSTRUCTION:
       tree.processingInstruction(node.getDisplayName(),
-                                node.getStringValue(), 0);
+                                node.getStringValue(), 0, 0);
       break;
     default:
       System.err.println("Error!");
@@ -403,17 +405,17 @@ public class Verbatim {
     lno += separator;
 
     if (wrapper != null) {
-      tree.startElement(wrapper.getNameCode(), 0, 0);
+      tree.startElement(wrapper.getNameCode(), 0, 0, 0);
       AxisIterator attrIter = wrapper.iterateAxis(Axis.ATTRIBUTE);
       NodeInfo attr = (NodeInfo) attrIter.next();
       while (attr != null) {
-       tree.attribute(attr.getNameCode(), 0, attr.getStringValue(), 0);
+       tree.attribute(attr.getNameCode(), 0, attr.getStringValue(), 0, 0);
        attr = (NodeInfo) attrIter.next();
       }
       tree.startContent();
     }
 
-    tree.characters(lno, 0);
+    tree.characters(lno, 0, 0);
 
     if (wrapper != null) {
       tree.endElement();
@@ -468,7 +470,8 @@ public class Verbatim {
 
     tree.setConfiguration(config);
     builder.setConfiguration(config);
-    tree.startDocument();
+    tree.open();
+    tree.startDocument(0);
 
     // Start at (1,1)
     lineNumber = 1;
@@ -493,6 +496,7 @@ public class Verbatim {
     }
 
     tree.endDocument();
+    tree.close();
     return builder.getCurrentDocument();
   }
 
@@ -504,13 +508,13 @@ public class Verbatim {
     // Maybe node is an element, a text node, a comment, or a PI
     switch (node.getNodeKind()) {
     case Type.ELEMENT:
-      tree.startElement(node.getNameCode(), 0, 0);
+      tree.startElement(node.getNameCode(), 0, 0, 0);
 
       {
        AxisIterator attrIter = node.iterateAxis(Axis.ATTRIBUTE);
        NodeInfo attr = (NodeInfo) attrIter.next();
        while (attr != null) {
-         tree.attribute(attr.getNameCode(), 0, attr.getStringValue(), 0);
+         tree.attribute(attr.getNameCode(), 0, attr.getStringValue(), 0, 0);
          attr = (NodeInfo) attrIter.next();
        }
       }
@@ -559,7 +563,7 @@ public class Verbatim {
 
          while (callout != null && "\n".equals(ch)
                 && lineNumber == callout.getLine()) {
-           tree.characters(" ", 0);
+           tree.characters(" ", 0, 0);
            colNumber++;
 
            done = false;
@@ -578,7 +582,7 @@ public class Verbatim {
            }
          }
 
-         tree.characters(ch, 0);
+         tree.characters(ch, 0, 0);
 
          if ("\n".equals(ch)) {
            lineNumber++;
@@ -588,15 +592,15 @@ public class Verbatim {
          }
        }
       } else {
-       tree.characters(text, 0);
+       tree.characters(text, 0, 0);
       }
       break;
     case Type.COMMENT:
-      tree.comment(node.getStringValue(), 0);
+      tree.comment(node.getStringValue(), 0, 0);
       break;
     case Type.PROCESSING_INSTRUCTION:
       tree.processingInstruction(node.getDisplayName(),
-                                node.getStringValue(), 0);
+                                node.getStringValue(), 0, 0);
       break;
     default:
       System.err.println("Error!");
@@ -627,7 +631,7 @@ public class Verbatim {
     switch (style) {
     case CALLOUT_TEXT:
       startCalloutWrapper(callout, textWrapper, tree);
-      tree.characters(textPrefix + callout.getCallout() + textSuffix, 0);
+      tree.characters(textPrefix + callout.getCallout() + textSuffix, 0, 0);
       endCalloutWrapper(textWrapper, tree);
       break;
     case CALLOUT_UNICODE:
@@ -636,7 +640,7 @@ public class Verbatim {
       char chars[] = new char[1];
       chars[0] = (char) codepoint;
       String unicodeCh = new String(chars);
-      tree.characters(unicodeCh, 0);
+      tree.characters(unicodeCh, 0, 0);
       endCalloutWrapper(unicodeWrapper, tree);
       break;
     case CALLOUT_GRAPHICS:
@@ -650,14 +654,14 @@ public class Verbatim {
     for (int openpos = 0; openpos < openElements.size(); openpos++) {
       NodeInfo onode = (NodeInfo) openElements.get(openpos);
 
-      tree.startElement(onode.getNameCode(), 0, 0);
+      tree.startElement(onode.getNameCode(), 0, 0, 0);
 
       AxisIterator oattrIter = onode.iterateAxis(Axis.ATTRIBUTE);
       NodeInfo attr = (NodeInfo) oattrIter.next();
       while (attr != null) {
        // Don't output {xml:}id attributes again
        if (!"id".equals(attr.getLocalPart())) {
-         tree.attribute(attr.getNameCode(), 0, attr.getStringValue(), 0);
+         tree.attribute(attr.getNameCode(), 0, attr.getStringValue(), 0, 0);
        }
        attr = (NodeInfo) oattrIter.next();
       }
@@ -671,13 +675,13 @@ public class Verbatim {
                                           Receiver tree)
     throws TransformerException {
     if (wrapper != null) {
-      tree.startElement(wrapper.getNameCode(), 0, 0);
+      tree.startElement(wrapper.getNameCode(), 0, 0, 0);
       AxisIterator attrIter = wrapper.iterateAxis(Axis.ATTRIBUTE);
       NodeInfo attr = (NodeInfo) attrIter.next();
       while (attr != null) {
        String value = attr.getStringValue().replaceAll("\\{CALLOUT\\}",
                                                        ""+callout.getCallout());
-       tree.attribute(attr.getNameCode(), 0, value, 0);
+       tree.attribute(attr.getNameCode(), 0, value, 0, 0);
        attr = (NodeInfo) attrIter.next();
       }
       tree.startContent();