summaryrefslogtreecommitdiff
path: root/libjava/gnu/xml/transform/Stylesheet.java
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/gnu/xml/transform/Stylesheet.java')
-rw-r--r--libjava/gnu/xml/transform/Stylesheet.java1728
1 files changed, 0 insertions, 1728 deletions
diff --git a/libjava/gnu/xml/transform/Stylesheet.java b/libjava/gnu/xml/transform/Stylesheet.java
deleted file mode 100644
index 5efd5ca3e3e..00000000000
--- a/libjava/gnu/xml/transform/Stylesheet.java
+++ /dev/null
@@ -1,1728 +0,0 @@
-/* Stylesheet.java --
- Copyright (C) 2004 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.text.DecimalFormat;
-import java.text.DecimalFormatSymbols;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.LinkedHashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.StringTokenizer;
-import java.util.TreeSet;
-import javax.xml.XMLConstants;
-import javax.xml.namespace.NamespaceContext;
-import javax.xml.namespace.QName;
-import javax.xml.transform.Source;
-import javax.xml.transform.TransformerConfigurationException;
-import javax.xml.transform.TransformerException;
-import javax.xml.xpath.XPathFunction;
-import javax.xml.xpath.XPathFunctionResolver;
-import javax.xml.xpath.XPathExpressionException;
-import org.w3c.dom.Attr;
-import org.w3c.dom.Document;
-import org.w3c.dom.DOMException;
-import org.w3c.dom.Element;
-import org.w3c.dom.NamedNodeMap;
-import org.w3c.dom.Node;
-import org.w3c.dom.Text;
-import org.w3c.dom.UserDataHandler;
-import gnu.xml.xpath.Expr;
-import gnu.xml.xpath.NameTest;
-import gnu.xml.xpath.NodeTypeTest;
-import gnu.xml.xpath.Pattern;
-import gnu.xml.xpath.Selector;
-import gnu.xml.xpath.Root;
-import gnu.xml.xpath.Test;
-import gnu.xml.xpath.XPathImpl;
-
-/**
- * An XSL stylesheet.
- *
- * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
- */
-class Stylesheet
- implements NamespaceContext, XPathFunctionResolver, UserDataHandler, Cloneable
-{
-
- static final String XSL_NS = "http://www.w3.org/1999/XSL/Transform";
-
- static final int OUTPUT_XML = 0;
- static final int OUTPUT_HTML = 1;
- static final int OUTPUT_TEXT = 2;
-
- final TransformerFactoryImpl factory;
- TransformerImpl transformer;
- Stylesheet parent;
- final XPathImpl xpath;
- final String systemId;
- final int precedence;
-
- final boolean debug;
-
- /**
- * Version of XSLT.
- */
- String version;
-
- Collection extensionElementPrefixes;
- Collection excludeResultPrefixes;
-
- /**
- * Set of element names for which we should strip whitespace.
- */
- Set stripSpace;
-
- /**
- * Set of element names for which we should preserve whitespace.
- */
- Set preserveSpace;
-
- /**
- * Output options.
- */
- int outputMethod;
- String outputVersion;
- String outputEncoding;
- boolean outputOmitXmlDeclaration;
- boolean outputStandalone;
- String outputPublicId;
- String outputSystemId;
- Collection outputCdataSectionElements;
- boolean outputIndent;
- String outputMediaType;
-
- /**
- * Keys.
- */
- Collection keys;
-
- /**
- * Decimal formats.
- */
- Map decimalFormats;
-
- /**
- * Namespace aliases.
- */
- Map namespaceAliases;
-
- /**
- * Attribute-sets.
- */
- List attributeSets;
-
- /**
- * Variables.
- */
- List variables;
-
- /**
- * Variable and parameter bindings.
- */
- Bindings bindings;
-
- /**
- * Templates.
- */
- LinkedList templates;
-
- TemplateNode builtInNodeTemplate;
- TemplateNode builtInTextTemplate;
-
- /**
- * Holds the current node while parsing.
- * Necessary to associate the document function with its declaring node,
- * to resolve namespaces, and to maintain the current node for the
- * current() function.
- */
- Node current;
-
- /**
- * Set by a terminating message.
- */
- transient boolean terminated;
-
- /**
- * Current template in force.
- */
- transient Template currentTemplate;
-
- Stylesheet(TransformerFactoryImpl factory,
- Stylesheet parent,
- Document doc,
- String systemId,
- int precedence)
- throws TransformerConfigurationException
- {
- this.factory = factory;
- this.systemId = systemId;
- this.precedence = precedence;
- this.parent = parent;
- extensionElementPrefixes = new HashSet();
- excludeResultPrefixes = new HashSet();
- stripSpace = new LinkedHashSet();
- preserveSpace = new LinkedHashSet();
- outputCdataSectionElements = new LinkedHashSet();
- xpath = (XPathImpl) factory.xpathFactory.newXPath();
- if (parent == null)
- {
- bindings = new Bindings(this);
- attributeSets = new LinkedList();
- variables = new LinkedList();
- namespaceAliases = new LinkedHashMap();
- templates = new LinkedList();
- keys = new LinkedList();
- decimalFormats = new LinkedHashMap();
- initDefaultDecimalFormat();
- xpath.setNamespaceContext(this);
- xpath.setXPathFunctionResolver(this);
- }
- else
- {
- /* Test for import circularity */
- for (Stylesheet ctx = this; ctx.parent != null; ctx = ctx.parent)
- {
- if (systemId != null && systemId.equals(ctx.parent.systemId))
- {
- String msg = "circularity importing " + systemId;
- throw new TransformerConfigurationException(msg);
- }
- }
- /* OK */
- Stylesheet root = getRootStylesheet();
- bindings = root.bindings;
- attributeSets = root.attributeSets;
- variables = root.variables;
- namespaceAliases = root.namespaceAliases;
- templates = root.templates;
- keys = root.keys;
- decimalFormats = root.decimalFormats;
- xpath.setNamespaceContext(root);
- xpath.setXPathFunctionResolver(root);
- }
- xpath.setXPathVariableResolver(bindings);
-
- Test anyNode = new NodeTypeTest((short) 0);
- List tests = Collections.singletonList(anyNode);
- builtInNodeTemplate =
- new ApplyTemplatesNode(null, null,
- new Selector(Selector.CHILD, tests),
- null, null, null, true);
- builtInTextTemplate =
- new ValueOfNode(null, null,
- new Selector(Selector.SELF, tests),
- false);
-
- parse(doc.getDocumentElement(), true);
- current = doc; // Alow namespace resolution during processing
-
- debug = ("yes".equals(System.getProperty("xsl.debug")));
-
- if (debug)
- {
- System.err.println("Stylesheet: " + doc.getDocumentURI());
- for (Iterator i = templates.iterator(); i.hasNext(); )
- {
- Template t = (Template) i.next();
- t.list(System.err);
- System.err.println("--------------------");
- }
- }
- }
-
- Stylesheet getRootStylesheet()
- {
- Stylesheet stylesheet = this;
- while (stylesheet.parent != null)
- {
- stylesheet = stylesheet.parent;
- }
- return stylesheet;
- }
-
- void initDefaultDecimalFormat()
- {
- DecimalFormat defaultDecimalFormat = new DecimalFormat();
- DecimalFormatSymbols symbols = new DecimalFormatSymbols();
- symbols.setDecimalSeparator('.');
- symbols.setGroupingSeparator(',');
- symbols.setPercent('%');
- symbols.setPerMill('\u2030');
- symbols.setZeroDigit('0');
- symbols.setDigit('#');
- symbols.setPatternSeparator(';');
- symbols.setInfinity("Infinity");
- symbols.setNaN("NaN");
- symbols.setMinusSign('-');
- defaultDecimalFormat.setDecimalFormatSymbols(symbols);
- decimalFormats.put(null, defaultDecimalFormat);
- }
-
- // -- Cloneable --
-
- public Object clone()
- {
- try
- {
- Stylesheet clone = (Stylesheet) super.clone();
- clone.bindings = (Bindings) bindings.clone();
-
- LinkedList templates2 = new LinkedList();
- for (Iterator i = templates.iterator(); i.hasNext(); )
- {
- Template t = (Template) i.next();
- templates2.add(t.clone(clone));
- }
- clone.templates = templates2;
-
- LinkedList attributeSets2 = new LinkedList();
- for (Iterator i = attributeSets.iterator(); i.hasNext(); )
- {
- AttributeSet as = (AttributeSet) i.next();
- attributeSets2.add(as.clone(clone));
- }
- clone.attributeSets = attributeSets2;
-
- LinkedList variables2 = new LinkedList();
- for (Iterator i = variables.iterator(); i.hasNext(); )
- {
- ParameterNode var = (ParameterNode) i.next();
- variables2.add(var.clone(clone));
- }
- clone.variables = variables2;
-
- LinkedList keys2 = new LinkedList();
- for (Iterator i = keys.iterator(); i.hasNext(); )
- {
- Key k = (Key) i.next();
- keys2.add(k.clone(clone));
- }
- clone.keys = keys2;
-
- return clone;
- }
- catch (CloneNotSupportedException e)
- {
- throw new Error(e.getMessage());
- }
- }
-
- // -- Variable evaluation --
-
- void initTopLevelVariables(Node context)
- throws TransformerException
- {
- for (Iterator i = variables.iterator(); i.hasNext(); )
- {
- ParameterNode var = (ParameterNode) i.next();
- bindings.set(var.name,
- var.getValue(this, null, context, 1, 1),
- var.global);
- }
- }
-
- // -- NamespaceContext --
-
- public String getNamespaceURI(String prefix)
- {
- return (current == null) ? null : current.lookupNamespaceURI(prefix);
- }
-
- public String getPrefix(String namespaceURI)
- {
- return (current == null) ? null : current.lookupPrefix(namespaceURI);
- }
-
- public Iterator getPrefixes(String namespaceURI)
- {
- // TODO
- return Collections.singleton(getPrefix(namespaceURI)).iterator();
- }
-
- // -- Template selection --
-
- TemplateNode getTemplate(QName mode, Node context, boolean applyImports)
- throws TransformerException
- {
- //System.err.println("getTemplate: mode="+mode+" context="+context);
- Set candidates = new TreeSet();
- for (Iterator j = templates.iterator(); j.hasNext(); )
- {
- Template t = (Template) j.next();
- boolean isMatch = t.matches(mode, context);
- if (applyImports)
- {
- if (currentTemplate == null)
- {
- String msg = "current template may not be null " +
- "during apply-imports";
- throw new TransformerException(msg);
- }
- if (!currentTemplate.imports(t))
- {
- isMatch = false;
- }
- }
- //System.err.println("\t"+context+" "+t+"="+isMatch);
- if (isMatch)
- {
- candidates.add(t);
- }
- }
- //System.err.println("\tcandidates="+candidates);
- if (candidates.isEmpty())
- {
- // Apply built-in template
- // Current template is unchanged
- //System.err.println("\tbuiltInTemplate context="+context);
- switch (context.getNodeType())
- {
- case Node.ELEMENT_NODE:
- case Node.DOCUMENT_NODE:
- case Node.DOCUMENT_FRAGMENT_NODE:
- case Node.PROCESSING_INSTRUCTION_NODE:
- case Node.COMMENT_NODE:
- return builtInNodeTemplate;
- case Node.TEXT_NODE:
- case Node.ATTRIBUTE_NODE:
- return builtInTextTemplate;
- default:
- return null;
- }
- }
- else
- {
- Template t = (Template) candidates.iterator().next();
- // Set current template
- currentTemplate = t;
- //System.err.println("\ttemplate="+t+" context="+context);
- return t.node;
- }
- }
-
- 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);
- }
- }
- if (candidates.isEmpty())
- {
- return null;
- //throw new TransformerException("template '" + name + "' not found");
- }
- Template t = (Template) candidates.iterator().next();
- //System.err.println("\ttemplate="+t+" context="+context);
- return t.node;
- }
-
- /**
- * template
- */
- final Template parseTemplate(Node node, NamedNodeMap attrs)
- throws TransformerConfigurationException, XPathExpressionException
- {
- String n = getAttribute(attrs, "name");
- QName name = (n == null) ? null : getQName(n);
- String m = getAttribute(attrs, "match");
- Pattern match = null;
- if (m != null)
- {
- try
- {
- match = (Pattern) xpath.compile(m);
- }
- catch (ClassCastException e)
- {
- String msg = "illegal pattern: " + m;
- throw new TransformerConfigurationException(msg);
- }
- }
- String p = getAttribute(attrs, "priority");
- String mm = getAttribute(attrs, "mode");
- QName mode = (mm == null) ? null : getQName(mm);
- double priority = (p == null) ? Template.DEFAULT_PRIORITY :
- Double.parseDouble(p);
- return new Template(this, name, match, parse(node.getFirstChild()),
- precedence, priority, mode);
- }
-
- /**
- * output
- */
- final void parseOutput(Node node, NamedNodeMap attrs)
- throws TransformerConfigurationException
- {
- String method = getAttribute(attrs, "method");
- if ("xml".equals(method) || method == null)
- {
- outputMethod = OUTPUT_XML;
- }
- else if ("html".equals(method))
- {
- outputMethod = OUTPUT_HTML;
- }
- else if ("text".equals(method))
- {
- 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");
- outputEncoding = getAttribute(attrs, "encoding");
- String indent = getAttribute(attrs, "indent");
- if (indent != null)
- {
- outputIndent = "yes".equals(indent);
- }
- outputVersion = getAttribute(attrs, "version");
- String omitXmlDecl = getAttribute(attrs, "omit-xml-declaration");
- if (omitXmlDecl != null)
- {
- outputOmitXmlDeclaration = "yes".equals(omitXmlDecl);
- }
- String standalone = getAttribute(attrs, "standalone");
- if (standalone != null)
- {
- outputStandalone = "yes".equals(standalone);
- }
- outputMediaType = getAttribute(attrs, "media-type");
- String cdataSectionElements =
- getAttribute(attrs, "cdata-section-elements");
- if (cdataSectionElements != null)
- {
- StringTokenizer st = new StringTokenizer(cdataSectionElements, " ");
- while (st.hasMoreTokens())
- {
- outputCdataSectionElements.add(st.nextToken());
- }
- }
- }
-
- /**
- * key
- */
- final void parseKey(Node node, NamedNodeMap attrs)
- throws TransformerConfigurationException, XPathExpressionException
- {
- String n = getRequiredAttribute(attrs, "name", node);
- String m = getRequiredAttribute(attrs, "match", node);
- String u = getRequiredAttribute(attrs, "use", node);
- QName name = getQName(n);
- Expr use = (Expr) xpath.compile(u);
- try
- {
- Pattern match = (Pattern) xpath.compile(m);
- Key key = new Key(name, match, use);
- keys.add(key);
- }
- catch (ClassCastException e)
- {
- throw new TransformerConfigurationException("invalid pattern: " + m);
- }
- }
-
- /**
- * decimal-format
- */
- final void parseDecimalFormat(Node node, NamedNodeMap attrs)
- throws TransformerConfigurationException
- {
- String dfName = getAttribute(attrs, "name");
- DecimalFormat df = new DecimalFormat();
- DecimalFormatSymbols symbols = new DecimalFormatSymbols();
- symbols.setDecimalSeparator(parseDFChar(attrs, "decimal-separator", '.'));
- symbols.setGroupingSeparator(parseDFChar(attrs, "grouping-separator", ','));
- symbols.setInfinity(parseDFString(attrs, "infinity", "Infinity"));
- symbols.setMinusSign(parseDFChar(attrs, "minus-sign", '-'));
- symbols.setNaN(parseDFString(attrs, "NaN", "NaN"));
- symbols.setPercent(parseDFChar(attrs, "percent", '%'));
- symbols.setPerMill(parseDFChar(attrs, "per-mille", '\u2030'));
- symbols.setZeroDigit(parseDFChar(attrs, "zero-digit", '0'));
- symbols.setDigit(parseDFChar(attrs, "digit", '#'));
- symbols.setPatternSeparator(parseDFChar(attrs, "pattern-separator", ';'));
- df.setDecimalFormatSymbols(symbols);
- decimalFormats.put(dfName, df);
- }
-
- private final char parseDFChar(NamedNodeMap attrs, String name, char def)
- throws TransformerConfigurationException
- {
- Node attr = attrs.getNamedItem(name);
- try
- {
- return (attr == null) ? def : attr.getNodeValue().charAt(0);
- }
- catch (StringIndexOutOfBoundsException e)
- {
- throw new TransformerConfigurationException("empty attribute '" +
- name +
- "' in decimal-format", e);
- }
- }
-
- private final String parseDFString(NamedNodeMap attrs, String name,
- String def)
- {
- Node attr = attrs.getNamedItem(name);
- return (attr == null) ? def : attr.getNodeValue();
- }
-
- /**
- * namespace-alias
- */
- final void parseNamespaceAlias(Node node, NamedNodeMap attrs)
- throws TransformerConfigurationException
- {
- String sp = getRequiredAttribute(attrs, "stylesheet-prefix", node);
- String rp = getRequiredAttribute(attrs, "result-prefix", node);
- namespaceAliases.put(sp, rp);
- }
-
- /**
- * attribute-set
- */
- final void parseAttributeSet(Node node, NamedNodeMap attrs)
- throws TransformerConfigurationException, XPathExpressionException
- {
- TemplateNode children = parse(node.getFirstChild());
- String name = getRequiredAttribute(attrs, "name", node);
- String uas = getAttribute(attrs, "use-attribute-sets");
- attributeSets.add(new AttributeSet(children, name, uas));
- }
-
- /**
- * Parse top-level elements.
- */
- void parse(Node node, boolean root)
- throws TransformerConfigurationException
- {
- if (node == null)
- {
- return;
- }
- current = node;
- try
- {
- String namespaceUri = node.getNamespaceURI();
- if (XSL_NS.equals(namespaceUri) &&
- node.getNodeType() == Node.ELEMENT_NODE)
- {
- String name = node.getLocalName();
- NamedNodeMap attrs = node.getAttributes();
- if ("stylesheet".equals(name))
- {
- version = getAttribute(attrs, "version");
- String eep = getAttribute(attrs, "extension-element-prefixes");
- if (eep != null)
- {
- StringTokenizer st = new StringTokenizer(eep);
- while (st.hasMoreTokens())
- {
- extensionElementPrefixes.add(st.nextToken());
- }
- }
- String erp = getAttribute(attrs, "exclude-result-prefixes");
- if (erp != null)
- {
- StringTokenizer st = new StringTokenizer(erp);
- while (st.hasMoreTokens())
- {
- excludeResultPrefixes.add(st.nextToken());
- }
- }
- parse(node.getFirstChild(), false);
- return;
- }
- else if ("template".equals(name))
- {
- templates.addFirst(parseTemplate(node, attrs));
- }
- else if ("param".equals(name) ||
- "variable".equals(name))
- {
- boolean global = "variable".equals(name);
- TemplateNode content = parse(node.getFirstChild());
- String paramName = getRequiredAttribute(attrs, "name", node);
- String select = getAttribute(attrs, "select");
- if (select != null && select.length() > 0)
- {
- if (content != null)
- {
- String msg = "parameter '" + paramName +
- "' has both select and content";
- DOMSourceLocator l = new DOMSourceLocator(node);
- throw new TransformerConfigurationException(msg, l);
- }
- Expr expr = (Expr) xpath.compile(select);
- variables.add(new ParameterNode(null, null,
- paramName,
- expr, global));
- }
- else
- {
- variables.add(new ParameterNode(content, null,
- paramName,
- null, global));
- }
- bindings.set(paramName, content, global);
- }
- else if ("include".equals(name) || "import".equals(name))
- {
- int delta = "import".equals(name) ? -1 : 0;
- String href = getRequiredAttribute(attrs, "href", node);
- Source source;
- synchronized (factory.resolver)
- {
- if (transformer != null)
- {
- factory.resolver
- .setUserResolver(transformer.getURIResolver());
- factory.resolver
- .setUserListener(transformer.getErrorListener());
- }
- source = factory.resolver.resolve(systemId, href);
- }
- factory.newStylesheet(source, precedence + delta, this);
- }
- else if ("output".equals(name))
- {
- parseOutput(node, attrs);
- }
- else if ("preserve-space".equals(name))
- {
- String elements =
- getRequiredAttribute(attrs, "elements", node);
- StringTokenizer st = new StringTokenizer(elements,
- " \t\n\r");
- while (st.hasMoreTokens())
- {
- preserveSpace.add(parseNameTest(st.nextToken()));
- }
- }
- else if ("strip-space".equals(name))
- {
- String elements =
- getRequiredAttribute(attrs, "elements", node);
- StringTokenizer st = new StringTokenizer(elements,
- " \t\n\r");
- while (st.hasMoreTokens())
- {
- stripSpace.add(parseNameTest(st.nextToken()));
- }
- }
- else if ("key".equals(name))
- {
- parseKey(node, attrs);
- }
- else if ("decimal-format".equals(name))
- {
- parseDecimalFormat(node, attrs);
- }
- else if ("namespace-alias".equals(name))
- {
- parseNamespaceAlias(node, attrs);
- }
- else if ("attribute-set".equals(name))
- {
- parseAttributeSet(node, attrs);
- }
- parse(node.getNextSibling(), false);
- }
- else if (root)
- {
- // Literal document element
- Attr versionNode =
- ((Element)node).getAttributeNodeNS(XSL_NS, "version");
- if (versionNode == null)
- {
- String msg = "no xsl:version attribute on literal result node";
- DOMSourceLocator l = new DOMSourceLocator(node);
- throw new TransformerConfigurationException(msg, l);
- }
- version = versionNode.getValue();
- Node rootClone = node.cloneNode(true);
- NamedNodeMap attrs = rootClone.getAttributes();
- attrs.removeNamedItemNS(XSL_NS, "version");
- templates.add(new Template(this, null, new Root(),
- parse(rootClone),
- precedence,
- Template.DEFAULT_PRIORITY,
- null));
- }
- else
- {
- // Skip unknown elements, text, comments, etc
- parse(node.getNextSibling(), false);
- }
- }
- catch (TransformerException e)
- {
- DOMSourceLocator l = new DOMSourceLocator(node);
- throw new TransformerConfigurationException(e.getMessage(), l, e);
- }
- catch (DOMException e)
- {
- DOMSourceLocator l = new DOMSourceLocator(node);
- throw new TransformerConfigurationException(e.getMessage(), l, e);
- }
- catch (XPathExpressionException e)
- {
- DOMSourceLocator l = new DOMSourceLocator(node);
- throw new TransformerConfigurationException(e.getMessage(), l, e);
- }
- }
-
- final NameTest parseNameTest(String token)
- {
- if ("*".equals(token))
- {
- return new NameTest(null, true, true);
- }
- else if (token.endsWith(":*"))
- {
- QName qName = getQName(token.substring(0, token.length() - 2));
- return new NameTest(qName, true, false);
- }
- else
- {
- QName qName = getQName(token);
- return new NameTest(qName, false, false);
- }
- }
-
- final QName getQName(String name)
- {
- QName qName = QName.valueOf(name);
- String prefix = qName.getPrefix();
- String uri = qName.getNamespaceURI();
- if (prefix != null && (uri == null || uri.length() == 0))
- {
- uri = getNamespaceURI(prefix);
- String localName = qName.getLocalPart();
- qName = new QName(uri, localName, prefix);
- }
- return qName;
- }
-
- final TemplateNode parseAttributeValueTemplate(String value, Node source)
- throws TransformerConfigurationException, XPathExpressionException
- {
- current = source;
- // Tokenize
- int len = value.length();
- int off = 0;
- List tokens = new ArrayList(); // text tokens
- List types = new ArrayList(); // literal or expression
- int depth = 0;
- for (int i = 0; i < len; i++)
- {
- char c = value.charAt(i);
- if (c == '{')
- {
- if (i < (len - 1) && value.charAt(i + 1) == '{')
- {
- tokens.add(value.substring(off, i + 1));
- types.add(Boolean.FALSE);
- i++;
- off = i + 1;
- continue;
- }
- if (depth == 0)
- {
- if (i - off > 0)
- {
- tokens.add(value.substring(off, i));
- types.add(Boolean.FALSE);
- }
- off = i + 1;
- }
- depth++;
- }
- else if (c == '}')
- {
- if (i < (len - 1) && value.charAt(i + 1) == '}')
- {
- tokens.add(value.substring(off, i + 1));
- types.add(Boolean.FALSE);
- i++;
- off = i + 1;
- continue;
- }
- if (depth == 1)
- {
- if (i - off > 0)
- {
- tokens.add(value.substring(off, i));
- types.add(Boolean.TRUE);
- }
- else
- {
- String msg = "attribute value template " +
- "must contain expression: " + value;
- DOMSourceLocator l = new DOMSourceLocator(source);
- throw new TransformerConfigurationException(msg, l);
- }
- off = i + 1;
- }
- depth--;
- }
- }
- if (depth > 0)
- {
- String msg = "invalid attribute value template: " + value;
- throw new TransformerConfigurationException(msg);
- }
- if (len - off > 0)
- {
- // Trailing text
- tokens.add(value.substring(off));
- types.add(Boolean.FALSE);
- }
-
- // Construct template node tree
- TemplateNode ret = null;
- Document doc = source.getOwnerDocument();
- len = tokens.size();
- for (int i = len - 1; i >= 0; i--)
- {
- String token = (String) tokens.get(i);
- Boolean type = (Boolean) types.get(i);
- if (type == Boolean.TRUE)
- {
- // Expression text
- Expr select = (Expr) xpath.compile(token);
- ret = new ValueOfNode(null, ret, select, false);
- }
- else
- {
- // Verbatim text
- ret = new LiteralNode(null, ret, doc.createTextNode(token));
- }
- }
- return ret;
- }
-
- boolean isPreserved(Text text)
- throws TransformerConfigurationException
- {
- // Check characters in text
- String value = text.getData();
- if (value != null)
- {
- int len = value.length();
- for (int i = 0; i < len; i++)
- {
- char c = value.charAt(i);
- if (c != 0x20 && c != 0x09 && c != 0x0a && c != 0x0d)
- {
- return true;
- }
- }
- }
- // Check parent node
- Node ctx = text.getParentNode();
- if (!preserveSpace.isEmpty())
- {
- for (Iterator i = preserveSpace.iterator(); i.hasNext(); )
- {
- NameTest preserveTest = (NameTest) i.next();
- if (preserveTest.matches(ctx, 1, 1))
- {
- boolean override = false;
- if (!stripSpace.isEmpty())
- {
- for (Iterator j = stripSpace.iterator(); j.hasNext(); )
- {
- NameTest stripTest = (NameTest) j.next();
- if (stripTest.matches(ctx, 1, 1))
- {
- override = true;
- break;
- }
- }
- }
- if (!override)
- {
- return true;
- }
- }
- }
- }
- // Check whether any ancestor specified xml:space
- while (ctx != null)
- {
- if (ctx.getNodeType() == Node.ELEMENT_NODE)
- {
- Element element = (Element) ctx;
- String xmlSpace = element.getAttribute("xml:space");
- if ("default".equals(xmlSpace))
- {
- break;
- }
- else if ("preserve".equals(xmlSpace))
- {
- 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();
- }
- return false;
- }
-
- public XPathFunction resolveFunction(QName name, int arity)
- {
- String uri = name.getNamespaceURI();
- if (XSL_NS.equals(uri) || uri == null || uri.length() == 0)
- {
- String localName = name.getLocalPart();
- 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());
- }
- else if ("format-number".equals(localName) &&
- (arity == 2 || arity == 3))
- {
- return new FormatNumberFunction(getRootStylesheet());
- }
- else if ("current".equals(localName) && (arity == 0))
- {
- return new CurrentFunction(getRootStylesheet());
- }
- else if ("unparsed-entity-uri".equals(localName) && (arity == 1))
- {
- return new UnparsedEntityUriFunction();
- }
- else if ("generate-id".equals(localName) &&
- (arity == 1 || arity == 0))
- {
- return new GenerateIdFunction();
- }
- else if ("system-property".equals(localName) && (arity == 1))
- {
- return new SystemPropertyFunction();
- }
- else if ("element-available".equals(localName) && (arity == 1))
- {
- return new ElementAvailableFunction(this);
- }
- else if ("function-available".equals(localName) && (arity == 1))
- {
- return new FunctionAvailableFunction(this);
- }
- }
- return null;
- }
-
- // -- Parsing --
-
- /**
- * apply-templates
- */
- final TemplateNode parseApplyTemplates(Node node, Node children, Node next)
- throws TransformerConfigurationException, XPathExpressionException
- {
- NamedNodeMap attrs = node.getAttributes();
- String m = getAttribute(attrs, "mode");
- QName mode = (m == null) ? null : getQName(m);
- String s = getAttribute(attrs, "select");
- if (s == null)
- {
- s = "child::node()";
- }
- List sortKeys = parseSortKeys(children);
- List withParams = parseWithParams(children);
- Expr select = (Expr) xpath.compile(s);
- return new ApplyTemplatesNode(null, parse(next),
- select, mode,
- sortKeys, withParams, false);
- }
-
- /**
- * call-template
- */
- final TemplateNode parseCallTemplate(Node node, Node children, Node next)
- throws TransformerConfigurationException, XPathExpressionException
- {
- NamedNodeMap attrs = node.getAttributes();
- String n = getRequiredAttribute(attrs, "name", node);
- QName name = getQName(n);
- List withParams = parseWithParams(children);
- return new CallTemplateNode(null, parse(next), name,
- withParams);
- }
-
- /**
- * value-of
- */
- final TemplateNode parseValueOf(Node node, Node children, Node next)
- throws TransformerConfigurationException, XPathExpressionException
- {
- NamedNodeMap attrs = node.getAttributes();
- String s = getRequiredAttribute(attrs, "select", node);
- String doe = getAttribute(attrs, "disable-output-escaping");
- boolean d = "yes".equals(doe);
- Expr select = (Expr) xpath.compile(s);
- return new ValueOfNode(null, parse(next), select, d);
- }
-
- /**
- * for-each
- */
- final TemplateNode parseForEach(Node node, Node children, Node next)
- throws TransformerConfigurationException, XPathExpressionException
- {
- NamedNodeMap attrs = node.getAttributes();
- String s = getRequiredAttribute(attrs, "select", node);
- List sortKeys = parseSortKeys(children);
- Expr select = (Expr) xpath.compile(s);
- return new ForEachNode(parse(children), parse(next), select, sortKeys);
- }
-
- /**
- * if
- */
- final TemplateNode parseIf(Node node, Node children, Node next)
- throws TransformerConfigurationException, XPathExpressionException
- {
- NamedNodeMap attrs = node.getAttributes();
- String t = getRequiredAttribute(attrs, "test", node);
- Expr test = (Expr) xpath.compile(t);
- return new IfNode(parse(children), parse(next), test);
- }
-
- /**
- * when
- */
- final TemplateNode parseWhen(Node node, Node children, Node next)
- throws TransformerConfigurationException, XPathExpressionException
- {
- NamedNodeMap attrs = node.getAttributes();
- String t = getRequiredAttribute(attrs, "test", node);
- Expr test = (Expr) xpath.compile(t);
- return new WhenNode(parse(children), parse(next), test);
- }
-
- /**
- * element
- */
- final TemplateNode parseElement(Node node, Node children, Node next)
- throws TransformerConfigurationException, XPathExpressionException
- {
- NamedNodeMap attrs = node.getAttributes();
- String name = getRequiredAttribute(attrs, "name", node);
- String namespace = getAttribute(attrs, "namespace");
- String uas = getAttribute(attrs, "use-attribute-sets");
- TemplateNode n = parseAttributeValueTemplate(name, node);
- TemplateNode ns = (namespace == null) ? null :
- parseAttributeValueTemplate(namespace, node);
- return new ElementNode(parse(children), parse(next), n, ns, uas, node);
- }
-
- /**
- * attribute
- */
- final TemplateNode parseAttribute(Node node, Node children, Node next)
- throws TransformerConfigurationException, XPathExpressionException
- {
- NamedNodeMap attrs = node.getAttributes();
- String name = getRequiredAttribute(attrs, "name", node);
- String namespace = getAttribute(attrs, "namespace");
- TemplateNode n = parseAttributeValueTemplate(name, node);
- TemplateNode ns = (namespace == null) ? null :
- parseAttributeValueTemplate(namespace, node);
- return new AttributeNode(parse(children), parse(next), n, ns, node);
- }
-
- /**
- * text
- */
- final TemplateNode parseText(Node node, Node children, Node next)
- throws TransformerConfigurationException, XPathExpressionException
- {
- NamedNodeMap attrs = node.getAttributes();
- String doe = getAttribute(attrs, "disable-output-escaping");
- boolean d = "yes".equals(doe);
- return new TextNode(parse(children), parse(next), d);
- }
-
- /**
- * copy
- */
- final TemplateNode parseCopy(Node node, Node children, Node next)
- throws TransformerConfigurationException, XPathExpressionException
- {
- NamedNodeMap attrs = node.getAttributes();
- String uas = getAttribute(attrs, "use-attribute-sets");
- return new CopyNode(parse(children), parse(next), uas);
- }
-
- /**
- * processing-instruction
- */
- final TemplateNode parseProcessingInstruction(Node node, Node children,
- Node next)
- throws TransformerConfigurationException, XPathExpressionException
- {
- NamedNodeMap attrs = node.getAttributes();
- String name = getRequiredAttribute(attrs, "name", node);
- return new ProcessingInstructionNode(parse(children),
- parse(next), name);
- }
-
- /**
- * number
- */
- final TemplateNode parseNumber(Node node, Node children, Node next)
- throws TransformerConfigurationException, XPathExpressionException
- {
- NamedNodeMap attrs = node.getAttributes();
- String v = getAttribute(attrs, "value");
- String ff = getAttribute(attrs, "format");
- if (ff == null)
- {
- ff = "1";
- }
- TemplateNode format = parseAttributeValueTemplate(ff, node);
- String lang = getAttribute(attrs, "lang");
- String lv = getAttribute(attrs, "letter-value");
- int letterValue = "traditional".equals(lv) ?
- AbstractNumberNode.TRADITIONAL :
- AbstractNumberNode.ALPHABETIC;
- String gs = getAttribute(attrs, "grouping-separator");
- String gz = getAttribute(attrs, "grouping-size");
- int gz2 = (gz != null && gz.length() > 0) ?
- Integer.parseInt(gz) : 1;
- if (v != null && v.length() > 0)
- {
- Expr value = (Expr) xpath.compile(v);
- return new NumberNode(parse(children), parse(next),
- value, format, lang,
- letterValue, gs, gz2);
- }
- else
- {
- String l = getAttribute(attrs, "level");
- int level =
- "multiple".equals(l) ? NodeNumberNode.MULTIPLE :
- "any".equals(l) ? NodeNumberNode.ANY :
- NodeNumberNode.SINGLE;
- String c = getAttribute(attrs, "count");
- String f = getAttribute(attrs, "from");
- Pattern count = null;
- Pattern from = null;
- if (c != null)
- {
- try
- {
- count = (Pattern) xpath.compile(c);
- }
- catch (ClassCastException e)
- {
- String msg = "invalid pattern: " + c;
- throw new TransformerConfigurationException(msg);
- }
- }
- if (f != null)
- {
- try
- {
- from = (Pattern) xpath.compile(f);
- }
- catch (ClassCastException e)
- {
- String msg = "invalid pattern: " + f;
- throw new TransformerConfigurationException(msg);
- }
- }
- return new NodeNumberNode(parse(children), parse(next),
- level, count, from,
- format, lang,
- letterValue, gs, gz2);
- }
- }
-
- /**
- * copy-of
- */
- final TemplateNode parseCopyOf(Node node, Node children, Node next)
- throws TransformerConfigurationException, XPathExpressionException
- {
- NamedNodeMap attrs = node.getAttributes();
- String s = getRequiredAttribute(attrs, "select", node);
- Expr select = (Expr) xpath.compile(s);
- return new CopyOfNode(parse(children), parse(next), select);
- }
-
- /**
- * message
- */
- final TemplateNode parseMessage(Node node, Node children, Node next)
- throws TransformerConfigurationException, XPathExpressionException
- {
- NamedNodeMap attrs = node.getAttributes();
- String t = getAttribute(attrs, "terminate");
- boolean terminate = "yes".equals(t);
- return new MessageNode(parse(children), parse(next), terminate);
- }
-
- /**
- * Parse template-level elements.
- */
- final TemplateNode parse(Node node)
- throws TransformerConfigurationException
- {
- if (node == null)
- {
- return null;
- }
- // Hack to associate the document function with its declaring node
- current = node;
- Node children = node.getFirstChild();
- Node next = node.getNextSibling();
- try
- {
- String namespaceUri = node.getNamespaceURI();
- if (Stylesheet.XSL_NS.equals(namespaceUri) &&
- Node.ELEMENT_NODE == node.getNodeType())
- {
- String name = node.getLocalName();
- if ("apply-templates".equals(name))
- {
- return parseApplyTemplates(node, children, next);
- }
- else if ("call-template".equals(name))
- {
- return parseCallTemplate(node, children, next);
- }
- else if ("value-of".equals(name))
- {
- return parseValueOf(node, children, next);
- }
- else if ("for-each".equals(name))
- {
- return parseForEach(node, children, next);
- }
- else if ("if".equals(name))
- {
- return parseIf(node, children, next);
- }
- else if ("choose".equals(name))
- {
- return new ChooseNode(parse(children), parse(next));
- }
- else if ("when".equals(name))
- {
- return parseWhen(node, children, next);
- }
- else if ("otherwise".equals(name))
- {
- return new OtherwiseNode(parse(children), parse(next));
- }
- else if ("element".equals(name))
- {
- return parseElement(node, children, next);
- }
- else if ("attribute".equals(name))
- {
- return parseAttribute(node, children, next);
- }
- else if ("text".equals(name))
- {
- return parseText(node, children, next);
- }
- else if ("copy".equals(name))
- {
- return parseCopy(node, children, next);
- }
- else if ("processing-instruction".equals(name))
- {
- return parseProcessingInstruction(node, children, next);
- }
- else if ("comment".equals(name))
- {
- return new CommentNode(parse(children), parse(next));
- }
- else if ("number".equals(name))
- {
- return parseNumber(node, children, next);
- }
- else if ("param".equals(name) ||
- "variable".equals(name))
- {
- boolean global = "variable".equals(name);
- NamedNodeMap attrs = node.getAttributes();
- TemplateNode content = parse(children);
- String paramName = getRequiredAttribute(attrs, "name", node);
- String select = getAttribute(attrs, "select");
- if (select != null)
- {
- if (content != null)
- {
- String msg = "parameter '" + paramName +
- "' has both select and content";
- DOMSourceLocator l = new DOMSourceLocator(node);
- throw new TransformerConfigurationException(msg, l);
- }
- Expr expr = (Expr) xpath.compile(select);
- return new ParameterNode(null, parse(next),
- paramName, expr, global);
- }
- else
- {
- return new ParameterNode(content, parse(next),
- paramName, null, global);
- }
- }
- else if ("copy-of".equals(name))
- {
- return parseCopyOf(node, children, next);
- }
- else if ("message".equals(name))
- {
- return parseMessage(node, children, next);
- }
- else if ("apply-imports".equals(name))
- {
- return new ApplyImportsNode(parse(children), parse(next));
- }
- else
- {
- // xsl:fallback
- // Pass over any other XSLT nodes
- return parse(next);
- }
- }
- String prefix = node.getPrefix();
- if (extensionElementPrefixes.contains(prefix))
- {
- // Pass over extension elements
- return parse(next);
- }
- switch (node.getNodeType())
- {
- case Node.TEXT_NODE:
- // Determine whether to strip whitespace
- Text text = (Text) node;
- if (!isPreserved(text))
- {
- // Strip
- text.getParentNode().removeChild(text);
- return parse(next);
- }
- break;
- case Node.COMMENT_NODE:
- // Ignore comments
- return parse(next);
- case Node.ELEMENT_NODE:
- // Check for attribute value templates and use-attribute-sets
- NamedNodeMap attrs = node.getAttributes();
- boolean convert = false;
- String useAttributeSets = null;
- int len = attrs.getLength();
- for (int i = 0; i < len; i++)
- {
- Node attr = attrs.item(i);
- String value = attr.getNodeValue();
- if (Stylesheet.XSL_NS.equals(attr.getNamespaceURI()) &&
- "use-attribute-sets".equals(attr.getLocalName()))
- {
- useAttributeSets = value;
- convert = true;
- break;
- }
- int start = value.indexOf('{');
- int end = value.indexOf('}');
- if (start != -1 || end != -1)
- {
- convert = true;
- break;
- }
- }
- if (convert)
- {
- // Create an element-producing template node instead
- // with appropriate attribute-producing child template nodes
- TemplateNode child = parse(children);
- for (int i = 0; i < len; i++)
- {
- Node attr = attrs.item(i);
- String ans = attr.getNamespaceURI();
- String aname = attr.getNodeName();
- if (Stylesheet.XSL_NS.equals(ans) &&
- "use-attribute-sets".equals(attr.getLocalName()))
- {
- continue;
- }
- String value = attr.getNodeValue();
- TemplateNode grandchild =
- parseAttributeValueTemplate(value, node);
- TemplateNode n =
- parseAttributeValueTemplate(aname, node);
- TemplateNode ns = (ans == null) ? null :
- parseAttributeValueTemplate(ans, node);
- child = new AttributeNode(grandchild, child, n, ns, attr);
- }
- String ename = node.getNodeName();
- TemplateNode n = parseAttributeValueTemplate(ename, node);
- TemplateNode ns = (namespaceUri == null) ? null :
- parseAttributeValueTemplate(namespaceUri, node);
- return new ElementNode(child, parse(next),
- n, ns, useAttributeSets,
- node);
- }
- // Otherwise fall through
- break;
- }
- }
- catch (XPathExpressionException e)
- {
- DOMSourceLocator l = new DOMSourceLocator(node);
- throw new TransformerConfigurationException(e.getMessage(), l, e);
- }
- return new LiteralNode(parse(children), parse(next), node);
- }
-
- final List parseSortKeys(Node node)
- throws TransformerConfigurationException, XPathExpressionException
- {
- List ret = new LinkedList();
- while (node != null)
- {
- String namespaceUri = node.getNamespaceURI();
- if (Stylesheet.XSL_NS.equals(namespaceUri) &&
- Node.ELEMENT_NODE == node.getNodeType() &&
- "sort".equals(node.getLocalName()))
- {
- NamedNodeMap attrs = node.getAttributes();
- String s = getAttribute(attrs, "select");
- if (s == null)
- {
- s = ".";
- }
- Expr select = (Expr) xpath.compile(s);
- String l = getAttribute(attrs, "lang");
- TemplateNode lang = (l == null) ? null :
- parseAttributeValueTemplate(l, node);
- String dt = getAttribute(attrs, "data-type");
- TemplateNode dataType = (dt == null) ? null :
- parseAttributeValueTemplate(dt, node);
- String o = getAttribute(attrs, "order");
- TemplateNode order = (o == null) ? null :
- parseAttributeValueTemplate(o, node);
- String co = getAttribute(attrs, "case-order");
- TemplateNode caseOrder = (co == null) ? null :
- parseAttributeValueTemplate(co, node);
- ret.add(new SortKey(select, lang, dataType, order, caseOrder));
- }
- node = node.getNextSibling();
- }
- return ret.isEmpty() ? null : ret;
- }
-
- final List parseWithParams(Node node)
- throws TransformerConfigurationException, XPathExpressionException
- {
- List ret = new LinkedList();
- while (node != null)
- {
- String namespaceUri = node.getNamespaceURI();
- if (Stylesheet.XSL_NS.equals(namespaceUri) &&
- Node.ELEMENT_NODE == node.getNodeType() &&
- "with-param".equals(node.getLocalName()))
- {
- NamedNodeMap attrs = node.getAttributes();
- TemplateNode content = parse(node.getFirstChild());
- String name = getRequiredAttribute(attrs, "name", node);
- String select = getAttribute(attrs, "select");
- if (select != null)
- {
- if (content != null)
- {
- String msg = "parameter '" + name +
- "' has both select and content";
- DOMSourceLocator l = new DOMSourceLocator(node);
- throw new TransformerConfigurationException(msg, l);
- }
- Expr expr = (Expr) xpath.compile(select);
- ret.add(new WithParam(name, expr));
- }
- else
- {
- ret.add(new WithParam(name, content));
- }
- }
- node = node.getNextSibling();
- }
- return ret.isEmpty() ? null : ret;
- }
-
- /**
- * Created element nodes have a copy of the namespace nodes in the
- * stylesheet, except the XSLT namespace, extension namespaces, and
- * exclude-result-prefixes.
- */
- final void addNamespaceNodes(Node source, Node target, Document doc,
- Collection elementExcludeResultPrefixes)
- {
- NamedNodeMap attrs = source.getAttributes();
- if (attrs != null)
- {
- int len = attrs.getLength();
- for (int i = 0; i < len; i++)
- {
- Node attr = attrs.item(i);
- String uri = attr.getNamespaceURI();
- if (uri == XMLConstants.XMLNS_ATTRIBUTE_NS_URI)
- {
- String prefix = attr.getLocalName();
- if (XMLConstants.XMLNS_ATTRIBUTE.equals(prefix))
- {
- 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;
- }
- // Is the namespace already defined on the target?
- if (prefix == "#default")
- {
- prefix = null;
- }
- if (target.lookupNamespaceURI(prefix) != null)
- {
- continue;
- }
- attr = attr.cloneNode(true);
- attr = doc.adoptNode(attr);
- target.getAttributes().setNamedItemNS(attr);
- }
- }
- }
- Node parent = source.getParentNode();
- if (parent != null)
- {
- addNamespaceNodes(parent, target, doc, elementExcludeResultPrefixes);
- }
- }
-
- static final String getAttribute(NamedNodeMap attrs, String name)
- {
- Node attr = attrs.getNamedItem(name);
- if (attr == null)
- {
- return null;
- }
- String ret = attr.getNodeValue();
- if (ret.length() == 0)
- {
- return null;
- }
- return ret;
- }
-
- static final String getRequiredAttribute(NamedNodeMap attrs, String name,
- Node source)
- throws TransformerConfigurationException
- {
- String value = getAttribute(attrs, name);
- if (value == null || value.length() == 0)
- {
- String msg =
- name + " attribute is required on " + source.getNodeName();
- DOMSourceLocator l = new DOMSourceLocator(source);
- throw new TransformerConfigurationException(msg, l);
- }
- return value;
- }
-
- // Handle user data changes when nodes are cloned etc
-
- public void handle(short op, String key, Object data, Node src, Node dst)
- {
- dst.setUserData(key, data, this);
- }
-
-}
-