diff --git a/xslthl/pom.xml b/xslthl/pom.xml
index 037d4f3..90ccdc9 100644
--- a/xslthl/pom.xml
+++ b/xslthl/pom.xml
@@ -47,118 +47,17 @@ This version of xslthl provides extensions of the Apache Xalan and Saxon XSLT pr
-
-
- org.codehaus.mojo
- findbugs-maven-plugin
- 2.5.5
-
-
- package
-
- check
-
-
-
-
-
- maven-antrun-plugin
- 1.8
-
-
- site
-
-
-
-
-
-
- run
-
-
-
-
-
- maven-assembly-plugin
- 3.1.0
-
-
- src/main/assembly/dist.xml
-
-
-
-
- make-assembly
- package
-
- single
-
-
-
-
-
- org.apache.maven.plugins
- maven-source-plugin
- 3.0.1
-
-
- attach-sources
-
- jar
-
-
-
-
-
- org.apache.maven.plugins
- maven-javadoc-plugin
- 3.0.0
-
-
- package
-
- jar
-
-
-
-
-
- org.sonatype.plugins
- nexus-staging-maven-plugin
- 1.6.8
- true
-
- ossrh
- https://oss.sonatype.org/
- true
-
-
-
-
+
-
-
- org.codehaus.mojo
- findbugs-maven-plugin
- 2.5.5
-
-
- org.apache.maven.plugins
- maven-javadoc-plugin
- 2.8.1
-
-
-
-
@@ -180,11 +79,17 @@ This version of xslthl provides extensions of the Apache Xalan and Saxon XSLT pr
[6.5,7.0]
true
-
+
+
+ net.sf.saxon
+ Saxon-HE
+ 9.9.1-7
+ true
junit
@@ -197,7 +102,7 @@ This version of xslthl provides extensions of the Apache Xalan and Saxon XSLT pr
scm:svn:https://xslthl.svn.sourceforge.net/svnroot/xslthl/trunk/xslthl/
scm:svn:https://xslthl.svn.sourceforge.net/svnroot/xslthl/trunk/xslthl/
- http://xslthl.svn.sourceforge.net/viewvc/xslthl/trunk/xslthl/
+ https://xslthl.svn.sourceforge.net/viewvc/xslthl/trunk/xslthl/
diff --git a/xslthl/src/main/java/net/sf/xslthl/ConnectorSaxon9api.java b/xslthl/src/main/java/net/sf/xslthl/ConnectorSaxon9api.java
new file mode 100644
index 0000000..e8417f9
--- /dev/null
+++ b/xslthl/src/main/java/net/sf/xslthl/ConnectorSaxon9api.java
@@ -0,0 +1,313 @@
+/*
+ * xslthl - XSLT Syntax Highlighting
+ * https://sourceforge.net/projects/xslthl/
+ * Copyright (C) 2005-2008 Michal Molhanec, Jirka Kosek, Michiel Hendriks
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ * Michal Molhanec
+ * Jirka Kosek
+ * Michiel Hendriks
+ */
+package net.sf.xslthl;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import net.sf.saxon.lib.ExtensionFunctionCall;
+import net.sf.saxon.lib.ExtensionFunctionDefinition;
+
+import net.sf.saxon.s9api.ItemType;
+import net.sf.saxon.s9api.OccurrenceIndicator;
+import net.sf.saxon.s9api.SaxonApiException;
+import net.sf.saxon.value.SequenceExtent;
+import net.sf.saxon.value.SequenceType;
+import net.sf.saxon.value.StringValue;
+import net.sf.saxon.s9api.XdmAtomicValue;
+import net.sf.saxon.s9api.XdmValue;
+
+import net.sf.saxon.event.Builder;
+import net.sf.saxon.expr.XPathContext;
+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.tree.iter.SingleNodeIterator;
+import net.sf.saxon.trans.XPathException;
+import net.sf.saxon.type.AnyType;
+import net.sf.saxon.type.Type;
+
+/**
+ * A new saxon connector to be used with saxon 8.5 and later. This class uses
+ * Java reflection to call Saxon classes in order to be able to compile both
+ * connectors with the older Saxon library.
+ */
+public class ConnectorSaxon9api extends ExtensionFunctionDefinition {
+
+ /**
+ * The logging facility
+ */
+ private static Logger logger = Logger.getLogger("net.sf.xslthl.saxon9apiconnector");
+
+ private static void blockToSaxon9Node(Block b, Builder builder,
+ Config config) throws Exception {
+ if (b.isStyled()) {
+ // int elemId = pool.allocate(config.prefix, config.uri,
+ // ((StyledBlock) b).getStyle());
+
+// new FingerprintedQName(config.prefix, config.uri, ((StyledBlock)
+ // b).getStyle())
+ Class fpQnameClazz = Class
+ .forName("net.sf.saxon.om.FingerprintedQName");
+ Constructor constructor = fpQnameClazz.getConstructor(new Class[] {
+ String.class, String.class, String.class });
+ Object fpQname = constructor.newInstance(new Object[] {
+ config.prefix, config.uri, ((StyledBlock) b).getStyle() });
+ startElement(builder, fpQname);
+ outputCharacters(builder, b.getText());
+ builder.endElement();
+ } else {
+ outputCharacters(builder, b.getText());
+ }
+ }
+
+ private static void startElement(Builder builder, Object fpQname) throws Exception{
+ try{
+ // builder.startElement(fpQname, AnyType.getInstance(), 0, 0);
+ Method startElement = builder.getClass().getMethod(
+ "startElement",
+ new Class[] { Class.forName("net.sf.saxon.om.NodeName"),
+ net.sf.saxon.type.SchemaType.class, int.class,
+ int.class });
+ startElement.invoke(builder,
+ new Object[] { fpQname, AnyType.getInstance(), 0, 0 });
+ } catch(Exception ex){
+ //Maybe Saxon 9.7.11 or newer
+ //public void startElement(/*@NotNull*/ NodeName elemName, SchemaType type, Location location, int properties) throws XPathException {
+ Method startElement = builder.getClass().getMethod(
+ "startElement",
+ new Class[] { Class.forName("net.sf.saxon.om.NodeName"),
+ net.sf.saxon.type.SchemaType.class, Class.forName("net.sf.saxon.expr.parser.Location"),
+ int.class });
+ startElement.invoke(builder,
+ new Object[] { fpQname, AnyType.getInstance(), createFakeLocation(), 0 });
+ }
+ }
+
+ private static void outputCharacters(Builder builder, String text) throws Exception{
+ Method characters = null;
+ try{
+ characters = builder.getClass().getMethod("characters", new Class[]{String.class, int.class, int.class});
+ characters.invoke(builder, new Object[]{text, 0, 0});
+ } catch(Exception ex){
+ //Maybe Saxon 9.7.11 or newer
+ characters = builder.getClass().getMethod("characters", new Class[]{CharSequence.class, Class.forName("net.sf.saxon.expr.parser.Location"), int.class});
+ characters.invoke(builder, new Object[]{text, createFakeLocation(), 0});
+ }
+ }
+
+ private static Object createFakeLocation() throws IllegalArgumentException, ClassNotFoundException{
+ return Proxy.newProxyInstance(ConnectorSaxon9api.class.getClassLoader(),
+ new Class[]{Class.forName("net.sf.saxon.expr.parser.Location")}, new InvocationHandler() {
+ @Override
+ public Object invoke(Object proxy, Method method, Object[] args)
+ throws Throwable {
+ if("saveLocation".equals(method.getName())){
+ return proxy;
+ } else if("getSystemId".equals(method.getName())
+ || "getPublicId".equals(method.getName())){
+ return null;
+ } else if ("getLineNumber".equals(method.getName())
+ || "getColumnNumber".equals(method.getName())){
+ return Integer.valueOf(0);
+ }
+ return null;
+ }
+ });
+ }
+
+ /**
+ * Highlight the nodes using the standard configuration file
+ *
+ * @param context
+ * @param hlCode
+ * @param nodes
+ * @return
+ * @throws Exception
+ */
+ public static SequenceIterator highlight(XPathContext context,
+ String hlCode, SequenceIterator nodes) throws Exception {
+ return highlight(context, hlCode, nodes, null);
+ }
+
+ /**
+ * highlight the nodes using a specific interface
+ *
+ * @param context
+ * @param hlCode
+ * @param seq
+ * @param configFilename
+ * @return
+ * @throws Exception
+ */
+ public static SequenceIterator highlight(XPathContext context,
+ String hlCode, SequenceIterator seq, String configFilename)
+ throws Exception {
+ try {
+ Config c = Config.getInstance(configFilename);
+ MainHighlighter hl = c.getMainHighlighter(hlCode);
+
+ // Axis info obtained via Java reflection.
+ byte childType = (Byte) Class.forName("net.sf.saxon.om.AxisInfo")
+ .getField("CHILD").get(null);
+ Method iterateAxis = Class
+ .forName("net.sf.saxon.om.NodeInfo")
+ .getMethod(
+ "iterateAxis",
+ new Class[] {
+ byte.class,
+ Class.forName("net.sf.saxon.pattern.NodeTest") });
+ Class axisIterClazz = Class
+ .forName("net.sf.saxon.tree.iter.AxisIterator");
+ Method next = axisIterClazz.getMethod("next", new Class[0]);
+
+ List- resultNodes = new ArrayList
- ();
+ Item itm = null;
+ while ((itm = seq.next()) != null) {
+ // Item itm = seq.current();
+ if (itm instanceof NodeInfo) {
+ NodeInfo ni = (NodeInfo) itm;
+ SequenceIterator ae = (SequenceIterator) iterateAxis
+ .invoke(ni,
+ new Object[] {
+ childType,
+ net.sf.saxon.pattern.AnyNodeTest
+ .getInstance() });
+ // SequenceIterator ae = ni.iterateAxis(childType,
+ // net.sf.saxon.pattern.AnyNodeTest.getInstance());
+ Item itm2 = null;
+ while ((itm2 = ae.next()) != null) {
+ if (itm2 instanceof NodeInfo) {
+ NodeInfo n2i = (NodeInfo) itm2;
+ if (n2i.getNodeKind() == Type.TEXT) {
+ if (hl != null) {
+ try {
+ Builder builder = context.getController()
+ .makeBuilder();
+ builder.open();
+ builder.startDocument(0);
+ List l = hl.highlight(n2i
+ .getStringValue());
+ for (Block b : l) {
+ blockToSaxon9Node(b, builder, c);
+ }
+ builder.endDocument();
+ builder.close();
+ NodeInfo doc = builder.getCurrentRoot();
+
+ Object elms = iterateAxis
+ .invoke(doc,
+ new Object[] {
+ childType,
+ net.sf.saxon.pattern.AnyNodeTest
+ .getInstance() });
+ // Object elms =
+ // doc.iterateAxis(childType,net.sf.saxon.pattern.AnyNodeTest);
+ Item crt = null;
+ while ((crt = (Item) next.invoke(elms,
+ new Object[0])) != null) {
+ resultNodes.add(crt);
+ }
+ } catch(Exception ex) {
+ logger.log(Level.SEVERE, String.format(
+ "1Highligher threw unhandled error at position %s: %s", n2i.getStringValue(),
+ ex.getMessage()), ex);
+ resultNodes.add(n2i); // No highlighting, but visible at least
+ }
+ } else {
+ resultNodes.add(n2i);
+ }
+ } else {
+ resultNodes.add(n2i);
+ }
+ } else {
+ resultNodes.add(itm2);
+ }
+ }
+ } else {
+ resultNodes.add(itm);
+ }
+ }
+ Class lstIterClassName = Class
+ .forName("net.sf.saxon.tree.iter.ListIterator");
+ Constructor constructor = lstIterClassName
+ .getConstructor(new Class[] { List.class });
+ return (SequenceIterator) constructor
+ .newInstance(new Object[] { resultNodes });
+ } catch (Throwable e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ @Override
+ public StructuredQName getFunctionQName() {
+ return new StructuredQName("s9hl", "http://sourceforge.net/projects/xslthl", "highlight");
+ }
+
+ @Override
+ public SequenceType[] getArgumentTypes() {
+ return new SequenceType[] {SequenceType.SINGLE_STRING, SequenceType.SINGLE_NODE, SequenceType.SINGLE_STRING};
+ }
+
+ @Override
+ public SequenceType getResultType(SequenceType[] sts) {
+ return SequenceType.NODE_SEQUENCE;
+ }
+
+ @Override
+ public ExtensionFunctionCall makeCallExpression() {
+ return new ExtensionFunctionCall() {
+ @Override
+ public Sequence call(XPathContext context, Sequence[] arguments) throws XPathException {
+ //String result = "Saxon is being extended correctly.1";
+ //return new StringValue(result);
+ try {
+ // StringValue.toString() returns the XPath representation, which
+ // has '"' around the value.
+ String hlCode = ((StringValue)arguments[0].head()).toString().replace("\"", "");
+ String configFilename = ((StringValue)arguments[2].head()).toString().replace("\"", "");
+ return new SequenceExtent(highlight(context,
+ hlCode,
+ SingleNodeIterator.makeIterator((NodeInfo)arguments[1].head()),
+ configFilename));
+ } catch (Throwable e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+ };
+ }
+
+}
diff --git a/xslthl/src/main/java/net/sf/xslthl/ConnectorSaxon9apiInitializer.java b/xslthl/src/main/java/net/sf/xslthl/ConnectorSaxon9apiInitializer.java
new file mode 100644
index 0000000..d0035e6
--- /dev/null
+++ b/xslthl/src/main/java/net/sf/xslthl/ConnectorSaxon9apiInitializer.java
@@ -0,0 +1,18 @@
+package net.sf.xslthl;
+
+import javax.xml.transform.TransformerException;
+import net.sf.saxon.Configuration;
+import net.sf.saxon.lib.Initializer;
+
+/**
+ *
+ * @author tgraham
+ */
+public class ConnectorSaxon9apiInitializer implements Initializer {
+
+ @Override
+ public void initialize(Configuration c) throws TransformerException {
+ c.registerExtensionFunction(new ConnectorSaxon9api());
+ }
+
+}
diff --git a/xslthl/src/main/java/net/sf/xslthl/ConnectorSaxonB.java b/xslthl/src/main/java/net/sf/xslthl/ConnectorSaxonB.java
deleted file mode 100644
index ad2a28e..0000000
--- a/xslthl/src/main/java/net/sf/xslthl/ConnectorSaxonB.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * xslthl - XSLT Syntax Highlighting
- * https://sourceforge.net/projects/xslthl/
- * Copyright (C) 2005-2008 Michal Molhanec, Jirka Kosek, Michiel Hendriks
- *
- * This software is provided 'as-is', without any express or implied
- * warranty. In no event will the authors be held liable for any damages
- * arising from the use of this software.
- *
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute it
- * freely, subject to the following restrictions:
- *
- * 1. The origin of this software must not be misrepresented; you must not
- * claim that you wrote the original software. If you use this software
- * in a product, an acknowledgment in the product documentation would be
- * appreciated but is not required.
- * 2. Altered source versions must be plainly marked as such, and must not be
- * misrepresented as being the original software.
- * 3. This notice may not be removed or altered from any source distribution.
- *
- * Michal Molhanec
- * Jirka Kosek
- * Michiel Hendriks
- */
-package net.sf.xslthl;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import net.sf.saxon.event.Builder;
-import net.sf.saxon.expr.XPathContext;
-import net.sf.saxon.om.Axis;
-import net.sf.saxon.om.AxisIterator;
-import net.sf.saxon.om.Item;
-import net.sf.saxon.om.ListIterator;
-import net.sf.saxon.om.NamePool;
-import net.sf.saxon.om.NodeInfo;
-import net.sf.saxon.om.SequenceIterator;
-import net.sf.saxon.pattern.AnyNodeTest;
-import net.sf.saxon.type.Type;
-
-/**
- * A new saxon connector to be used with saxon 8.5 and later.
- */
-public class ConnectorSaxonB {
- /**
- * The logging facility
- */
- private static Logger logger = Logger.getLogger("net.sf.xslthl.saxon9Bconnector");
-
- private static void blockToSaxon9Node(Block b, Builder builder,
- NamePool pool, Config config) throws Exception {
- if (b.isStyled()) {
- int elemId = pool.allocate(config.prefix, config.uri,
- ((StyledBlock) b).getStyle());
- builder.startElement(elemId, -1, 0, 0);
- builder.characters(b.getText(), 0, b.getText().length());
- builder.endElement();
- } else {
- builder.characters(b.getText(), 0, b.getText().length());
- }
- }
-
- /**
- * Highlight the nodes using the standard configuration file
- *
- * @param context
- * @param hlCode
- * @param nodes
- * @return
- * @throws Exception
- */
- public static SequenceIterator highlight(XPathContext context,
- String hlCode, SequenceIterator nodes) throws Exception {
- return highlight(context, hlCode, nodes, null);
- }
-
- /**
- * highlight the nodes using a specific interface
- *
- * @param context
- * @param hlCode
- * @param seq
- * @param configFilename
- * @return
- * @throws Exception
- */
- public static SequenceIterator highlight(XPathContext context,
- String hlCode, SequenceIterator seq, String configFilename)
- throws Exception {
- try {
- Config c = Config.getInstance(configFilename);
- MainHighlighter hl = c.getMainHighlighter(hlCode);
-
- NamePool pool = context.getController().getNamePool();
-
- List
- resultNodes = new ArrayList
- ();
- while (seq.next() != null) {
- Item itm = seq.current();
- if (itm instanceof NodeInfo) {
- NodeInfo ni = (NodeInfo) itm;
- SequenceIterator ae = ni.iterateAxis(Axis.CHILD,
- AnyNodeTest.getInstance());
- while (ae.next() != null) {
- Item itm2 = ae.current();
- if (itm2 instanceof NodeInfo) {
- NodeInfo n2i = (NodeInfo) itm2;
- if (n2i.getNodeKind() == Type.TEXT) {
- if (hl != null) {
- try {
- Builder builder = context.getController()
- .makeBuilder();
- builder.open();
- builder.startDocument(0);
- List l = hl.highlight(n2i
- .getStringValue());
- for (Block b : l) {
- blockToSaxon9Node(b, builder, pool, c);
- }
- builder.endDocument();
- builder.close();
- NodeInfo doc = builder.getCurrentRoot();
- AxisIterator elms = doc.iterateAxis(
- Axis.CHILD, AnyNodeTest
- .getInstance());
- while (elms.next() != null) {
- resultNodes.add(elms.current());
- }
- } catch(Exception ex) {
- logger.log(Level.SEVERE, String.format(
- "Highligher threw unhandled error at position %s: %s", n2i.getStringValue(),
- ex.getMessage()), ex);
- resultNodes.add(n2i); // No highlighting, but visible at least
- }
- } else {
- resultNodes.add(n2i);
- }
- } else {
- resultNodes.add(n2i);
- }
- } else {
- resultNodes.add(itm2);
- }
- }
- } else {
- resultNodes.add(itm);
- }
- }
- return new ListIterator(resultNodes);
- } catch (Exception e) {
- e.printStackTrace();
- return null;
- }
- }
-}