diff options
Diffstat (limited to 'libjava/classpath/gnu/xml/transform')
14 files changed, 917 insertions, 794 deletions
diff --git a/libjava/classpath/gnu/xml/transform/AttributeNode.java b/libjava/classpath/gnu/xml/transform/AttributeNode.java index 1e0eb1e961a..bc5bc30c9c1 100644 --- a/libjava/classpath/gnu/xml/transform/AttributeNode.java +++ b/libjava/classpath/gnu/xml/transform/AttributeNode.java @@ -1,5 +1,5 @@ /* AttributeNode.java -- - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004,2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -75,13 +75,9 @@ final class AttributeNode namespace.clone(stylesheet), source); if (children != null) - { - ret.children = children.clone(stylesheet); - } + ret.children = children.clone(stylesheet); if (next != null) - { - ret.next = next.clone(stylesheet); - } + ret.next = next.clone(stylesheet); return ret; } @@ -113,9 +109,7 @@ final class AttributeNode // Use XPath string-value of fragment namespaceValue = Expr.stringValue(fragment); if (namespaceValue.length() == 0) - { - namespaceValue = null; - } + namespaceValue = null; } String prefix = getPrefix(nameValue); @@ -124,9 +118,7 @@ final class AttributeNode if (prefix != null) { if (XMLConstants.XML_NS_PREFIX.equals(prefix)) - { - namespaceValue = XMLConstants.XML_NS_URI; - } + namespaceValue = XMLConstants.XML_NS_URI; else { // Resolve namespace for this prefix @@ -153,9 +145,7 @@ final class AttributeNode // Resolve prefix for this namespace prefix = source.lookupPrefix(namespaceValue); if (prefix != null) - { - nameValue = prefix + ":" + nameValue; - } + nameValue = prefix + ":" + nameValue; else { if (namespaceValue != null) @@ -196,27 +186,19 @@ final class AttributeNode if (attrs != null) { if (namespace != null) - { - attrs.setNamedItemNS(attr); - } + attrs.setNamedItemNS(attr); else - { - attrs.setNamedItem(attr); - } + attrs.setNamedItem(attr); } if (children != null) - { - children.apply(stylesheet, mode, - context, pos, len, - attr, null); - } + children.apply(stylesheet, mode, + context, pos, len, + attr, null); } if (next != null) - { - next.apply(stylesheet, mode, - context, pos, len, - parent, nextSibling); - } + next.apply(stylesheet, mode, + context, pos, len, + parent, nextSibling); } final String getPrefix(String name) @@ -241,13 +223,9 @@ final class AttributeNode public boolean references(QName var) { if (name != null && name.references(var)) - { - return true; - } + return true; if (namespace != null && namespace.references(var)) - { - return true; - } + return true; return super.references(var); } diff --git a/libjava/classpath/gnu/xml/transform/Bindings.java b/libjava/classpath/gnu/xml/transform/Bindings.java index c372ea83091..4ee08322317 100644 --- a/libjava/classpath/gnu/xml/transform/Bindings.java +++ b/libjava/classpath/gnu/xml/transform/Bindings.java @@ -78,6 +78,11 @@ public class Bindings */ final LinkedList withParameters; + /** + * Only search globals. + */ + boolean global; + Bindings(Stylesheet stylesheet) { this.stylesheet = stylesheet; @@ -136,6 +141,12 @@ public class Bindings public boolean containsKey(QName name, int type) { + if (global) + { + Map ctx1 = (Map) variables.getLast(); + Map ctx2 = (Map) parameters.getLast(); + return (ctx1.containsKey(name) || ctx2.containsKey(name)); + } Iterator i = null; switch (type) { @@ -165,6 +176,17 @@ public class Bindings public Object get(QName name, Node context, int pos, int len) { + if (global) + { + Map ctx = (Map) variables.getLast(); + Object ret = ctx.get(name); + if (ret == null) + { + ctx = (Map) parameters.getLast(); + ret = ctx.get(name); + } + return ret; + } //System.err.println("bindings.get: "+name); //System.err.println("\t"+toString()); Object ret = null; diff --git a/libjava/classpath/gnu/xml/transform/ElementAvailableFunction.java b/libjava/classpath/gnu/xml/transform/ElementAvailableFunction.java index 84cb6207af9..aa15981695e 100644 --- a/libjava/classpath/gnu/xml/transform/ElementAvailableFunction.java +++ b/libjava/classpath/gnu/xml/transform/ElementAvailableFunction.java @@ -144,8 +144,8 @@ class ElementAvailableFunction { return elements.contains(localName) ? Boolean.TRUE : Boolean.FALSE; - // TODO extension elements } + // TODO extension elements return Boolean.FALSE; } @@ -153,16 +153,12 @@ class ElementAvailableFunction { NamespaceContext n = nsctx; if (context instanceof NamespaceContext) - { - n = (NamespaceContext) context; - } + n = (NamespaceContext) context; ElementAvailableFunction f = new ElementAvailableFunction(n); int len = args.size(); List args2 = new ArrayList(len); for (int i = 0; i < len; i++) - { - args2.add(((Expr) args.get(i)).clone(context)); - } + args2.add(((Expr) args.get(i)).clone(context)); f.setArguments(args2); return f; } @@ -172,12 +168,15 @@ class ElementAvailableFunction for (Iterator i = args.iterator(); i.hasNext(); ) { if (((Expr) i.next()).references(var)) - { - return true; - } + return true; } return false; } + public String toString() + { + return "element-available(" + args.get(0) + ")"; + } + } diff --git a/libjava/classpath/gnu/xml/transform/ElementNode.java b/libjava/classpath/gnu/xml/transform/ElementNode.java index d8f7f6db6db..092c56a4b64 100644 --- a/libjava/classpath/gnu/xml/transform/ElementNode.java +++ b/libjava/classpath/gnu/xml/transform/ElementNode.java @@ -82,14 +82,10 @@ final class ElementNode elementExcludeResultPrefixes = new HashSet(); StringTokenizer st = new StringTokenizer(attr.getNodeValue()); while (st.hasMoreTokens()) - { - elementExcludeResultPrefixes.add(st.nextToken()); - } + elementExcludeResultPrefixes.add(st.nextToken()); } else - { - elementExcludeResultPrefixes = Collections.EMPTY_SET; - } + elementExcludeResultPrefixes = Collections.EMPTY_SET; } TemplateNode clone(Stylesheet stylesheet) @@ -99,19 +95,15 @@ final class ElementNode namespace.clone(stylesheet), uas, source); if (children != null) - { - ret.children = children.clone(stylesheet); - } + ret.children = children.clone(stylesheet); if (next != null) - { - ret.next = next.clone(stylesheet); - } + ret.next = next.clone(stylesheet); return ret; } void doApply(Stylesheet stylesheet, QName mode, - Node context, int pos, int len, - Node parent, Node nextSibling) + Node context, int pos, int len, + Node parent, Node nextSibling) throws TransformerException { Document doc = (parent instanceof Document) ? (Document) parent : @@ -137,96 +129,70 @@ final class ElementNode // Use XPath string-value of fragment namespaceValue = Expr.stringValue(fragment); if (namespaceValue.length() == 0) - { - namespaceValue = null; - } - } - - String prefix = getPrefix(nameValue); - if (XMLConstants.XMLNS_ATTRIBUTE.equals(prefix)) - { - int ci = nameValue.indexOf(':'); - nameValue = nameValue.substring(ci + 1); + namespaceValue = null; } else - { - // Namespace aliasing - if (prefix == null) - { - prefix = "#default"; - } - String resultPrefix = - (String) stylesheet.namespaceAliases.get(prefix); - if (resultPrefix != null) - { - if ("#default".equals(resultPrefix)) - { - resultPrefix = null; - } - namespaceValue = source.lookupNamespaceURI(resultPrefix); - } - if (prefix == "#default") + { + String prefix = getPrefix(nameValue); + if (XMLConstants.XMLNS_ATTRIBUTE.equals(prefix)) { - prefix = null; + int ci = nameValue.indexOf(':'); + nameValue = nameValue.substring(ci + 1); } - // Look up ordinary namespace for this prefix - if (namespaceValue == null) + else { - if (XMLConstants.XML_NS_PREFIX.equals(prefix)) + // Namespace aliasing + if (prefix == null) + prefix = "#default"; + String resultPrefix = + (String) stylesheet.namespaceAliases.get(prefix); + if (resultPrefix != null) { - namespaceValue = XMLConstants.XML_NS_URI; + if ("#default".equals(resultPrefix)) + resultPrefix = null; + namespaceValue = source.lookupNamespaceURI(resultPrefix); } - else + if (prefix == "#default") + prefix = null; + // Look up ordinary namespace for this prefix + if (namespaceValue == null) { - // Resolve namespace for this prefix - namespaceValue = source.lookupNamespaceURI(prefix); + if (XMLConstants.XML_NS_PREFIX.equals(prefix)) + namespaceValue = XMLConstants.XML_NS_URI; + else + { + // Resolve namespace for this prefix + namespaceValue = source.lookupNamespaceURI(prefix); + } } } - /*if (prefix == null) - { - // Resolve prefix for this namespace - prefix = parent.lookupPrefix(namespaceValue); - if (prefix != null) - { - nameValue = prefix + ":" + nameValue; - } - }*/ } + // Create element Element element = (namespaceValue != null) ? doc.createElementNS(namespaceValue, nameValue) : - doc.createElement(nameValue); + doc.createElement(nameValue); if (nextSibling != null) - { - parent.insertBefore(element, nextSibling); - } + parent.insertBefore(element, nextSibling); else - { - parent.appendChild(element); - } + parent.appendChild(element); stylesheet.addNamespaceNodes(source, element, doc, elementExcludeResultPrefixes); if (uas != null) { StringTokenizer st = new StringTokenizer(uas, " "); while (st.hasMoreTokens()) - { - addAttributeSet(stylesheet, mode, context, pos, len, - element, null, st.nextToken()); - } + addAttributeSet(stylesheet, mode, context, pos, len, + element, null, st.nextToken()); } if (children != null) - { - children.apply(stylesheet, mode, - context, pos, len, - element, null); - } + children.apply(stylesheet, mode, + context, pos, len, + element, null); if (next != null) - { - next.apply(stylesheet, mode, - context, pos, len, - parent, nextSibling); - } + next.apply(stylesheet, mode, + context, pos, len, + parent, nextSibling); } final String getPrefix(String name) @@ -240,41 +206,33 @@ final class ElementNode Node parent, Node nextSibling, String attributeSet) throws TransformerException { + stylesheet.bindings.global = true; for (Iterator i = stylesheet.attributeSets.iterator(); i.hasNext(); ) { AttributeSet as = (AttributeSet) i.next(); if (!as.name.equals(attributeSet)) - { - continue; - } + continue; if (as.uas != null) { StringTokenizer st = new StringTokenizer(as.uas, " "); while (st.hasMoreTokens()) - { - addAttributeSet(stylesheet, mode, context, pos, len, - parent, nextSibling, st.nextToken()); - } + addAttributeSet(stylesheet, mode, context, pos, len, + parent, nextSibling, st.nextToken()); } if (as.children != null) - { - as.children.apply(stylesheet, mode, - context, pos, len, - parent, nextSibling); - } + as.children.apply(stylesheet, mode, + context, pos, len, + parent, nextSibling); } + stylesheet.bindings.global = false; } public boolean references(QName var) { if (name != null && name.references(var)) - { - return true; - } + return true; if (namespace != null && namespace.references(var)) - { - return true; - } + return true; return super.references(var); } @@ -283,6 +241,11 @@ final class ElementNode StringBuffer buf = new StringBuffer(getClass().getName()); buf.append('['); buf.append("name="); + if (namespace != null) + { + buf.append(",namespace="); + buf.append(namespace); + } buf.append(name); if (uas != null) { diff --git a/libjava/classpath/gnu/xml/transform/FunctionAvailableFunction.java b/libjava/classpath/gnu/xml/transform/FunctionAvailableFunction.java index 7daf7ea3f70..ab86401d0e4 100644 --- a/libjava/classpath/gnu/xml/transform/FunctionAvailableFunction.java +++ b/libjava/classpath/gnu/xml/transform/FunctionAvailableFunction.java @@ -147,11 +147,16 @@ class FunctionAvailableFunction uri = nsctx.getNamespaceURI(prefix); if (uri == null) { - return xsltFunctions.contains(localName) || - xpathFunctions.contains(localName) ? + return (xpathFunctions.contains(localName) || + xsltFunctions.contains(localName)) ? Boolean.TRUE : Boolean.FALSE; - // TODO extension functions } + else if (Stylesheet.XSL_NS.equals(uri)) + { + return xsltFunctions.contains(localName) ? + Boolean.TRUE : Boolean.FALSE; + } + // TODO extension functions return Boolean.FALSE; } @@ -159,16 +164,12 @@ class FunctionAvailableFunction { NamespaceContext n = nsctx; if (context instanceof NamespaceContext) - { - n = (NamespaceContext) context; - } + n = (NamespaceContext) context; FunctionAvailableFunction f = new FunctionAvailableFunction(n); int len = args.size(); List args2 = new ArrayList(len); for (int i = 0; i < len; i++) - { - args2.add(((Expr) args.get(i)).clone(context)); - } + args2.add(((Expr) args.get(i)).clone(context)); f.setArguments(args2); return f; } @@ -178,12 +179,15 @@ class FunctionAvailableFunction for (Iterator i = args.iterator(); i.hasNext(); ) { if (((Expr) i.next()).references(var)) - { - return true; - } + return true; } return false; } + public String toString() + { + return "function-available(" + args.get(0) + ")"; + } + } diff --git a/libjava/classpath/gnu/xml/transform/LiteralNode.java b/libjava/classpath/gnu/xml/transform/LiteralNode.java index 0be2b35c84d..453c22c5e0d 100644 --- a/libjava/classpath/gnu/xml/transform/LiteralNode.java +++ b/libjava/classpath/gnu/xml/transform/LiteralNode.java @@ -1,5 +1,5 @@ /* LiteralNode.java -- - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004,2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -77,38 +77,28 @@ final class LiteralNode elementExcludeResultPrefixes = new HashSet(); StringTokenizer st = new StringTokenizer(attr.getNodeValue()); while (st.hasMoreTokens()) - { - elementExcludeResultPrefixes.add(st.nextToken()); - } + elementExcludeResultPrefixes.add(st.nextToken()); } else - { - elementExcludeResultPrefixes = Collections.EMPTY_SET; - } + elementExcludeResultPrefixes = Collections.EMPTY_SET; } else - { - elementExcludeResultPrefixes = null; - } + elementExcludeResultPrefixes = null; } TemplateNode clone(Stylesheet stylesheet) { TemplateNode ret = new LiteralNode(source); if (children != null) - { - ret.children = children.clone(stylesheet); - } + ret.children = children.clone(stylesheet); if (next != null) - { - ret.next = next.clone(stylesheet); - } + ret.next = next.clone(stylesheet); return ret; } void doApply(Stylesheet stylesheet, QName mode, - Node context, int pos, int len, - Node parent, Node nextSibling) + Node context, int pos, int len, + Node parent, Node nextSibling) throws TransformerException { Node result = null; @@ -127,17 +117,13 @@ final class LiteralNode { String prefix = source.getPrefix(); if (prefix == null) - { - prefix = "#default"; - } + prefix = "#default"; String resultPrefix = (String) stylesheet.namespaceAliases.get(prefix); if (resultPrefix != null) { if ("#default".equals(resultPrefix)) - { - resultPrefix = null; - } + resultPrefix = null; String uri = source.lookupNamespaceURI(resultPrefix); String name = source.getNodeName(); // Create a new element node in the result document @@ -189,33 +175,23 @@ final class LiteralNode result = result2; } if (nextSibling != null) - { - parent.insertBefore(result, nextSibling); - } + parent.insertBefore(result, nextSibling); else - { - parent.appendChild(result); - } + parent.appendChild(result); if (nodeType == Node.ELEMENT_NODE) - { - stylesheet.addNamespaceNodes(source, result, doc, - elementExcludeResultPrefixes); - } + stylesheet.addNamespaceNodes(source, result, doc, + elementExcludeResultPrefixes); // children if (children != null) - { - children.apply(stylesheet, mode, - context, pos, len, - result, null); - } + children.apply(stylesheet, mode, + context, pos, len, + result, null); } // next sibling if (next != null) - { - next.apply(stylesheet, mode, - context, pos, len, - parent, nextSibling); - } + next.apply(stylesheet, mode, + context, pos, len, + parent, nextSibling); } public String toString() diff --git a/libjava/classpath/gnu/xml/transform/MessageNode.java b/libjava/classpath/gnu/xml/transform/MessageNode.java index 1df716836e7..e8e07c6da29 100644 --- a/libjava/classpath/gnu/xml/transform/MessageNode.java +++ b/libjava/classpath/gnu/xml/transform/MessageNode.java @@ -1,5 +1,5 @@ /* MessageNode.java -- - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004,2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -37,6 +37,7 @@ exception statement from your version. */ package gnu.xml.transform; +import java.util.logging.Logger; import javax.xml.namespace.QName; import javax.xml.transform.TransformerException; import org.w3c.dom.Document; @@ -53,6 +54,8 @@ final class MessageNode extends TemplateNode { + static final Logger logger = Logger.getLogger("gnu.xml.transform"); + final boolean terminate; MessageNode(boolean terminate) @@ -64,13 +67,9 @@ final class MessageNode { TemplateNode ret = new MessageNode(terminate); if (children != null) - { - ret.children = children.clone(stylesheet); - } + ret.children = children.clone(stylesheet); if (next != null) - { - ret.next = next.clone(stylesheet); - } + ret.next = next.clone(stylesheet); return ret; } @@ -86,16 +85,12 @@ final class MessageNode DocumentFragment fragment = doc.createDocumentFragment(); children.apply(stylesheet, mode, context, pos, len, fragment, null); String message = Expr.stringValue(fragment); - System.err.println(message); + logger.info(message); if (terminate) - { - stylesheet.terminated = true; - } + stylesheet.terminated = true; } if (next != null && !terminate) - { - next.apply(stylesheet, mode, context, pos, len, parent, nextSibling); - } + next.apply(stylesheet, mode, context, pos, len, parent, nextSibling); } } diff --git a/libjava/classpath/gnu/xml/transform/NamespaceProxy.java b/libjava/classpath/gnu/xml/transform/NamespaceProxy.java new file mode 100644 index 00000000000..b3c233cd7a5 --- /dev/null +++ b/libjava/classpath/gnu/xml/transform/NamespaceProxy.java @@ -0,0 +1,77 @@ +/* NamespaceProxy.java -- + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.transform; + +import java.util.Collections; +import java.util.Iterator; +import javax.xml.namespace.NamespaceContext; +import org.w3c.dom.Node; + +/** + * A namespace context using a DOM node to resolve the namespace. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +class NamespaceProxy + implements NamespaceContext +{ + + private final Node node; + + NamespaceProxy(Node node) + { + this.node = node; + } + + public String getNamespaceURI(String prefix) + { + return (node == null) ? null : node.lookupNamespaceURI(prefix); + } + + public String getPrefix(String namespaceURI) + { + return (node == null) ? null : node.lookupPrefix(namespaceURI); + } + + public Iterator getPrefixes(String namespaceURI) + { + // TODO + return Collections.singleton(getPrefix(namespaceURI)).iterator(); + } + +} diff --git a/libjava/classpath/gnu/xml/transform/StreamSerializer.java b/libjava/classpath/gnu/xml/transform/StreamSerializer.java index 74b10057c12..fb8b1a601bc 100644 --- a/libjava/classpath/gnu/xml/transform/StreamSerializer.java +++ b/libjava/classpath/gnu/xml/transform/StreamSerializer.java @@ -1,5 +1,5 @@ /* StreamSerializer.java -- - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004,2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -49,6 +49,8 @@ import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; import java.util.Map; import javax.xml.XMLConstants; import org.w3c.dom.Attr; @@ -149,16 +151,25 @@ public class StreamSerializer HTML_BOOLEAN_ATTRIBUTES.put("script", set); } + // HTML namespace URIs + static final HashSet HTML_URIS = new HashSet(); + static { + HTML_URIS.add("http://www.w3.org/1999/xhtml"); + } + protected final String encoding; final Charset charset; final CharsetEncoder encoder; final int mode; - final Map namespaces; + final LinkedList namespaces; protected String eol; Collection cdataSectionElements = Collections.EMPTY_SET; protected boolean discardDefaultContent; protected boolean xmlDeclaration = true; + + // has a META element with the encoding been added? + private boolean htmlEncoded; public StreamSerializer() { @@ -174,14 +185,12 @@ public class StreamSerializer { this.mode = mode; if (encoding == null) - { - encoding = "UTF-8"; - } + encoding = (mode == Stylesheet.OUTPUT_HTML) ? "ISO-8859-1" : "UTF-8"; this.encoding = encoding.intern(); charset = Charset.forName(this.encoding); encoder = charset.newEncoder(); this.eol = (eol != null) ? eol : System.getProperty("line.separator"); - namespaces = new HashMap(); + namespaces = new LinkedList(); } void setCdataSectionElements(Collection c) @@ -212,18 +221,14 @@ public class StreamSerializer throws IOException { if (out == null) - { - throw new NullPointerException("no output stream"); - } + throw new NullPointerException("no output stream"); + htmlEncoded = false; String value, prefix; Node children; String uri = node.getNamespaceURI(); - boolean defined = false; short nt = node.getNodeType(); if (convertToCdata && nt == Node.TEXT_NODE) - { - nt = Node.CDATA_SECTION_NODE; - } + nt = Node.CDATA_SECTION_NODE; switch (nt) { case Node.ATTRIBUTE_NODE: @@ -233,27 +238,28 @@ public class StreamSerializer (prefix != null && prefix.startsWith("xmlns:"))) { String nsuri = node.getNodeValue(); - if (isDefined(nsuri)) - { - break; - } + if (isDefined(nsuri, prefix)) + break; String name = node.getLocalName(); if (name == null) { + // Namespace-unaware name = node.getNodeName(); + int ci = name.indexOf(':'); + if (ci != -1) + name = name.substring(ci + 1); } define(nsuri, name); } - else if (uri != null && !isDefined(uri)) + else if (uri != null && !isDefined(uri, prefix)) { prefix = define(uri, prefix); String nsname = (prefix == null) ? "xmlns" : "xmlns:" + prefix; out.write(SPACE); out.write(encodeText(nsname)); out.write(EQ); - String nsvalue = "'" + encode(uri, true, true) + "'"; + String nsvalue = "\"" + encode(uri, true, true) + "\""; out.write(nsvalue.getBytes(encoding)); - defined = true; } out.write(SPACE); String a_nodeName = node.getNodeName(); @@ -262,27 +268,26 @@ public class StreamSerializer if (mode == Stylesheet.OUTPUT_HTML && a_nodeName.equals(a_nodeValue) && isHTMLBoolean((Attr) node, a_nodeName)) - { - break; - } + break; out.write(EQ); - value = "'" + encode(a_nodeValue, true, true) + "'"; + value = "\"" + encode(a_nodeValue, true, true) + "\""; out.write(encodeText(value)); break; case Node.ELEMENT_NODE: + pushNamespaceContext(); value = node.getNodeName(); out.write(BRA); out.write(encodeText(value)); - if (uri != null && !isDefined(uri)) + prefix = node.getPrefix(); + if (uri != null && !isDefined(uri, prefix)) { - prefix = define(uri, node.getPrefix()); + prefix = define(uri, prefix); String nsname = (prefix == null) ? "xmlns" : "xmlns:" + prefix; out.write(SPACE); out.write(encodeText(nsname)); out.write(EQ); - String nsvalue = "'" + encode(uri, true, true) + "'"; + String nsvalue = "\"" + encode(uri, true, true) + "\""; out.write(encodeText(nsvalue)); - defined = true; } NamedNodeMap attrs = node.getAttributes(); if (attrs != null) @@ -296,9 +301,7 @@ public class StreamSerializer // NOOP } else - { - serialize(attr, out, false); - } + serialize(attr, out, false); } } convertToCdata = cdataSectionElements.contains(value); @@ -317,27 +320,35 @@ public class StreamSerializer out.write(encodeText(value)); out.write(KET); } + popNamespaceContext(); break; case Node.TEXT_NODE: value = node.getNodeValue(); if (!"yes".equals(node.getUserData("disable-output-escaping"))) - { - value = encode(value, false, false); - } + value = encode(value, false, false); out.write(encodeText(value)); break; case Node.CDATA_SECTION_NODE: - value = "<![CDATA[" + node.getNodeValue() + "]]>"; - out.write(encodeText(value)); + value = node.getNodeValue(); + // Where any instanceof of ]]> occur, split into multiple CDATA + // sections + int bbk = value.indexOf("]]>"); + while (bbk != -1) + { + String head = value.substring(0, bbk + 2); + out.write(encodeText("<![CDATA[" + head + "]]>")); + value = value.substring(bbk + 2); + bbk = value.indexOf("]]>"); + } + // Write final tail value + out.write(encodeText("<![CDATA[" + value + "]]>")); break; case Node.COMMENT_NODE: value = "<!--" + node.getNodeValue() + "-->"; out.write(encodeText(value)); Node cp = node.getParentNode(); if (cp != null && cp.getNodeType() == Node.DOCUMENT_NODE) - { - out.write(encodeText(eol)); - } + out.write(encodeText(eol)); break; case Node.DOCUMENT_NODE: case Node.DOCUMENT_FRAGMENT_NODE: @@ -355,29 +366,23 @@ public class StreamSerializer (Document) node : null; String version = (doc != null) ? doc.getXmlVersion() : null; if (version == null) - { - version = (String) node.getUserData("version"); - } + version = (String) node.getUserData("version"); if (version == null) - { - version = "1.0"; - } + version = "1.0"; out.write(BRA); out.write(0x3f); - out.write("xml version='".getBytes("US-ASCII")); + out.write("xml version=\"".getBytes("US-ASCII")); out.write(version.getBytes("US-ASCII")); - out.write(APOS); + out.write(0x22); if (!("UTF-8".equalsIgnoreCase(encoding))) { - out.write(" encoding='".getBytes("US-ASCII")); + out.write(" encoding=\"".getBytes("US-ASCII")); out.write(encoding.getBytes("US-ASCII")); - out.write(APOS); + out.write(0x22); } if ((doc != null && doc.getXmlStandalone()) || "yes".equals(node.getUserData("standalone"))) - { - out.write(" standalone='yes'".getBytes("US-ASCII")); - } + out.write(" standalone=\"yes\"".getBytes("US-ASCII")); out.write(0x3f); out.write(KET); out.write(encodeText(eol)); @@ -387,12 +392,10 @@ public class StreamSerializer } else if (mode == Stylesheet.OUTPUT_HTML) { - // Ensure that encoding is accessible + // Ensure that encoding is accessible if head element is present String mediaType = (String) node.getUserData("media-type"); if (mediaType == null) - { - mediaType = "text/html"; - } + mediaType = "text/html"; String contentType = mediaType + "; charset=" + ((encoding.indexOf(' ') != -1) ? "\"" + encoding + "\"" : @@ -403,133 +406,87 @@ public class StreamSerializer for (Node ctx = node.getFirstChild(); ctx != null; ctx = ctx.getNextSibling()) { - if (ctx.getNodeType() == Node.ELEMENT_NODE) + if (ctx.getNodeType() == Node.ELEMENT_NODE && + isHTMLElement(ctx, "html")) { html = ctx; break; } } - if (html == null) - { - html = doc.createElement("html"); - node.appendChild(html); - } - Node head = null; - for (Node ctx = html.getFirstChild(); ctx != null; - ctx = ctx.getNextSibling()) + if (html != null) { - if (ctx.getNodeType() == Node.ELEMENT_NODE) - { - String name = ctx.getLocalName(); - if (name == null) - { - name = ctx.getNodeName(); - } - if ("head".equalsIgnoreCase(name)) - { - head = ctx; - break; - } - } - } - if (head == null) - { - head = doc.createElement("head"); - Node c1 = null; + Node head = null; for (Node ctx = html.getFirstChild(); ctx != null; ctx = ctx.getNextSibling()) { - if (ctx.getNodeType() == Node.ELEMENT_NODE) + if (isHTMLElement(ctx, "head")) { - c1 = ctx; + head = ctx; break; } } - if (c1 != null) - { - html.insertBefore(head, c1); - } - else - { - html.appendChild(head); - } - } - Node meta = null; - Node metaContent = null; - for (Node ctx = head.getFirstChild(); ctx != null; - ctx = ctx.getNextSibling()) - { - if (ctx.getNodeType() == Node.ELEMENT_NODE) + if (head != null) { - String name = ctx.getLocalName(); - if (name == null) - { - name = ctx.getNodeName(); - } - if ("meta".equalsIgnoreCase(name)) + Node meta = null; + Node metaContent = null; + for (Node ctx = head.getFirstChild(); ctx != null; + ctx = ctx.getNextSibling()) { - NamedNodeMap metaAttrs = ctx.getAttributes(); - int len = metaAttrs.getLength(); - String httpEquiv = null; - Node content = null; - for (int i = 0; i < len; i++) + if (isHTMLElement(ctx, "meta")) { - Node attr = metaAttrs.item(i); - String attrName = attr.getNodeName(); - if ("http-equiv".equalsIgnoreCase(attrName)) + NamedNodeMap metaAttrs = ctx.getAttributes(); + int len = metaAttrs.getLength(); + String httpEquiv = null; + Node content = null; + for (int i = 0; i < len; i++) { - httpEquiv = attr.getNodeValue(); + Node attr = metaAttrs.item(i); + String attrName = attr.getNodeName(); + if ("http-equiv".equalsIgnoreCase(attrName)) + httpEquiv = attr.getNodeValue(); + else if ("content".equalsIgnoreCase(attrName)) + content = attr; } - else if ("content".equalsIgnoreCase(attrName)) + if ("Content-Type".equalsIgnoreCase(httpEquiv)) { - content = attr; + meta = ctx; + metaContent = content; + break; } } - if ("Content-Type".equalsIgnoreCase(httpEquiv)) - { - meta = ctx; - metaContent = content; - break; - } } + if (meta == null) + { + meta = doc.createElement("meta"); + // Insert first + Node first = head.getFirstChild(); + if (first == null) + head.appendChild(meta); + else + head.insertBefore(meta, first); + Node metaHttpEquiv = doc.createAttribute("http-equiv"); + meta.getAttributes().setNamedItem(metaHttpEquiv); + metaHttpEquiv.setNodeValue("Content-Type"); + } + if (metaContent == null) + { + metaContent = doc.createAttribute("content"); + meta.getAttributes().setNamedItem(metaContent); + } + metaContent.setNodeValue(contentType); + htmlEncoded = true; } } - if (meta == null) - { - meta = doc.createElement("meta"); - // Insert first - Node first = head.getFirstChild(); - if (first == null) - { - head.appendChild(meta); - } - else - { - head.insertBefore(meta, first); - } - Node metaHttpEquiv = doc.createAttribute("http-equiv"); - meta.getAttributes().setNamedItem(metaHttpEquiv); - metaHttpEquiv.setNodeValue("Content-Type"); - } - if (metaContent == null) - { - metaContent = doc.createAttribute("content"); - meta.getAttributes().setNamedItem(metaContent); - } - metaContent.setNodeValue(contentType); - // phew } children = node.getFirstChild(); if (children != null) - { - serialize(children, out, convertToCdata); - } + serialize(children, out, convertToCdata); break; case Node.DOCUMENT_TYPE_NODE: DocumentType doctype = (DocumentType) node; out.write(BRA); out.write(BANG); - out.write(encodeText("DOCTYPE ")); + out.write(encodeText("DOCTYPE ")); value = doctype.getNodeName(); out.write(encodeText(value)); String publicId = doctype.getPublicId(); @@ -569,41 +526,73 @@ public class StreamSerializer out.write(encodeText(eol)); } break; + default: + System.err.println("Unhandled node type: "+nt); } - if (defined) + } + + boolean isHTMLElement(Node node, String name) + { + if (node.getNodeType() != Node.ELEMENT_NODE) + return false; + String localName = node.getLocalName(); + if (localName == null) + localName = node.getNodeName(); + if (!name.equalsIgnoreCase(localName)) + return false; + String uri = node.getNamespaceURI(); + return (uri == null || HTML_URIS.contains(uri)); + } + + boolean isDefined(String uri, String prefix) + { + if (XMLConstants.XML_NS_URI.equals(uri)) + return "xml".equals(prefix); + if (XMLConstants.XMLNS_ATTRIBUTE_NS_URI.equals(uri)) + return "xmlns".equals(prefix); + if (prefix == null) + prefix = ""; + for (Iterator i = namespaces.iterator(); i.hasNext(); ) { - undefine(uri); + Map ctx = (Map) i.next(); + String val = (String) ctx.get(uri); + if (val != null && val.equals(prefix)) + return true; } + return false; } - boolean isDefined(String uri) + void pushNamespaceContext() { - return XMLConstants.XML_NS_URI.equals(uri) || - XMLConstants.XMLNS_ATTRIBUTE_NS_URI.equals(uri) || - namespaces.containsKey(uri); + namespaces.addFirst(new HashMap()); } String define(String uri, String prefix) { - while (namespaces.containsValue(prefix)) + if (namespaces.isEmpty()) + return prefix; + HashMap ctx = (HashMap) namespaces.getFirst(); + while (ctx.containsValue(prefix)) { // Fabricate new prefix prefix = prefix + "_"; } - namespaces.put(uri, prefix); + ctx.put(uri, prefix); return prefix; } - void undefine(String uri) + void popNamespaceContext() { - namespaces.remove(uri); + namespaces.removeFirst(); } final byte[] encodeText(String text) throws IOException { encoder.reset(); - if (!encoder.canEncode(text)) + boolean htmlNeedingEncoding = + (mode == Stylesheet.OUTPUT_HTML && !htmlEncoded); + if (!encoder.canEncode(text) || htmlNeedingEncoding) { // Check each character StringBuffer buf = new StringBuffer(); @@ -611,11 +600,7 @@ public class StreamSerializer for (int i = 0; i < len; i++) { char c = text.charAt(i); - if (encoder.canEncode(c)) - { - buf.append(c); - } - else + if (!encoder.canEncode(c)) { // Replace with character entity reference String hex = Integer.toHexString((int) c); @@ -623,6 +608,20 @@ public class StreamSerializer buf.append(hex); buf.append(';'); } + else if (htmlNeedingEncoding) + { + String entityName = getHTMLCharacterEntity(c); + if (entityName != null) + { + buf.append('&'); + buf.append(entityName); + buf.append(';'); + } + else + buf.append(c); + } + else + buf.append(c); } text = buf.toString(); } @@ -656,17 +655,13 @@ public class StreamSerializer if (c == '<') { if (buf == null) - { - buf = new StringBuffer(text.substring(0, i)); - } + buf = new StringBuffer(text.substring(0, i)); buf.append("<"); } else if (c == '>') { if (buf == null) - { - buf = new StringBuffer(text.substring(0, i)); - } + buf = new StringBuffer(text.substring(0, i)); buf.append(">"); } else if (c == '&') @@ -675,25 +670,19 @@ public class StreamSerializer text.charAt(i + 1) == '{') { if (buf != null) - { - buf.append(c); - } + buf.append(c); } else { if (buf == null) - { - buf = new StringBuffer(text.substring(0, i)); - } + buf = new StringBuffer(text.substring(0, i)); buf.append("&"); } } else if (c == '\'' && inAttr) { if (buf == null) - { - buf = new StringBuffer(text.substring(0, i)); - } + buf = new StringBuffer(text.substring(0, i)); if (mode == Stylesheet.OUTPUT_HTML) // HTML does not define ', use character entity ref buf.append("'"); @@ -703,9 +692,7 @@ public class StreamSerializer else if (c == '"' && inAttr) { if (buf == null) - { - buf = new StringBuffer(text.substring(0, i)); - } + buf = new StringBuffer(text.substring(0, i)); buf.append("""); } else if (encodeCtl) @@ -713,23 +700,17 @@ public class StreamSerializer if (c < 0x20) { if (buf == null) - { - buf = new StringBuffer(text.substring(0, i)); - } + buf = new StringBuffer(text.substring(0, i)); buf.append('&'); buf.append('#'); buf.append((int) c); buf.append(';'); } else if (buf != null) - { - buf.append(c); - } + buf.append(c); } else if (buf != null) - { - buf.append(c); - } + buf.append(c); } return (buf == null) ? text : buf.toString(); } @@ -763,4 +744,109 @@ public class StreamSerializer return (attributes != null && attributes.contains(attrName)); } + static String getHTMLCharacterEntity(char c) + { + // Hardcode these here to avoid loading the HTML DTD + switch (c) + { + case 160: return "nbsp"; + case 161: return "iexcl"; + case 162: return "cent"; + case 163: return "pound"; + case 164: return "curren"; + case 165: return "yen"; + case 166: return "brvbar"; + case 167: return "sect"; + case 168: return "uml"; + case 169: return "copy"; + case 170: return "ordf"; + case 171: return "laquo"; + case 172: return "not"; + case 173: return "shy"; + case 174: return "reg"; + case 175: return "macr"; + case 176: return "deg"; + case 177: return "plusmn"; + case 178: return "sup2"; + case 179: return "sup3"; + case 180: return "acute"; + case 181: return "micro"; + case 182: return "para"; + case 183: return "middot"; + case 184: return "cedil"; + case 185: return "sup1"; + case 186: return "ordm"; + case 187: return "raquo"; + case 188: return "frac14"; + case 189: return "frac12"; + case 190: return "frac34"; + case 191: return "iquest"; + case 192: return "Agrave"; + case 193: return "Aacute"; + case 194: return "Acirc"; + case 195: return "Atilde"; + case 196: return "Auml"; + case 197: return "Aring"; + case 198: return "AElig"; + case 199: return "Ccedil"; + case 200: return "Egrave"; + case 201: return "Eacute"; + case 202: return "Ecirc"; + case 203: return "Euml"; + case 204: return "Igrave"; + case 205: return "Iacute"; + case 206: return "Icirc"; + case 207: return "Iuml"; + case 208: return "ETH"; + case 209: return "Ntilde"; + case 210: return "Ograve"; + case 211: return "Oacute"; + case 212: return "Ocirc"; + case 213: return "Otilde"; + case 214: return "Ouml"; + case 215: return "times"; + case 216: return "Oslash"; + case 217: return "Ugrave"; + case 218: return "Uacute"; + case 219: return "Ucirc"; + case 220: return "Uuml"; + case 221: return "Yacute"; + case 222: return "THORN"; + case 223: return "szlig"; + case 224: return "agrave"; + case 225: return "aacute"; + case 226: return "acirc"; + case 227: return "atilde"; + case 228: return "auml"; + case 229: return "aring"; + case 230: return "aelig"; + case 231: return "ccedil"; + case 232: return "egrave"; + case 233: return "eacute"; + case 234: return "ecirc"; + case 235: return "euml"; + case 236: return "igrave"; + case 237: return "iacute"; + case 238: return "icirc"; + case 239: return "iuml"; + case 240: return "eth"; + case 241: return "ntilde"; + case 242: return "ograve"; + case 243: return "oacute"; + case 244: return "ocirc"; + case 245: return "otilde"; + case 246: return "ouml"; + case 247: return "divide"; + case 248: return "oslash"; + case 249: return "ugrave"; + case 250: return "uacute"; + case 251: return "ucirc"; + case 252: return "uuml"; + case 253: return "yacute"; + case 254: return "thorn"; + case 255: return "yuml"; + default: return null; + } + } + } diff --git a/libjava/classpath/gnu/xml/transform/StrippingInstruction.java b/libjava/classpath/gnu/xml/transform/StrippingInstruction.java new file mode 100644 index 00000000000..c6391b9c521 --- /dev/null +++ b/libjava/classpath/gnu/xml/transform/StrippingInstruction.java @@ -0,0 +1,73 @@ +/* StrippingInstruction.java -- + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.transform; + +import gnu.xml.xpath.NameTest; + +/** + * An entry in a strip-space or preserve-space list. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +class StrippingInstruction +{ + + final NameTest element; + final int precedence; + + StrippingInstruction(NameTest element, int precedence) + { + this.element = element; + this.precedence = precedence; + } + + /** + * Returns the <i>default priority</i> of the element name test. + * @see http://www.w3.org/TR/xslt#dt-default-priority + */ + float getPriority() + { + if (element.matchesAny()) + return -0.5f; + else if (element.matchesAnyLocalName()) + return -0.25f; + else + return 0.0f; + } + +} diff --git a/libjava/classpath/gnu/xml/transform/Stylesheet.java b/libjava/classpath/gnu/xml/transform/Stylesheet.java index 99431b699d8..51accaa3b9a 100644 --- a/libjava/classpath/gnu/xml/transform/Stylesheet.java +++ b/libjava/classpath/gnu/xml/transform/Stylesheet.java @@ -1,5 +1,5 @@ /* Stylesheet.java -- - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004,2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -88,6 +88,8 @@ class Stylesheet { static final String XSL_NS = "http://www.w3.org/1999/XSL/Transform"; + private static final NameTest STYLESHEET_PRESERVE_TEXT = + new NameTest(new QName(XSL_NS, "text"), false, false); static final int OUTPUT_XML = 0; static final int OUTPUT_HTML = 1; @@ -208,6 +210,7 @@ class Stylesheet preserveSpace = new LinkedHashSet(); outputCdataSectionElements = new LinkedHashSet(); xpath = (XPathImpl) factory.xpathFactory.newXPath(); + xpath.setNamespaceContext(this); if (parent == null) { bindings = new Bindings(this); @@ -218,7 +221,6 @@ class Stylesheet keys = new LinkedList(); decimalFormats = new LinkedHashMap(); initDefaultDecimalFormat(); - xpath.setNamespaceContext(this); xpath.setXPathFunctionResolver(this); } else @@ -241,7 +243,6 @@ class Stylesheet templates = root.templates; keys = root.keys; decimalFormats = root.decimalFormats; - xpath.setNamespaceContext(root); xpath.setXPathFunctionResolver(root); } xpath.setXPathVariableResolver(bindings); @@ -276,9 +277,7 @@ class Stylesheet { Stylesheet stylesheet = this; while (stylesheet.parent != null) - { - stylesheet = stylesheet.parent; - } + stylesheet = stylesheet.parent; return stylesheet; } @@ -408,9 +407,7 @@ class Stylesheet throws TransformerException { if (debug) - { - System.err.println("getTemplate: mode="+mode+" context="+context); - } + System.err.println("getTemplate: mode="+mode+" context="+context); Set candidates = new TreeSet(); for (Iterator j = templates.iterator(); j.hasNext(); ) { @@ -425,15 +422,11 @@ class Stylesheet throw new TransformerException(msg); } if (!currentTemplate.imports(t)) - { - isMatch = false; - } + isMatch = false; } //System.err.println("\t"+context+" "+t+"="+isMatch); if (isMatch) - { - candidates.add(t); - } + candidates.add(t); } //System.err.println("\tcandidates="+candidates); if (candidates.isEmpty()) @@ -441,9 +434,7 @@ class Stylesheet // Apply built-in template // Current template is unchanged if (debug) - { - System.err.println("\tbuiltInTemplate context="+context); - } + System.err.println("\tbuiltInTemplate context="+context); switch (context.getNodeType()) { case Node.ELEMENT_NODE: @@ -453,6 +444,7 @@ class Stylesheet case Node.COMMENT_NODE: return builtInNodeTemplate; case Node.TEXT_NODE: + case Node.CDATA_SECTION_NODE: case Node.ATTRIBUTE_NODE: return builtInTextTemplate; default: @@ -465,9 +457,7 @@ class Stylesheet // Set current template currentTemplate = t; if (debug) - { - System.err.println("\ttemplate="+t+" context="+context); - } + System.err.println("\ttemplate="+t+" context="+context); return t.node; } } @@ -475,25 +465,17 @@ class Stylesheet TemplateNode getTemplate(QName mode, QName name) throws TransformerException { - //System.err.println("getTemplate: mode="+mode+" name="+name); Set candidates = new TreeSet(); for (Iterator j = templates.iterator(); j.hasNext(); ) { Template t = (Template) j.next(); boolean isMatch = t.matches(name); - //System.err.println("\t"+name+" "+t+"="+isMatch); if (isMatch) - { - candidates.add(t); - } + candidates.add(t); } if (candidates.isEmpty()) - { - return null; - //throw new TransformerException("template '" + name + "' not found"); - } + return null; Template t = (Template) candidates.iterator().next(); - //System.err.println("\ttemplate="+t+" context="+context); return t.node; } @@ -538,42 +520,30 @@ class Stylesheet output = node; String method = getAttribute(attrs, "method"); if ("xml".equals(method) || method == null) - { - outputMethod = OUTPUT_XML; - } + outputMethod = OUTPUT_XML; else if ("html".equals(method)) - { - outputMethod = OUTPUT_HTML; - } + outputMethod = OUTPUT_HTML; else if ("text".equals(method)) - { - outputMethod = OUTPUT_TEXT; - } + outputMethod = OUTPUT_TEXT; else { String msg = "unsupported output method: " + method; DOMSourceLocator l = new DOMSourceLocator(node); throw new TransformerConfigurationException(msg, l); } - outputPublicId = getAttribute(attrs, "public-id"); - outputSystemId = getAttribute(attrs, "system-id"); + outputPublicId = getAttribute(attrs, "doctype-public"); + outputSystemId = getAttribute(attrs, "doctype-system"); outputEncoding = getAttribute(attrs, "encoding"); String indent = getAttribute(attrs, "indent"); if (indent != null) - { - outputIndent = "yes".equals(indent); - } + outputIndent = "yes".equals(indent); outputVersion = getAttribute(attrs, "version"); String omitXmlDecl = getAttribute(attrs, "omit-xml-declaration"); if (omitXmlDecl != null) - { - outputOmitXmlDeclaration = "yes".equals(omitXmlDecl); - } + outputOmitXmlDeclaration = "yes".equals(omitXmlDecl); String standalone = getAttribute(attrs, "standalone"); if (standalone != null) - { - outputStandalone = "yes".equals(standalone); - } + outputStandalone = "yes".equals(standalone); outputMediaType = getAttribute(attrs, "media-type"); String cdataSectionElements = getAttribute(attrs, "cdata-section-elements"); @@ -581,9 +551,7 @@ class Stylesheet { StringTokenizer st = new StringTokenizer(cdataSectionElements, " "); while (st.hasMoreTokens()) - { - outputCdataSectionElements.add(st.nextToken()); - } + outputCdataSectionElements.add(st.nextToken()); } } @@ -728,9 +696,7 @@ class Stylesheet parse(node.getFirstChild(), false); } else if ("template".equals(name)) - { - templates.add(parseTemplate(node, attrs)); - } + templates.add(parseTemplate(node, attrs)); else if ("param".equals(name) || "variable".equals(name)) { @@ -779,9 +745,7 @@ class Stylesheet factory.newStylesheet(source, precedence + delta, this); } else if ("output".equals(name)) - { - parseOutput(node, attrs); - } + parseOutput(node, attrs); else if ("preserve-space".equals(name)) { String elements = @@ -790,7 +754,9 @@ class Stylesheet " \t\n\r"); while (st.hasMoreTokens()) { - preserveSpace.add(parseNameTest(st.nextToken())); + NameTest element = parseNameTest(st.nextToken()); + preserveSpace.add(new StrippingInstruction(element, + precedence)); } } else if ("strip-space".equals(name)) @@ -801,25 +767,19 @@ class Stylesheet " \t\n\r"); while (st.hasMoreTokens()) { - stripSpace.add(parseNameTest(st.nextToken())); + NameTest element = parseNameTest(st.nextToken()); + stripSpace.add(new StrippingInstruction(element, + precedence)); } } else if ("key".equals(name)) - { - parseKey(node, attrs); - } + parseKey(node, attrs); else if ("decimal-format".equals(name)) - { - parseDecimalFormat(node, attrs); - } + parseDecimalFormat(node, attrs); else if ("namespace-alias".equals(name)) - { - parseNamespaceAlias(node, attrs); - } + parseNamespaceAlias(node, attrs); else if ("attribute-set".equals(name)) - { - parseAttributeSet(node, attrs); - } + parseAttributeSet(node, attrs); } else if (root) { @@ -867,12 +827,10 @@ class Stylesheet final NameTest parseNameTest(String token) { if ("*".equals(token)) - { - return new NameTest(null, true, true); - } + return new NameTest(null, true, true); else if (token.endsWith(":*")) { - QName qName = getQName(token.substring(0, token.length() - 2)); + QName qName = getQName(token); return new NameTest(qName, true, false); } else @@ -984,7 +942,13 @@ class Stylesheet return ret; } - boolean isPreserved(Text text) + /** + * Whitespace stripping. + * @param text the text node + * @param source true if a source node, false if a stylesheet text node + * @see http://www.w3.org/TR/xslt#strip + */ + boolean isPreserved(Text text, boolean source) throws TransformerConfigurationException { // Check characters in text @@ -996,39 +960,73 @@ class Stylesheet { char c = value.charAt(i); if (c != 0x20 && c != 0x09 && c != 0x0a && c != 0x0d) - { - return true; - } + return true; } } // Check parent node Node ctx = text.getParentNode(); - if (!preserveSpace.isEmpty()) + if (source) { - for (Iterator i = preserveSpace.iterator(); i.hasNext(); ) + // Source document text node + boolean preserve = true; + float psPriority = 0.0f, ssPriority = 0.0f; + if (!stripSpace.isEmpty()) { - NameTest preserveTest = (NameTest) i.next(); - if (preserveTest.matches(ctx, 1, 1)) + // Conflict resolution + StrippingInstruction ssi = null, psi = null; + for (Iterator i = stripSpace.iterator(); i.hasNext(); ) + { + StrippingInstruction si = (StrippingInstruction) i.next(); + if (si.element.matches(ctx, 1, 1)) + { + if (ssi != null) + { + if (si.precedence < ssi.precedence) + continue; + float p = si.getPriority(); + if (p < ssPriority) + continue; + } + ssi = si; + } + } + for (Iterator i = preserveSpace.iterator(); i.hasNext(); ) { - boolean override = false; - if (!stripSpace.isEmpty()) + StrippingInstruction si = (StrippingInstruction) i.next(); + if (si.element.matches(ctx, 1, 1)) { - for (Iterator j = stripSpace.iterator(); j.hasNext(); ) + if (psi != null) { - NameTest stripTest = (NameTest) j.next(); - if (stripTest.matches(ctx, 1, 1)) - { - override = true; - break; - } + if (si.precedence < psi.precedence) + continue; + float p = si.getPriority(); + if (p < psPriority) + continue; } + psi = si; } - if (!override) + } + if (ssi != null) + { + if (psi != null) { - return true; + if (psi.precedence < ssi.precedence) + preserve = false; + else if (psPriority < ssPriority) + preserve = false; } + else + preserve = false; } } + if (preserve) + return true; + } + else + { + // Stylesheet text node + if (STYLESHEET_PRESERVE_TEXT.matches(ctx, 1, 1)) + return true; } // Check whether any ancestor specified xml:space while (ctx != null) @@ -1038,24 +1036,14 @@ class Stylesheet Element element = (Element) ctx; String xmlSpace = element.getAttribute("xml:space"); if ("default".equals(xmlSpace)) - { - break; - } + break; else if ("preserve".equals(xmlSpace)) - { - return true; - } + return true; else if (xmlSpace.length() > 0) { String msg = "Illegal value for xml:space: " + xmlSpace; throw new TransformerConfigurationException(msg); } - else if ("text".equals(ctx.getLocalName()) && - XSL_NS.equals(ctx.getNamespaceURI())) - { - // xsl:text implies xml:space='preserve' - return true; - } } ctx = ctx.getParentNode(); } @@ -1071,45 +1059,27 @@ class Stylesheet if ("document".equals(localName) && (arity == 1 || arity == 2)) { if (current == null) - { throw new RuntimeException("current is null"); - } return new DocumentFunction(getRootStylesheet(), current); } else if ("key".equals(localName) && (arity == 2)) - { - return new KeyFunction(getRootStylesheet()); - } + return new KeyFunction(getRootStylesheet()); else if ("format-number".equals(localName) && (arity == 2 || arity == 3)) - { - return new FormatNumberFunction(getRootStylesheet()); - } + return new FormatNumberFunction(getRootStylesheet()); else if ("current".equals(localName) && (arity == 0)) - { - return new CurrentFunction(getRootStylesheet()); - } + return new CurrentFunction(getRootStylesheet()); else if ("unparsed-entity-uri".equals(localName) && (arity == 1)) - { - return new UnparsedEntityUriFunction(); - } + return new UnparsedEntityUriFunction(); else if ("generate-id".equals(localName) && (arity == 1 || arity == 0)) - { - return new GenerateIdFunction(); - } + return new GenerateIdFunction(); else if ("system-property".equals(localName) && (arity == 1)) - { - return new SystemPropertyFunction(); - } + return new SystemPropertyFunction(); else if ("element-available".equals(localName) && (arity == 1)) - { - return new ElementAvailableFunction(this); - } + return new ElementAvailableFunction(new NamespaceProxy(current)); else if ("function-available".equals(localName) && (arity == 1)) - { - return new FunctionAvailableFunction(this); - } + return new FunctionAvailableFunction(new NamespaceProxy(current)); } return null; } @@ -1127,9 +1097,7 @@ class Stylesheet QName mode = (m == null) ? null : getQName(m); String s = getAttribute(attrs, "select"); if (s == null) - { - s = "child::node()"; - } + s = "child::node()"; Node children = node.getFirstChild(); List sortKeys = parseSortKeys(children); List withParams = parseWithParams(children); @@ -1411,13 +1379,9 @@ class Stylesheet if (tnode != null) { if (first == null) - { - first = tnode; - } + first = tnode; if (previous != null) - { - previous.next = tnode; - } + previous.next = tnode; previous = tnode; } node = next; @@ -1438,25 +1402,15 @@ class Stylesheet { String name = node.getLocalName(); if ("apply-templates".equals(name)) - { - return parseApplyTemplates(node); - } + return parseApplyTemplates(node); else if ("call-template".equals(name)) - { - return parseCallTemplate(node); - } + return parseCallTemplate(node); else if ("value-of".equals(name)) - { - return parseValueOf(node); - } + return parseValueOf(node); else if ("for-each".equals(name)) - { - return parseForEach(node); - } + return parseForEach(node); else if ("if".equals(name)) - { - return parseIf(node); - } + return parseIf(node); else if ("choose".equals(name)) { Node children = node.getFirstChild(); @@ -1465,9 +1419,7 @@ class Stylesheet return ret; } else if ("when".equals(name)) - { - return parseWhen(node); - } + return parseWhen(node); else if ("otherwise".equals(name)) { Node children = node.getFirstChild(); @@ -1476,25 +1428,15 @@ class Stylesheet return ret; } else if ("element".equals(name)) - { - return parseElement(node); - } + return parseElement(node); else if ("attribute".equals(name)) - { - return parseAttribute(node); - } + return parseAttribute(node); else if ("text".equals(name)) - { - return parseText(node); - } + return parseText(node); else if ("copy".equals(name)) - { - return parseCopy(node); - } + return parseCopy(node); else if ("processing-instruction".equals(name)) - { - return parseProcessingInstruction(node); - } + return parseProcessingInstruction(node); else if ("comment".equals(name)) { Node children = node.getFirstChild(); @@ -1503,9 +1445,7 @@ class Stylesheet return ret; } else if ("number".equals(name)) - { - return parseNumber(node); - } + return parseNumber(node); else if ("param".equals(name) || "variable".equals(name)) { @@ -1538,13 +1478,9 @@ class Stylesheet return ret; } else if ("copy-of".equals(name)) - { - return parseCopyOf(node); - } + return parseCopyOf(node); else if ("message".equals(name)) - { - return parseMessage(node); - } + return parseMessage(node); else if ("apply-imports".equals(name)) { Node children = node.getFirstChild(); @@ -1562,22 +1498,30 @@ class Stylesheet String prefix = node.getPrefix(); if (extensionElementPrefixes.contains(prefix)) { - // Pass over extension elements + // Check for xsl:fallback + for (Node ctx = node.getFirstChild(); ctx != null; + ctx = ctx.getNextSibling()) + { + String ctxUri = ctx.getNamespaceURI(); + if (XSL_NS.equals(ctxUri) && + "fallback".equals(ctx.getLocalName())) + { + ctx = ctx.getFirstChild(); + return (ctx == null) ? null : parse(ctx); + } + } + // Otherwise pass over extension element return null; } switch (node.getNodeType()) { case Node.TEXT_NODE: + case Node.CDATA_SECTION_NODE: // Determine whether to strip whitespace Text text = (Text) node; - if (!isPreserved(text)) + if (!isPreserved(text, false)) { // Strip - /*String data = text.getData().trim(); - if (data.length() > 0) - { - text.setData(data); - } // else */ text.getParentNode().removeChild(text); return null; } @@ -1623,9 +1567,7 @@ class Stylesheet String aname = attr.getNodeName(); if (Stylesheet.XSL_NS.equals(ans) && "use-attribute-sets".equals(attr.getLocalName())) - { - continue; - } + continue; String value = attr.getNodeValue(); TemplateNode grandchild = parseAttributeValueTemplate(value, node); @@ -1640,8 +1582,9 @@ class Stylesheet } String ename = node.getNodeName(); TemplateNode n = parseAttributeValueTemplate(ename, node); - TemplateNode ns = (namespaceUri == null) ? null : - parseAttributeValueTemplate(namespaceUri, node); + //TemplateNode ns = (namespaceUri == null) ? null : + // parseAttributeValueTemplate(namespaceUri, node); + TemplateNode ns = null; ElementNode ret = new ElementNode(n, ns, useAttributeSets, node); ret.children = child; @@ -1676,9 +1619,7 @@ class Stylesheet NamedNodeMap attrs = node.getAttributes(); String s = getAttribute(attrs, "select"); if (s == null) - { - s = "."; - } + s = "."; Expr select = (Expr) xpath.compile(s); String l = getAttribute(attrs, "lang"); TemplateNode lang = (l == null) ? null : @@ -1728,9 +1669,7 @@ class Stylesheet ret.add(new WithParam(name, expr)); } else - { - ret.add(new WithParam(name, content)); - } + ret.add(new WithParam(name, content)); } node = node.getNextSibling(); } @@ -1757,27 +1696,19 @@ class Stylesheet { String prefix = attr.getLocalName(); if (XMLConstants.XMLNS_ATTRIBUTE.equals(prefix)) - { - prefix = "#default"; - } + prefix = "#default"; String ns = attr.getNodeValue(); // Should the namespace be excluded? if (XSL_NS.equals(ns) || extensionElementPrefixes.contains(prefix) || elementExcludeResultPrefixes.contains(prefix) || excludeResultPrefixes.contains(prefix)) - { - continue; - } + continue; // Is the namespace already defined on the target? if (prefix == "#default") - { - prefix = null; - } + prefix = null; if (target.lookupNamespaceURI(prefix) != null) - { - continue; - } + continue; attr = attr.cloneNode(true); attr = doc.adoptNode(attr); target.getAttributes().setNamedItemNS(attr); @@ -1786,23 +1717,17 @@ class Stylesheet } Node parent = source.getParentNode(); if (parent != null) - { - addNamespaceNodes(parent, target, doc, elementExcludeResultPrefixes); - } + addNamespaceNodes(parent, target, doc, elementExcludeResultPrefixes); } static final String getAttribute(NamedNodeMap attrs, String name) { Node attr = attrs.getNamedItem(name); if (attr == null) - { - return null; - } + return null; String ret = attr.getNodeValue(); if (ret.length() == 0) - { - return null; - } + return null; return ret; } diff --git a/libjava/classpath/gnu/xml/transform/TransformerFactoryImpl.java b/libjava/classpath/gnu/xml/transform/TransformerFactoryImpl.java index dde2017ff6b..16e3363f8c6 100644 --- a/libjava/classpath/gnu/xml/transform/TransformerFactoryImpl.java +++ b/libjava/classpath/gnu/xml/transform/TransformerFactoryImpl.java @@ -1,5 +1,5 @@ /* TransformerFactoryImpl.java -- - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004,2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -37,7 +37,11 @@ exception statement from your version. */ package gnu.xml.transform; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.InputStream; import java.io.IOException; +import java.io.OutputStream; import java.net.URL; import java.util.Iterator; import java.util.LinkedHashMap; @@ -73,7 +77,7 @@ public class TransformerFactoryImpl { final XPathFactory xpathFactory; - final XSLURIResolver resolver; + final XSLURIResolver resolver; ErrorListener userListener; URIResolver userResolver; @@ -341,5 +345,46 @@ public class TransformerFactoryImpl { return userListener; } + + /** + * Syntax: TransformerFactoryImpl [<stylesheet> [<input> [<output>]]] + */ + public static void main(String[] args) + throws Exception + { + InputStream stylesheet = null, in = null; + OutputStream out = null; + try + { + if (args.length > 0) + { + stylesheet = new FileInputStream(args[0]); + if (args.length > 1) + { + in = new FileInputStream(args[1]); + if (args.length > 2) + out = new FileOutputStream(args[2]); + } + } + if (in == null) + in = System.in; + if (out == null) + out = System.out; + TransformerFactory f = new TransformerFactoryImpl(); + Transformer t = (stylesheet != null) ? + f.newTransformer(new StreamSource(stylesheet)) : + f.newTransformer(); + t.transform(new StreamSource(in), new StreamResult(out)); + } + finally + { + if (stylesheet != null) + stylesheet.close(); + if (in != null && in instanceof FileInputStream) + in.close(); + if (out != null && out instanceof FileOutputStream) + out.close(); + } + } } diff --git a/libjava/classpath/gnu/xml/transform/TransformerImpl.java b/libjava/classpath/gnu/xml/transform/TransformerImpl.java index cf404884736..b7ff668843b 100644 --- a/libjava/classpath/gnu/xml/transform/TransformerImpl.java +++ b/libjava/classpath/gnu/xml/transform/TransformerImpl.java @@ -1,5 +1,5 @@ /* TransformerImpl.java -- - Copyright (C) 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2004,2005,2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -128,8 +128,6 @@ class TransformerImpl { // Suppress mutation events ((DomDocument) doc).setBuilding(true); - // TODO find a better/more generic way of doing this than - // casting } // Get the result tree Node parent = null, nextSibling = null; @@ -147,8 +145,6 @@ class TransformerImpl DomDocument drdoc = (DomDocument) rdoc; drdoc.setBuilding(true); drdoc.setCheckWellformedness(false); - // TODO find a better/more generic way of doing this than - // casting } } boolean created = false; @@ -184,9 +180,7 @@ class TransformerImpl { // Done transforming, reset document if (doc instanceof DomDocument) - { - ((DomDocument) doc).setBuilding(false); - } + ((DomDocument) doc).setBuilding(false); throw e; } } @@ -214,17 +208,11 @@ class TransformerImpl } Document sourceDoc = context.getOwnerDocument(); if (sourceDoc != resultDoc) - { - clone = resultDoc.adoptNode(clone); - } + clone = resultDoc.adoptNode(clone); if (nextSibling != null) - { - parent.insertBefore(clone, nextSibling); - } + parent.insertBefore(clone, nextSibling); else - { - parent.appendChild(clone); - } + parent.appendChild(clone); } else { @@ -256,15 +244,18 @@ class TransformerImpl DomDocument resultDoc = (DomDocument) parent; Node root = resultDoc.getDocumentElement(); // Add doctype if specified - if ((publicId != null || systemId != null) && - root != null) + if (publicId != null || systemId != null) { - // We must know the name of the root element to - // create the document type - resultDoc.appendChild(new DomDoctype(resultDoc, - root.getNodeName(), - publicId, - systemId)); + if (root != null) + { + // We must know the name of the root element to + // create the document type + DocumentType doctype = new DomDoctype(resultDoc, + root.getNodeName(), + publicId, + systemId); + resultDoc.insertBefore(doctype, root); + } } resultDoc.setBuilding(false); resultDoc.setCheckWellformedness(true); @@ -279,43 +270,25 @@ class TransformerImpl (Document) parent : parent.getOwnerDocument(); DOMImplementation impl = resultDoc.getImplementation(); - DocumentType doctype = - impl.createDocumentType(resultDoc.getNodeName(), - publicId, - systemId); - // Try to insert doctype before first element - Node ctx = parent.getFirstChild(); - for (; ctx != null && - ctx.getNodeType() != Node.ELEMENT_NODE; - ctx = ctx.getNextSibling()) + Node root = resultDoc.getDocumentElement(); + if (root != null) { - } - if (ctx != null) - { - parent.insertBefore(doctype, ctx); - } - else - { - parent.appendChild(doctype); + DocumentType doctype = + impl.createDocumentType(root.getNodeName(), + publicId, + systemId); + resultDoc.insertBefore(doctype, root); } } } if (version != null) - { - parent.setUserData("version", version, stylesheet); - } + parent.setUserData("version", version, stylesheet); if (omitXmlDeclaration) - { - parent.setUserData("omit-xml-declaration", "yes", stylesheet); - } + parent.setUserData("omit-xml-declaration", "yes", stylesheet); if (standalone) - { - parent.setUserData("standalone", "yes", stylesheet); - } + parent.setUserData("standalone", "yes", stylesheet); if (mediaType != null) - { - parent.setUserData("media-type", mediaType, stylesheet); - } + parent.setUserData("media-type", mediaType, stylesheet); if (cdataSectionElements != null) { List list = new LinkedList(); @@ -390,13 +363,9 @@ class TransformerImpl if (ex != null) { if (errorListener != null) - { - errorListener.error(new TransformerException(ex)); - } + errorListener.error(new TransformerException(ex)); else - { - ex.printStackTrace(System.err); - } + ex.printStackTrace(System.err); } } else if (outputTarget instanceof SAXResult) @@ -407,22 +376,16 @@ class TransformerImpl ContentHandler ch = sr.getHandler(); LexicalHandler lh = sr.getLexicalHandler(); if (lh == null && ch instanceof LexicalHandler) - { - lh = (LexicalHandler) ch; - } + lh = (LexicalHandler) ch; SAXSerializer serializer = new SAXSerializer(); serializer.serialize(parent, ch, lh); } catch (SAXException e) { if (errorListener != null) - { - errorListener.error(new TransformerException(e)); - } + errorListener.error(new TransformerException(e)); else - { - e.printStackTrace(System.err); - } + e.printStackTrace(System.err); } } } @@ -430,7 +393,7 @@ class TransformerImpl /** * Strip whitespace from the source tree. */ - void strip(Node node) + boolean strip(Node node) throws TransformerConfigurationException { short nt = node.getNodeType(); @@ -438,44 +401,101 @@ class TransformerImpl { // Replace entity reference with its content Node parent = node.getParentNode(); + Node nextSibling = node.getNextSibling(); Node child = node.getFirstChild(); - if (child != null) - { - strip(child); - } while (child != null) { Node next = child.getNextSibling(); node.removeChild(child); - parent.insertBefore(child, node); + if (nextSibling != null) + parent.insertBefore(child, nextSibling); + else + parent.appendChild(child); child = next; } - parent.removeChild(node); + return true; } if (nt == Node.TEXT_NODE || nt == Node.CDATA_SECTION_NODE) { - if (!stylesheet.isPreserved((Text) node)) + // Denormalize text into whitespace and non-whitespace nodes + String text = node.getNodeValue(); + String[] tokens = tokenizeWhitespace(text); + if (tokens.length > 1) { - node.getParentNode().removeChild(node); - } - else - { - String text = node.getNodeValue(); - String stripped = text.trim(); - if (!text.equals(stripped)) + node.setNodeValue(tokens[0]); + Node parent = node.getParentNode(); + Node nextSibling = node.getNextSibling(); + Document doc = node.getOwnerDocument(); + for (int i = 1; i < tokens.length; i++) { - node.setNodeValue(stripped); + Node newChild = (nt == Node.CDATA_SECTION_NODE) ? + doc.createCDATASection(tokens[i]) : + doc.createTextNode(tokens[i]); + if (nextSibling != null) + parent.insertBefore(newChild, nextSibling); + else + parent.appendChild(newChild); } } + return !stylesheet.isPreserved((Text) node, true); } else { - for (Node child = node.getFirstChild(); child != null; - child = child.getNextSibling()) + Node child = node.getFirstChild(); + while (child != null) { - strip(child); + boolean remove = strip(child); + Node next = child.getNextSibling(); + if (remove) + node.removeChild(child); + child = next; } } + return false; + } + + /** + * Tokenize the specified text into contiguous whitespace-only and + * non-whitespace chunks. + */ + private static String[] tokenizeWhitespace(String text) + { + int len = text.length(); + int start = 0, end = len - 1; + // Find index of text start + for (int i = 0; i < len; i++) + { + char c = text.charAt(i); + boolean whitespace = (c == ' ' || c == '\n' || c == '\t' || c == '\r'); + if (whitespace) + start++; + else + break; + } + if (start == end) // all whitespace + return new String[] { text }; + // Find index of text end + for (int i = end; i > start; i--) + { + char c = text.charAt(i); + boolean whitespace = (c == ' ' || c == '\n' || c == '\t' || c == '\r'); + if (whitespace) + end--; + else + break; + } + if (start == 0 && end == len - 1) // all non-whitespace + return new String[] { text }; + // whitespace, then text, then whitespace + String[] ret = (start > 0 && end < len - 1) ? + new String[3] : new String[2]; + int i = 0; + if (start > 0) + ret[i++] = text.substring(0, start); + ret[i++] = text.substring(start, end + 1); + if (end < len - 1) + ret[i++] = text.substring(end + 1); + return ret; } /** @@ -487,6 +507,7 @@ class TransformerImpl throws IOException { OutputStream out = null; + boolean created = false; try { out = sr.getOutputStream(); @@ -494,9 +515,7 @@ class TransformerImpl { Writer writer = sr.getWriter(); if (writer != null) - { - out = new WriterOutputStream(writer); - } + out = new WriterOutputStream(writer); } if (out == null) { @@ -523,6 +542,7 @@ class TransformerImpl URL url = new URL(systemId); out = new FileOutputStream(url.getPath()); } + created = true; } out = new BufferedOutputStream(out); StreamSerializer serializer = @@ -539,10 +559,8 @@ class TransformerImpl { try { - if (out != null) - { - out.close(); - } + if (out != null && created) + out.close(); } catch (IOException e) { @@ -564,17 +582,13 @@ class TransformerImpl public void setParameter(String name, Object value) { if (stylesheet != null) - { - stylesheet.bindings.set(new QName(null, name), value, Bindings.PARAM); - } + stylesheet.bindings.set(new QName(null, name), value, Bindings.PARAM); } public Object getParameter(String name) { if (stylesheet != null) - { - return stylesheet.bindings.get(new QName(null, name), null, 1, 1); - } + return stylesheet.bindings.get(new QName(null, name), null, 1, 1); return null; } @@ -601,13 +615,9 @@ class TransformerImpl throws IllegalArgumentException { if (oformat == null) - { - outputProperties.clear(); - } + outputProperties.clear(); else - { - outputProperties.putAll(oformat); - } + outputProperties.putAll(oformat); } public Properties getOutputProperties() @@ -689,9 +699,7 @@ class TransformerImpl StringBuffer buf = new StringBuffer(); buf.append('\n'); for (int i = 0; i < offset + 1; i++) - { - buf.append(INDENT_WHITESPACE); - } + buf.append(INDENT_WHITESPACE); String ws = buf.toString(); for (Iterator i = children.iterator(); i.hasNext(); ) { @@ -703,9 +711,7 @@ class TransformerImpl buf.append('\n'); ws = buf.toString(); for (int i = 0; i < offset; i++) - { - buf.append(INDENT_WHITESPACE); - } + buf.append(INDENT_WHITESPACE); node.appendChild(doc.createTextNode(ws)); } } @@ -749,9 +755,7 @@ class TransformerImpl while (ctx != null) { if (ctx.hasChildNodes()) - { - convertCdataSectionElements(doc, ctx, list); - } + convertCdataSectionElements(doc, ctx, list); ctx = ctx.getNextSibling(); } } @@ -761,9 +765,7 @@ class TransformerImpl String ln1 = qname.getLocalPart(); String ln2 = node.getLocalName(); if (ln2 == null) - { - return ln1.equals(node.getNodeName()); - } + return ln1.equals(node.getNodeName()); else { String uri1 = qname.getNamespaceURI(); diff --git a/libjava/classpath/gnu/xml/transform/ValueOfNode.java b/libjava/classpath/gnu/xml/transform/ValueOfNode.java index 430598a94b3..24c229ea3b3 100644 --- a/libjava/classpath/gnu/xml/transform/ValueOfNode.java +++ b/libjava/classpath/gnu/xml/transform/ValueOfNode.java @@ -1,5 +1,5 @@ /* ValueOfNode.java -- - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004,2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -69,26 +69,18 @@ final class ValueOfNode TemplateNode ret = new ValueOfNode(select.clone(stylesheet), disableOutputEscaping); if (children != null) - { - ret.children = children.clone(stylesheet); - } + ret.children = children.clone(stylesheet); if (next != null) - { - ret.next = next.clone(stylesheet); - } + ret.next = next.clone(stylesheet); return ret; } void doApply(Stylesheet stylesheet, QName mode, - Node context, int pos, int len, - Node parent, Node nextSibling) + Node context, int pos, int len, + Node parent, Node nextSibling) throws TransformerException { Object ret = select.evaluate(context, pos, len); - /*if (stylesheet.debug) - { - System.err.println("value-of: " + select + " -> " + ret); - }*/ String value; if (ret instanceof Collection) { @@ -100,47 +92,35 @@ final class ValueOfNode } value = buf.toString(); } + else if (ret == null) + value = ""; else - { - value = Expr._string(context, ret); - } + value = Expr._string(context, ret); if (stylesheet.debug) - { - System.err.println("value-of: "+context+" "+ select + " -> "+ value); - } + System.err.println("value-of: "+context+" "+ select + " -> "+ value); if (value != null && value.length() > 0) { Document doc = (parent instanceof Document) ? (Document) parent : parent.getOwnerDocument(); Text textNode = doc.createTextNode(value); if (disableOutputEscaping) - { - textNode.setUserData("disable-output-escaping", "yes", stylesheet); - } + textNode.setUserData("disable-output-escaping", "yes", stylesheet); if (nextSibling != null) - { - parent.insertBefore(textNode, nextSibling); - } + parent.insertBefore(textNode, nextSibling); else - { - parent.appendChild(textNode); - } + parent.appendChild(textNode); } // value-of doesn't process children if (next != null) - { - next.apply(stylesheet, mode, - context, pos, len, - parent, nextSibling); - } + next.apply(stylesheet, mode, + context, pos, len, + parent, nextSibling); } public boolean references(QName var) { if (select != null && select.references(var)) - { - return true; - } + return true; return super.references(var); } @@ -151,9 +131,7 @@ final class ValueOfNode buf.append("select="); buf.append(select); if (disableOutputEscaping) - { - buf.append(",disableOutputEscaping"); - } + buf.append(",disableOutputEscaping"); buf.append(']'); return buf.toString(); } |