morten 01/08/16 05:06:45
Modified: java/src/org/apache/xalan/xsltc/dom AbsoluteIterator.java
DOMImpl.java DupFilterIterator.java
StepIterator.java UnionIterator.java
Log:
Implementation of id() and key() pattern - finally!
Added a small fix to the DOMImpl$DescendantIterator to prevent NPEs.
PR: bugzilla 1376
Obtained from: n/a
Submitted by: [EMAIL PROTECTED]
Reviewed by: [EMAIL PROTECTED]
Revision Changes Path
1.2 +2 -1
xml-xalan/java/src/org/apache/xalan/xsltc/dom/AbsoluteIterator.java
Index: AbsoluteIterator.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/dom/AbsoluteIterator.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- AbsoluteIterator.java 2001/04/17 18:52:25 1.1
+++ AbsoluteIterator.java 2001/08/16 12:06:45 1.2
@@ -1,5 +1,5 @@
/*
- * @(#)$Id: AbsoluteIterator.java,v 1.1 2001/04/17 18:52:25 sboag Exp $
+ * @(#)$Id: AbsoluteIterator.java,v 1.2 2001/08/16 12:06:45 morten Exp $
*
* The Apache Software License, Version 1.1
*
@@ -80,6 +80,7 @@
}
public NodeIterator setStartNode(int node) {
+ _startNode = DOM.ROOTNODE;
if (_isRestartable) {
resetPosition();
return _source.setStartNode(_startNode = DOM.ROOTNODE);
1.19 +25 -21
xml-xalan/java/src/org/apache/xalan/xsltc/dom/DOMImpl.java
Index: DOMImpl.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/dom/DOMImpl.java,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -r1.18 -r1.19
--- DOMImpl.java 2001/08/08 10:57:05 1.18
+++ DOMImpl.java 2001/08/16 12:06:45 1.19
@@ -1,5 +1,5 @@
/*
- * @(#)$Id: DOMImpl.java,v 1.18 2001/08/08 10:57:05 morten Exp $
+ * @(#)$Id: DOMImpl.java,v 1.19 2001/08/16 12:06:45 morten Exp $
*
* The Apache Software License, Version 1.1
*
@@ -131,7 +131,6 @@
private String[] _nsNamesArray;
private short[] _namespace;
private Hashtable _nsIndex = new Hashtable();
- private int _nsCounter = 0;
// Tracks which textnodes are whitespaces and which are not
private BitArray _whitespace; // takes xml:space into acc.
@@ -160,15 +159,6 @@
}
/**
- * Generates a namespace prefix for URIs that have no associated
- * prefix. Can happen quite frequently since we do not store
- * namespace prefixes in the tree (we only store the URIs).
- */
- private String generateNamespacePrefix() {
- return(new String("ns"+Integer.toString(_nsCounter++)));
- }
-
- /**
* Returns 'true' if a specific node is an element (of any type)
*/
private boolean isElement(final int node) {
@@ -1250,6 +1240,7 @@
protected int _limit;
public NodeIterator setStartNode(int node) {
+ _startNode = node;
if (_isRestartable) {
_node = _startNode = _includeSelf ? node - 1 : node;
// no descendents if no children
@@ -2312,9 +2303,13 @@
// Copy element name - start tag
col = name.lastIndexOf(':');
if (col > 0) {
- final String prefix = generateNamespacePrefix();
- handler.startElement(prefix+':'+name.substring(col+1));
- handler.namespace(prefix, name.substring(0,col));
+ final String uri = name.substring(0,col);
+ final String prefix = handler.getPrefix(uri);
+ final String local = name.substring(col+1);
+ if (prefix.equals(EMPTYSTRING))
+ handler.startElement(local);
+ else
+ handler.startElement(prefix+':'+local);
}
else {
handler.startElement(name);
@@ -2330,10 +2325,15 @@
handler.attribute(aname,makeStringValue(attr));
}
else {
- final String prefix = generateNamespacePrefix();
- handler.namespace(prefix,aname.substring(0,col));
- handler.attribute(prefix+':'+aname.substring(col+1),
- makeStringValue(attr));
+ final String uri = aname.substring(0,col);
+ final String prefix = handler.getPrefix(uri);
+ final String local = aname.substring(col+1);
+ final String value = makeStringValue(attr);
+ final String qname = prefix+':'+local;
+ if (prefix.equals(EMPTYSTRING))
+ handler.attribute(local, value);
+ else
+ handler.attribute(prefix+':'+local, value);
}
}
@@ -2403,9 +2403,13 @@
// Copy element name - start tag
int col = name.lastIndexOf(':');
if (col > 0) {
- final String prefix = generateNamespacePrefix();
- handler.startElement(prefix+':'+name.substring(col+1));
- handler.namespace(prefix, name.substring(0,col));
+ final String uri = name.substring(0,col);
+ final String prefix = handler.getPrefix(uri);
+ final String local = name.substring(col+1);
+ if (prefix.equals(EMPTYSTRING))
+ handler.startElement(local);
+ else
+ handler.startElement(prefix+':'+local);
}
else {
handler.startElement(name);
1.2 +66 -15
xml-xalan/java/src/org/apache/xalan/xsltc/dom/DupFilterIterator.java
Index: DupFilterIterator.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/dom/DupFilterIterator.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- DupFilterIterator.java 2001/08/15 19:23:22 1.1
+++ DupFilterIterator.java 2001/08/16 12:06:45 1.2
@@ -1,5 +1,5 @@
/*
- * @(#)$Id: DupFilterIterator.java,v 1.1 2001/08/15 19:23:22 tmiller Exp $
+ * @(#)$Id: DupFilterIterator.java,v 1.2 2001/08/16 12:06:45 morten Exp $
*
* The Apache Software License, Version 1.1
*
@@ -68,36 +68,68 @@
public final class DupFilterIterator extends NodeIteratorBase {
private final static int INIT_DATA_SIZE = 16;
- private final NodeIterator _source;
- private int[] _data = null;
- private int _last = 0;
+
+ private final NodeIterator _source; // the source iterator
+ private int[] _data = null; // cached nodes from the source
+ private int _last = 0; // the number of nodes in this
iterator
private int _current = 0;
- private int _start = -1;
+ // NOTE: NodeIteratorBase has a _startNode global variable
+ //private int _start = -1;
+
+ /**
+ * Creates a new duplicate filter iterator based on an existing iterator.
+ * This iterator should be used with union expressions and other complex
+ * iterator combinations (like 'get me the parents of all child node in
+ * the dom' sort of thing). The iterator is also used to cache node-sets
+ * returned by id() and key() iterators.
+ * @param source The iterator this iterator will get its nodes from
+ */
public DupFilterIterator(NodeIterator source) {
+ // Save a reference to the source iterator
_source = source;
+
+ // THIS HERE IS WHAT WE MIGHT WANT TO DO FOR ALL ABSOLUTE ITERATORS
+
+ // Cache contents of id() or key() index right away. Necessary for
+ // union expressions containing multiple calls to the same index, and
+ // correct as well since start-node is irrelevant for id()/key() exrp.
+ if (source instanceof KeyIndex) setStartNode(DOM.ROOTNODE);
}
+ /**
+ * Returns the next node in this iterator - excludes duplicates.
+ * @return The next node in this iterator
+ */
public int next() {
return _current < _last ? _data[_current++] : END;
}
-
+
+ /**
+ * Set the start node for this iterator
+ * @param node The start node
+ * @return A reference to this node iterator
+ */
public NodeIterator setStartNode(int node) {
- if ((_data == null) || (node != _start)) {
- _start = node;
- _source.setStartNode(node);
- _data = new int[INIT_DATA_SIZE];
+ // If the _data array is populated, and the current start node is
+ // equal to the new start node, we know we already have what we need.
+ if ((_data == null) || (node != _startNode)) {
+
+ _startNode = node;
_last = 0;
- // gather all nodes from the source iterator, eliminate dups
+ _source.setStartNode(node);
+
+ if ((_data == null) || (_data.length != INIT_DATA_SIZE))
+ _data = new int[INIT_DATA_SIZE];
+
+ // Gather all nodes from the source iterator, eliminate dups
while ((node = _source.next()) != END) {
if (_last == _data.length) {
int[] newArray = new int[_data.length * 2];
System.arraycopy(_data, 0, newArray, 0, _last);
_data = newArray;
}
- if (!isDup(node)) {
- _data[_last++] = node;
- }
+ if (!isDup(node)) _data[_last++] = node;
}
}
@@ -105,6 +137,11 @@
return this;
}
+ /**
+ * Check if a node is already in the _data array. The nodes should be in
+ * document order or reverse document order, so we may be able to use
+ * binary search here.
+ */
private boolean isDup(int node) {
boolean retval = false;
int size = _data.length;
@@ -115,20 +152,34 @@
}
return retval;
}
-
+
+ /**
+ * Returns the current position of the iterator. The position is within
the
+ * node set covered by this iterator, not within the DOM.
+ */
public int getPosition() {
return (_last - _current);
}
+ /**
+ * Returns the position of the last node in this iterator. The integer
+ * returned is equivalent to the number of nodes in this iterator.
+ */
public int getLast() {
return _last;
}
+ /**
+ * Saves the position of this iterator - see gotoMark()
+ */
public void setMark() {
_source.setMark();
_markedNode = _current;
}
+ /**
+ * Restores the position of this iterator - see setMark()
+ */
public void gotoMark() {
_source.gotoMark();
_current = _markedNode;
1.3 +5 -3
xml-xalan/java/src/org/apache/xalan/xsltc/dom/StepIterator.java
Index: StepIterator.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/dom/StepIterator.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- StepIterator.java 2001/07/10 17:46:20 1.2
+++ StepIterator.java 2001/08/16 12:06:45 1.3
@@ -1,5 +1,5 @@
/*
- * @(#)$Id: StepIterator.java,v 1.2 2001/07/10 17:46:20 morten Exp $
+ * @(#)$Id: StepIterator.java,v 1.3 2001/08/16 12:06:45 morten Exp $
*
* The Apache Software License, Version 1.1
*
@@ -70,7 +70,7 @@
public final class StepIterator extends NodeIteratorBase {
private NodeIterator _source;
private NodeIterator _iterator;
-
+
public StepIterator(NodeIterator source, NodeIterator iterator) {
_source = source;
_iterator = iterator;
@@ -105,8 +105,10 @@
}
public NodeIterator reset() {
+ _source.setStartNode(_startNode);
_source.reset();
- _iterator.setStartNode(_source.next());
+ int node = _source.next();
+ _iterator.setStartNode(node);
return resetPosition();
}
1.5 +3 -2
xml-xalan/java/src/org/apache/xalan/xsltc/dom/UnionIterator.java
Index: UnionIterator.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/dom/UnionIterator.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- UnionIterator.java 2001/08/03 15:23:21 1.4
+++ UnionIterator.java 2001/08/16 12:06:45 1.5
@@ -1,5 +1,5 @@
/*
- * @(#)$Id: UnionIterator.java,v 1.4 2001/08/03 15:23:21 morten Exp $
+ * @(#)$Id: UnionIterator.java,v 1.5 2001/08/16 12:06:45 morten Exp $
*
* The Apache Software License, Version 1.1
*
@@ -88,7 +88,8 @@
}
public int step() {
- return node = iterator.next();
+ node = iterator.next();
+ return node;
}
public void setMark() {
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]