diff options
author | Andrew John Hughes <gnu_andrew@member.fsf.org> | 2008-06-23 22:35:26 +0000 |
---|---|---|
committer | Andrew John Hughes <gnu_andrew@member.fsf.org> | 2008-06-23 22:35:26 +0000 |
commit | d40155b93283c0da209b9ba3bc4b178fabc0c140 (patch) | |
tree | 391948f3dc0a4c61704d8166696451f843816627 /gnu | |
parent | c4468c342efcd45bdc6cc08ea9c06ea6edd75f69 (diff) | |
download | classpath-d40155b93283c0da209b9ba3bc4b178fabc0c140.tar.gz |
2008-06-23 Andrew John Hughes <gnu_andrew@member.fsf.org>
PR classpath/36219:
* gnu/xml/transform/ForEachNode.java:
Genericised.
* gnu/xml/transform/SortKey.java:
Documented.
(clone(Stylesheet)): Implemented.
(cloneAttributeValueTemplate(TemplateNode,Stylesheet)):
Implemented.
* gnu/xml/transform/Stylesheet.java:
(parseSortKeys(Node)): Return empty list not null.
* gnu/xml/transform/TemplateNode.java:
Genericise documentOrderComparator.
Diffstat (limited to 'gnu')
-rw-r--r-- | gnu/xml/transform/ForEachNode.java | 54 | ||||
-rw-r--r-- | gnu/xml/transform/SortKey.java | 62 | ||||
-rw-r--r-- | gnu/xml/transform/Stylesheet.java | 2 | ||||
-rw-r--r-- | gnu/xml/transform/TemplateNode.java | 2 |
4 files changed, 90 insertions, 30 deletions
diff --git a/gnu/xml/transform/ForEachNode.java b/gnu/xml/transform/ForEachNode.java index e2aed74b4..8908114cc 100644 --- a/gnu/xml/transform/ForEachNode.java +++ b/gnu/xml/transform/ForEachNode.java @@ -59,9 +59,9 @@ final class ForEachNode { final Expr select; - final List sortKeys; + final List<SortKey> sortKeys; - ForEachNode(Expr select, List sortKeys) + ForEachNode(Expr select, List<SortKey> sortKeys) { this.select = select; this.sortKeys = sortKeys; @@ -69,10 +69,10 @@ final class ForEachNode TemplateNode clone(Stylesheet stylesheet) { - int len = sortKeys != null ? sortKeys.size() : 0; - List sortKeys2 = new ArrayList(len); + int len = sortKeys.size(); + List<SortKey> sortKeys2 = new ArrayList<SortKey>(len); for (int i = 0; i < len; i++) - sortKeys2.add(((Key) sortKeys.get(i)).clone(stylesheet)); + sortKeys2.add(sortKeys.get(i).clone(stylesheet)); TemplateNode ret = new ForEachNode(select.clone(stylesheet), sortKeys2); if (children != null) @@ -82,6 +82,7 @@ final class ForEachNode return ret; } + @Override void doApply(Stylesheet stylesheet, QName mode, Node context, int pos, int len, Node parent, Node nextSibling) @@ -96,26 +97,26 @@ final class ForEachNode //System.err.println(toString() + ": " + context+" -> "+ret); if (ret instanceof Collection) { - Collection ns = (Collection) ret; - List list = new ArrayList(ns); - if (sortKeys != null) - { - for (Iterator i = sortKeys.iterator(); i.hasNext(); ) - { - SortKey sortKey = (SortKey) i.next(); - sortKey.init(stylesheet, mode, context, pos, len, parent, - nextSibling); - } - Collections.sort(list, new XSLComparator(sortKeys)); - } - else + /* Suppression is safe, as we know context produces Collection<Node> */ + @SuppressWarnings("unchecked") + Collection<Node> ns = (Collection<Node>) ret; + List<Node> list = new ArrayList<Node>(ns); + if (!sortKeys.isEmpty()) + { + for (SortKey sortKey : sortKeys) + { + sortKey.init(stylesheet, mode, context, pos, len, parent, + nextSibling); + } + Collections.sort(list, new XSLComparator(sortKeys)); + } + else Collections.sort(list, documentOrderComparator); // Perform children for each node int l = list.size(); int p = 1; - for (Iterator i = list.iterator(); i.hasNext(); ) + for (Node node : list) { - Node node = (Node) i.next(); stylesheet.current = node; children.apply(stylesheet, mode, node, p++, l, @@ -131,21 +132,20 @@ final class ForEachNode parent, nextSibling); } + @Override public boolean references(QName var) { if (select != null && select.references(var)) return true; - if (sortKeys != null) + for (Iterator<SortKey> i = sortKeys.iterator(); i.hasNext(); ) { - for (Iterator i = sortKeys.iterator(); i.hasNext(); ) - { - if (((SortKey) i.next()).references(var)) - return true; - } + if (i.next().references(var)) + return true; } return super.references(var); } - + + @Override public String toString() { CPStringBuilder buf = new CPStringBuilder("for-each"); diff --git a/gnu/xml/transform/SortKey.java b/gnu/xml/transform/SortKey.java index d4ffb05e2..72934a5b7 100644 --- a/gnu/xml/transform/SortKey.java +++ b/gnu/xml/transform/SortKey.java @@ -45,7 +45,22 @@ import org.w3c.dom.Node; import gnu.xml.xpath.Expr; /** - * An XSL sort key. + * <p> + * An XSL sort key, as specified by section 10 of the XSL + * Transformations specification. This takes the form: + * </p> + * <pre> + * <xsl:sort + * select = string-expression + * lang = { nmtoken } + * data-type = { "text" | "number" | qname-but-not-ncname } + * order = { "ascending" | "descending" } + * case-order = { "upper-first" | "lower-first" } /&rt; + * </pre> + * <p> + * Note that all but the selection expression are optional, + * and so may be {@code null}. + * </p> * * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> */ @@ -67,6 +82,20 @@ final class SortKey transient boolean descending; transient int caseOrder; + /** + * Constructs a new {@link SortKey} to represent an <xsl:sort&rt; + * tag. + * + * @param select the XPath expression which selects the nodes to be sorted. + * @param lang the language of the sort keys or {@code null} if unspecified. + * @param dataType the data type of the strings. May be "string", "number", + * a QName or {@code null} if unspecified. + * @param order the ordering of the nodes, which may be "ascending", "descending" + * or {@code null} if unspecified. + * @param caseOrder the treatment of case when the data type is a string. This + * may be "upper-first", "lower-first" or {@code null} if + * unspecified. + */ SortKey(Expr select, TemplateNode lang, TemplateNode dataType, TemplateNode order, TemplateNode caseOrder) { @@ -176,4 +205,35 @@ final class SortKey return false; } + /** + * Provides a clone of this {@link SortKey}, using the given + * stylesheet as a context. + * + * @param stylesheet the stylesheet which provides context for the cloning. + * @return a clone of this instance. + */ + SortKey clone(Stylesheet stylesheet) + { + return new SortKey(select.clone(stylesheet), + langTemplate == null ? null : cloneAttributeValueTemplate(langTemplate, stylesheet), + dataTypeTemplate == null ? null : cloneAttributeValueTemplate(dataTypeTemplate, stylesheet), + orderTemplate == null ? null : cloneAttributeValueTemplate(orderTemplate, stylesheet), + caseOrderTemplate == null ? null : cloneAttributeValueTemplate(caseOrderTemplate, stylesheet)); + } + + /** + * Clones an attribute value template as created by + * {@link Stylesheet#parseAttributeValueTemplate(String, Node)}. + * The node may either by a literal node or an xsl:value-of expression. + * + * @param node the node to clone. + * @param stylesheet the stylesheet which provides context for the cloning. + * @return the cloned node. + */ + private TemplateNode cloneAttributeValueTemplate(TemplateNode node, Stylesheet stylesheet) + { + if (node instanceof ValueOfNode) + return ((ValueOfNode) node).clone(stylesheet); + return ((LiteralNode) node).clone(stylesheet); + } } diff --git a/gnu/xml/transform/Stylesheet.java b/gnu/xml/transform/Stylesheet.java index 7d973e424..30bd95349 100644 --- a/gnu/xml/transform/Stylesheet.java +++ b/gnu/xml/transform/Stylesheet.java @@ -1644,7 +1644,7 @@ class Stylesheet } node = node.getNextSibling(); } - return ret.isEmpty() ? null : ret; + return ret; } final List<WithParam> parseWithParams(Node node) diff --git a/gnu/xml/transform/TemplateNode.java b/gnu/xml/transform/TemplateNode.java index 6ff727c07..ad80c59f9 100644 --- a/gnu/xml/transform/TemplateNode.java +++ b/gnu/xml/transform/TemplateNode.java @@ -52,7 +52,7 @@ import gnu.xml.xpath.DocumentOrderComparator; abstract class TemplateNode { - static final Comparator documentOrderComparator = + static final Comparator<Node> documentOrderComparator = new DocumentOrderComparator(); TemplateNode children; |