You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xalan.apache.org by sa...@apache.org on 2002/10/08 23:44:15 UTC
cvs commit: xml-xalan/java/src/org/apache/xalan/xsltc/util IntegerArray.java
santiagopg 2002/10/08 14:44:15
Modified: java/src/org/apache/xalan/xsltc DOM.java
java/src/org/apache/xalan/xsltc/compiler ApplyTemplates.java
Constants.java ForEach.java LastCall.java
Parser.java PositionCall.java Step.java
java/src/org/apache/xalan/xsltc/dom AbsoluteIterator.java
CurrentNodeListIterator.java DOMAdapter.java
DOMImpl.java DupFilterIterator.java
FilterIterator.java FilteredStepIterator.java
KeyIndex.java MatchingIterator.java MultiDOM.java
NodeIteratorBase.java NthIterator.java
StepIterator.java
java/src/org/apache/xalan/xsltc/util IntegerArray.java
Added: java/src/org/apache/xalan/xsltc/dom
ForwardPositionIterator.java
Removed: java/src/org/apache/xalan/xsltc/dom ReverseIterator.java
Log:
(1) Eliminated the need for a ReverseIterator.
(2) Added a ForwardPositionIterator as a temporary solution for some
cases.
(3) Added several javadoc-type comments.
(4) Fixed a number of cloneIterator() implementations that were broken.
Revision Changes Path
1.11 +1 -3 xml-xalan/java/src/org/apache/xalan/xsltc/DOM.java
Index: DOM.java
===================================================================
RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/DOM.java,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- DOM.java 24 Apr 2002 17:03:14 -0000 1.10
+++ DOM.java 8 Oct 2002 21:44:13 -0000 1.11
@@ -126,8 +126,6 @@
public String getLanguage(int node);
public int getSize();
public String getDocumentURI(int node);
- public int getTypedPosition(int type, int node);
- public int getTypedLast(int type, int node);
public void setFilter(StripFilter filter);
public void setupMapping(String[] names, String[] namespaces);
public boolean isElement(final int node);
1.15 +7 -1 xml-xalan/java/src/org/apache/xalan/xsltc/compiler/ApplyTemplates.java
Index: ApplyTemplates.java
===================================================================
RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/ApplyTemplates.java,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -r1.14 -r1.15
--- ApplyTemplates.java 10 May 2002 15:40:02 -0000 1.14
+++ ApplyTemplates.java 8 Oct 2002 21:44:13 -0000 1.15
@@ -103,6 +103,12 @@
if (select.length() > 0) {
_select = parser.parseExpression(this, "select", null);
+
+ // Wrap _select in a ForwardPositionExpr
+ final Expression fpe = new ForwardPositionExpr(_select);
+ _select.setParent(fpe);
+ fpe.setParser(_select.getParser());
+ _select = fpe;
}
if (mode.length() > 0) {
1.28 +3 -3 xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Constants.java
Index: Constants.java
===================================================================
RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Constants.java,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -r1.27 -r1.28
--- Constants.java 16 Sep 2002 19:33:18 -0000 1.27
+++ Constants.java 8 Oct 2002 21:44:13 -0000 1.28
@@ -155,8 +155,8 @@
= "org.apache.xalan.xsltc.dom.SortingIterator";
public static final String SORT_ITERATOR_SIG
= "Lorg.apache.xalan.xsltc.dom.SortingIterator;";
- public static final String REVERSE_ITERATOR
- = "org.apache.xalan.xsltc.dom.ReverseIterator";
+ public static final String FORWARD_POSITION_ITERATOR
+ = "org.apache.xalan.xsltc.dom.ForwardPositionIterator";
public static final String NODE_SORT_RECORD
= "org.apache.xalan.xsltc.dom.NodeSortRecord";
public static final String NODE_SORT_FACTORY
1.13 +10 -3 xml-xalan/java/src/org/apache/xalan/xsltc/compiler/ForEach.java
Index: ForEach.java
===================================================================
RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/ForEach.java,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- ForEach.java 1 Feb 2002 20:07:08 -0000 1.12
+++ ForEach.java 8 Oct 2002 21:44:13 -0000 1.13
@@ -97,8 +97,14 @@
// make sure required attribute(s) have been set
if (_select.isDummy()) {
reportError(this, parser, ErrorMsg.REQUIRED_ATTR_ERR, "select");
- return;
}
+ else {
+ // Wrap _select in a ForwardPositionExpr
+ final Expression fpe = new ForwardPositionExpr(_select);
+ _select.setParent(fpe);
+ fpe.setParser(_select.getParser());
+ _select = fpe;
+ }
}
public Type typeCheck(SymbolTable stable) throws TypeCheckError {
@@ -161,7 +167,8 @@
else {
_select.translate(classGen, methodGen);
}
- if (!(_type instanceof ReferenceType)) {
+
+ if (_type instanceof ReferenceType == false) {
_select.startResetIterator(classGen, methodGen);
}
}
1.8 +8 -66 xml-xalan/java/src/org/apache/xalan/xsltc/compiler/LastCall.java
Index: LastCall.java
===================================================================
RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/LastCall.java,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- LastCall.java 1 Feb 2002 20:07:08 -0000 1.7
+++ LastCall.java 8 Oct 2002 21:44:13 -0000 1.8
@@ -71,17 +71,10 @@
final class LastCall extends FunctionCall {
- private int _type = -1;
-
public LastCall(QName fname) {
super(fname);
}
- public LastCall(QName fname, int type) {
- this(fname);
- _type = type;
- }
-
public boolean hasPositionCall() {
return true;
}
@@ -91,72 +84,21 @@
}
public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
-
final InstructionList il = methodGen.getInstructionList();
- final ConstantPoolGen cpg = classGen.getConstantPool();
-
- boolean lastChild = false;
-
- // If we're a part of an pattern's predicate we want to know what
- // type of node we want to be looking for (not just any).
- if (getParent() instanceof Expression) {
- if (getParent().getParent() instanceof Predicate) {
- Predicate pred = (Predicate)getParent().getParent();
- _type = pred.getPosType();
- if ((_type==DOM.ELEMENT) || (_type==DOM.ATTRIBUTE)) _type = -1;
- }
- }
-
- // If we're a part of a step-type expression we want the last of the
- // current node's children and not the last in the current iterator.
- if (getParent() instanceof Predicate) {
- _type = ((Predicate)getParent()).getPosType();
- if ((_type==DOM.ELEMENT) || (_type==DOM.ATTRIBUTE)) _type = -1;
- if (getParent().getParent() instanceof Step) {
- lastChild = true;
- }
- }
if (methodGen instanceof CompareGenerator) {
il.append(((CompareGenerator)methodGen).loadLastNode());
}
- else if (classGen.isExternal()) {
+ else if (methodGen instanceof TestGenerator) {
il.append(new ILOAD(LAST_INDEX));
}
- else if (_type == -1) {
- final int last = cpg.addInterfaceMethodref(NODE_ITERATOR,
- "getLast",
- "()I");
- final int git = cpg.addInterfaceMethodref(DOM_INTF,
- "getTypedAxisIterator",
- "(II)"+NODE_ITERATOR_SIG);
- final int start = cpg.addInterfaceMethodref(NODE_ITERATOR,
- "setStartNode",
- "(I)"+
- NODE_ITERATOR_SIG);
- if (lastChild) {
- il.append(methodGen.loadDOM());
- il.append(new PUSH(cpg, Axis.CHILD));
- il.append(new PUSH(cpg, DOM.ELEMENT));
- il.append(new INVOKEINTERFACE(git, 3));
- il.append(methodGen.loadCurrentNode());
- il.append(new INVOKEINTERFACE(start, 2));
- }
- else {
- il.append(methodGen.loadIterator());
- }
- il.append(new INVOKEINTERFACE(last, 1));
- }
else {
- // public int getTypedLast(int type, int node) {
- final int last = cpg.addInterfaceMethodref(DOM_INTF,
- "getTypedLast",
- "(II)I");
- il.append(methodGen.loadDOM());
- il.append(new PUSH(cpg, _type));
- il.append(methodGen.loadContextNode());
- il.append(new INVOKEINTERFACE(last, 3));
-
+ final ConstantPoolGen cpg = classGen.getConstantPool();
+ final int getLast = cpg.addInterfaceMethodref(NODE_ITERATOR,
+ "getLast",
+ "()I");
+ il.append(methodGen.loadIterator());
+ il.append(new INVOKEINTERFACE(getLast, 1));
}
}
}
1.53 +2 -1 xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Parser.java
Index: Parser.java
===================================================================
RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Parser.java,v
retrieving revision 1.52
retrieving revision 1.53
diff -u -r1.52 -r1.53
--- Parser.java 16 Sep 2002 19:38:17 -0000 1.52
+++ Parser.java 8 Oct 2002 21:44:13 -0000 1.53
@@ -1103,6 +1103,7 @@
node.setParser(this);
node.setParent(parent);
node.setLineNumber(line);
+// System.out.println("e = " + text + " " + node);
return node;
}
}
1.9 +2 -40 xml-xalan/java/src/org/apache/xalan/xsltc/compiler/PositionCall.java
Index: PositionCall.java
===================================================================
RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/PositionCall.java,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- PositionCall.java 1 Feb 2002 20:07:08 -0000 1.8
+++ PositionCall.java 8 Oct 2002 21:44:13 -0000 1.9
@@ -71,68 +71,30 @@
final class PositionCall extends FunctionCall {
- private int _type = -1;
-
public PositionCall(QName fname) {
super(fname);
}
- public PositionCall(QName fname, int type) {
- this(fname);
- _type = type;
- }
-
public boolean hasPositionCall() {
return true;
}
public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
-
final InstructionList il = methodGen.getInstructionList();
- SyntaxTreeNode parent = getParent();
- SyntaxTreeNode granny = parent.getParent();
-
- // If we're a part of an expression's predicate we want to know what
- // type of node we want to be looking for
- if ((parent instanceof Expression) && (granny instanceof Predicate)) {
- _type = ((Predicate)granny).getPosType();
- }
- else {
- while ((granny != null) && !(granny instanceof StepPattern)) {
- parent = granny;
- granny = granny.getParent();
- }
- if ((parent instanceof Predicate) &&
- (granny instanceof StepPattern)){
- _type = ((StepPattern)granny).getNodeType();
- }
- }
-
if (methodGen instanceof CompareGenerator) {
il.append(((CompareGenerator)methodGen).loadCurrentNode());
}
else if (methodGen instanceof TestGenerator) {
il.append(new ILOAD(POSITION_INDEX));
}
- else if (_type == -1) {
+ else {
final ConstantPoolGen cpg = classGen.getConstantPool();
final int getPosition = cpg.addInterfaceMethodref(NODE_ITERATOR,
"getPosition",
"()I");
il.append(methodGen.loadIterator());
il.append(new INVOKEINTERFACE(getPosition, 1));
- }
- else {
- final ConstantPoolGen cpg = classGen.getConstantPool();
- // public int getTypedPosition(int type, int node)
- final int pos = cpg.addInterfaceMethodref(DOM_INTF,
- "getTypedPosition",
- "(II)I");
- il.append(methodGen.loadDOM());
- il.append(new PUSH(cpg, _type));
- il.append(methodGen.loadContextNode());
- il.append(new INVOKEINTERFACE(pos, 3));
}
}
}
1.38 +5 -70 xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Step.java
Index: Step.java
===================================================================
RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Step.java,v
retrieving revision 1.37
retrieving revision 1.38
diff -u -r1.37 -r1.38
--- Step.java 27 Jun 2002 14:56:29 -0000 1.37
+++ Step.java 8 Oct 2002 21:44:13 -0000 1.38
@@ -149,10 +149,12 @@
* Returns the vector containing all predicates for this step.
*/
public void addPredicates(Vector predicates) {
- if (_predicates == null)
+ if (_predicates == null) {
_predicates = predicates;
- else
+ }
+ else {
_predicates.addAll(predicates);
+ }
}
/**
@@ -235,41 +237,6 @@
}
/**
- * This method is used to determine whether the node-set produced by
- * this step must be reversed before returned to the parent element.
- * <xsl:apply-templates> should always return nodes in document order,
- * while others, such as <xsl:value-of> and <xsl:for-each> should return
- * nodes in the order of the axis in use.
- */
- private boolean reverseNodeSet() {
- // Check if axis returned nodes in reverse document order
- if ((_axis == Axis.ANCESTOR) || (_axis == Axis.ANCESTORORSELF) ||
- (_axis == Axis.PRECEDING) || (_axis == Axis.PRECEDINGSIBLING)) {
-
- // Do not reverse nodes if we had predicates
- // if (_hadPredicates) return false;
-
- // Check if this step occured under an <xsl:apply-templates> element
- SyntaxTreeNode parent = this;
- do {
- // Get the next ancestor element and check its type
- parent = parent.getParent();
-
- // Order node set if descendant of these elements:
- if (parent instanceof ApplyImports) return true;
- if (parent instanceof ApplyTemplates) return true;
- if (parent instanceof ForEach) return true;
- if (parent instanceof FilterParentPath) return true;
- if (parent instanceof FilterExpr) return true;
- if (parent instanceof WithParam) return true;
- if (parent instanceof ValueOf) return true;
-
- } while (parent != null && parent instanceof Instruction == false);
- }
- return false;
- }
-
- /**
* Translate a step by pushing the appropriate iterator onto the stack.
* The abbreviated steps '.' and '@attr' do not create new iterators
* if they are not part of a LocationPath and have no filters.
@@ -282,11 +249,6 @@
if (hasPredicates()) {
translatePredicates(classGen, methodGen);
-
- // If needed, create a reverse iterator after compiling preds
- if (_predicates.size() == 0) {
- orderIterator(classGen, methodGen);
- }
}
else {
// If it is an attribute but not '@*' or '@attr' with a parent
@@ -383,11 +345,6 @@
break;
}
-
- // If needed, create a reverse iterator
- if (!_hadPredicates) {
- orderIterator(classGen, methodGen);
- }
}
}
@@ -493,28 +450,6 @@
}
}
}
-
-
- /**
- * This method tests if this step needs to have its axis reversed,
- * and wraps its iterator inside a ReverseIterator to return the node-set
- * in document order.
- */
- public void orderIterator(ClassGenerator classGen,
- MethodGenerator methodGen) {
- // First test if nodes are in reverse document order
- if (!reverseNodeSet()) return;
-
- final ConstantPoolGen cpg = classGen.getConstantPool();
- final InstructionList il = methodGen.getInstructionList();
- final int init = cpg.addMethodref(REVERSE_ITERATOR, "<init>",
- "("+NODE_ITERATOR_SIG+")V");
- il.append(new NEW(cpg.addClass(REVERSE_ITERATOR)));
- il.append(DUP_X1);
- il.append(SWAP);
- il.append(new INVOKESPECIAL(init));
- }
-
/**
* Returns a string representation of this step.
1.9 +41 -17 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.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- AbsoluteIterator.java 15 Sep 2002 14:26:36 -0000 1.8
+++ AbsoluteIterator.java 8 Oct 2002 21:44:14 -0000 1.9
@@ -67,43 +67,67 @@
import org.apache.xalan.xsltc.NodeIterator;
import org.apache.xalan.xsltc.runtime.BasisLibrary;
+/**
+ * Absolute iterators ignore the node that is passed to setStartNode().
+ * Instead, they always start from the root node. The node passed to
+ * setStartNode() is not totally useless, though. It is needed to obtain the
+ * DOM mask, i.e. the index into the MultiDOM table that corresponds to the
+ * DOM "owning" the node.
+ *
+ * The DOM mask is cached, so successive calls to setStartNode() passing
+ * nodes from other DOMs will have no effect (i.e. this iterator cannot
+ * migrate between DOMs).
+ */
public final class AbsoluteIterator extends NodeIteratorBase {
+
+ /**
+ * Initial value for DOM masks.
+ */
+ private static final int NO_MASK = -1;
+
+ /**
+ * Source for this iterator.
+ */
private NodeIterator _source;
+
+ /**
+ * DOM mask cached after first call to setStartNode().
+ */
+ private int _mask = NO_MASK;
public AbsoluteIterator(NodeIterator source) {
_source = source;
- }
-
- public int next() {
- return returnNode(_source.next());
+// System.out.println("AI source = " + source + " this = " + this);
}
public void setRestartable(boolean isRestartable) {
_isRestartable = isRestartable;
_source.setRestartable(isRestartable);
}
-
- int _mask = -1;
public NodeIterator setStartNode(int node) {
- if (_mask == -1) {
- _mask = node & 0xFF000000;
- }
- _startNode = _mask | DOM.ROOTNODE;
if (_isRestartable) {
- resetPosition();
+ if (_mask == NO_MASK) {
+ _mask = node & 0xFF000000;
+ }
+ _startNode = _mask | DOM.ROOTNODE;
_source.setStartNode(_startNode);
- return this;
+ resetPosition();
}
- return reset();
+ return this;
+ }
+
+ public int next() {
+ return returnNode(_source.next());
}
public NodeIterator cloneIterator() {
try {
- final AbsoluteIterator clone = (AbsoluteIterator)super.clone();
- clone.setRestartable(false);
- clone._source = _source.cloneIterator();
- return clone.reset();
+ final AbsoluteIterator clone = (AbsoluteIterator) super.clone();
+ clone._source = _source.cloneIterator(); // resets source
+ clone.resetPosition();
+ clone._isRestartable = false;
+ return clone;
}
catch (CloneNotSupportedException e) {
BasisLibrary.runTimeError(BasisLibrary.ITERATOR_CLONE_ERR,
1.9 +64 -22 xml-xalan/java/src/org/apache/xalan/xsltc/dom/CurrentNodeListIterator.java
Index: CurrentNodeListIterator.java
===================================================================
RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/dom/CurrentNodeListIterator.java,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- CurrentNodeListIterator.java 13 Jun 2002 12:26:16 -0000 1.8
+++ CurrentNodeListIterator.java 8 Oct 2002 21:44:14 -0000 1.9
@@ -69,17 +69,51 @@
import org.apache.xalan.xsltc.util.IntegerArray;
import org.apache.xalan.xsltc.runtime.BasisLibrary;
+/**
+ * Iterators of this kind use a CurrentNodeListFilter to filter a subset of
+ * nodes from a source iterator. For each node from the source, the boolean
+ * method CurrentNodeListFilter.test() is called.
+ *
+ * All nodes from the source are read into an array upon calling setStartNode()
+ * (this is needed to determine the value of last, a parameter to
+ * CurrentNodeListFilter.test()). The method getLast() returns the last element
+ * after applying the filter.
+ */
public final class CurrentNodeListIterator extends NodeIteratorBase {
+ /**
+ * A flag indicating if nodes are returned in document order.
+ */
private boolean _docOrder;
+
+ /**
+ * The source for this iterator.
+ */
private NodeIterator _source;
+
+ /**
+ * A reference to a filter object.
+ */
private final CurrentNodeListFilter _filter;
+
+ /**
+ * An integer array to store nodes from source iterator.
+ */
private IntegerArray _nodes = new IntegerArray();
- private int _current; // index in _nodes of the next node to try
- private int _last = -1;
+ /**
+ * Index in _nodes of the next node to filter.
+ */
+ private int _currentIndex;
+ /**
+ * The current node in the stylesheet at the time of evaluation.
+ */
private final int _currentNode;
+
+ /**
+ * A reference to the translet.
+ */
private AbstractTranslet _translet;
public CurrentNodeListIterator(NodeIterator source,
@@ -114,9 +148,10 @@
public NodeIterator cloneIterator() {
try {
final CurrentNodeListIterator clone =
- (CurrentNodeListIterator)super.clone();
- clone._nodes = (IntegerArray)_nodes.clone();
- clone.setRestartable(false);
+ (CurrentNodeListIterator) super.clone();
+ clone._nodes = (IntegerArray) _nodes.clone();
+ clone._source = _source.cloneIterator();
+ clone._isRestartable = false;
return clone.reset();
}
catch (CloneNotSupportedException e) {
@@ -127,7 +162,7 @@
}
public NodeIterator reset() {
- _current = 0;
+ _currentIndex = 0;
return resetPosition();
}
@@ -136,10 +171,12 @@
final int currentNode = _currentNode;
final AbstractTranslet translet = _translet;
- for (int index = _current; index < last; ) {
+ for (int index = _currentIndex; index < last; ) {
+ final int position = _docOrder ? index + 1 : last - index;
final int node = _nodes.at(index++); // note increment
- if (_filter.test(node, index, last, currentNode, translet, this)) {
- _current = index;
+
+ if (_filter.test(node, position, last, currentNode, translet, this)) {
+ _currentIndex = index;
return returnNode(node);
}
}
@@ -147,8 +184,6 @@
}
public NodeIterator setStartNode(int node) {
- NodeIterator retval = this;
-
if (_isRestartable) {
_source.setStartNode(_startNode = node);
@@ -156,12 +191,19 @@
while ((node = _source.next()) != END) {
_nodes.add(node);
}
- _current = 0;
- retval = resetPosition();
+ _currentIndex = 0;
+ resetPosition();
}
- return retval;
+ return this;
}
+ public int getPosition() {
+ if (_last == -1) {
+ _last = computePositionOfLast();
+ }
+ return _docOrder ? _position : _last - _position + 1;
+ }
+
public int getLast() {
if (_last == -1) {
_last = computePositionOfLast();
@@ -170,13 +212,11 @@
}
public void setMark() {
- _source.setMark();
- _markedNode = _current;
+ _markedNode = _currentIndex;
}
public void gotoMark() {
- _source.gotoMark();
- _current = _markedNode;
+ _currentIndex = _markedNode;
}
private int computePositionOfLast() {
@@ -184,10 +224,12 @@
final int currNode = _currentNode;
final AbstractTranslet translet = _translet;
- int lastPosition = 0;
- for (int index = _current; index < last; ) {
+ int lastPosition = _position;
+ for (int index = _currentIndex; index < last; ) {
+ final int position = _docOrder ? index + 1 : last - index;
int nodeIndex = _nodes.at(index++); // note increment
- if (_filter.test(nodeIndex, index, last, currNode, translet, this)) {
+
+ if (_filter.test(nodeIndex, position, last, currNode, translet, this)) {
lastPosition++;
}
}
1.15 +1 -9 xml-xalan/java/src/org/apache/xalan/xsltc/dom/DOMAdapter.java
Index: DOMAdapter.java
===================================================================
RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/dom/DOMAdapter.java,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -r1.14 -r1.15
--- DOMAdapter.java 21 Sep 2002 17:53:23 -0000 1.14
+++ DOMAdapter.java 8 Oct 2002 21:44:14 -0000 1.15
@@ -237,14 +237,6 @@
return _domImpl.getParent(node);
}
- public int getTypedPosition(int type, int node) {
- return _domImpl.getTypedPosition(getReverse()[type], node);
- }
-
- public int getTypedLast(int type, int node) {
- return _domImpl.getTypedLast(getReverse()[type], node);
- }
-
public int getAttributeNode(final int type, final int element) {
return _domImpl.getAttributeNode(getReverse()[type], element);
}
1.86 +116 -173 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.85
retrieving revision 1.86
diff -u -r1.85 -r1.86
--- DOMImpl.java 27 Sep 2002 18:59:33 -0000 1.85
+++ DOMImpl.java 8 Oct 2002 21:44:14 -0000 1.86
@@ -1151,26 +1151,20 @@
* Iterator that returns preceding siblings of a given node
*/
private class PrecedingSiblingIterator extends NodeIteratorBase {
-
+
private int _node;
- private int _mom;
-
+ private int _sibling;
+
public boolean isReverse() {
return true;
}
public NodeIterator setStartNode(int node) {
if (_isRestartable) {
- if (node >= _firstAttributeNode) node = NULL;
- int tmp = NULL;
- _startNode = node;
- _mom = _parent[node];
- _node = _offsetOrChild[_mom];
- while ((_node != node) && (_node != NULL)) {
- tmp = _node;
- _node = _nextSibling[_node];
- }
- _node = tmp;
+ _node = node;
+ _sibling = _startNode = (node >= _firstAttributeNode) ?
+ NULL : _offsetOrChild[_parent[node]];
+ _last = -1;
return resetPosition();
}
return this;
@@ -1178,27 +1172,34 @@
public int next() {
// Return NULL if end already reached
- if (_node == NULL) return NULL;
-
- int current = _offsetOrChild[_mom];
+ if (_sibling == NULL) {
+ return END;
+ }
- // Otherwise find the next preceeding sibling
- int last = NULL;
- while ((current != _node) && (current != NULL)) {
- last = current;
- current = _nextSibling[current];
+ if (_sibling == _node) {
+ return (_node = END);
}
- current = _node;
- _node = last;
+
+ final int current = _sibling;
+ _sibling = _nextSibling[current];
return returnNode(current);
}
+ public NodeIterator reset() {
+ _sibling = _startNode;
+ return resetPosition();
+ }
+
+ public int getPosition() {
+ return getLast() - _position + 1;
+ }
+
public void setMark() {
- _markedNode = _node;
+ _markedNode = _sibling;
}
public void gotoMark() {
- _node = _markedNode;
+ _sibling = _markedNode;
}
} // end of PrecedingSiblingIterator
@@ -1209,7 +1210,8 @@
* a given node
*/
private final class TypedPrecedingSiblingIterator
- extends PrecedingSiblingIterator {
+ extends PrecedingSiblingIterator
+ {
private final int _nodeType;
public TypedPrecedingSiblingIterator(int type) {
@@ -1218,9 +1220,10 @@
public int next() {
int node;
- while ((node = super.next()) != NULL && _type[node] != _nodeType)
+ while ((node = super.next()) != NULL && _type[node] != _nodeType) {
_position--;
- return(node);
+ }
+ return node;
}
} // end of PrecedingSiblingIterator
@@ -1233,8 +1236,10 @@
*/
private class PrecedingIterator extends NodeIteratorBase {
- private int _node = 0;
- private int _mom = 0;
+ private int _node;
+ private int _ancestor;
+ private int _index, _markedIndex;
+ private IntegerArray _ancestorOrSelf = new IntegerArray();
public boolean isReverse() {
return true;
@@ -1243,8 +1248,9 @@
public NodeIterator cloneIterator() {
try {
final PrecedingIterator clone =
- (PrecedingIterator)super.clone();
+ (PrecedingIterator) super.clone();
clone.setRestartable(false);
+ clone._ancestorOrSelf = (IntegerArray) _ancestorOrSelf.clone();
return clone.reset();
}
catch (CloneNotSupportedException e) {
@@ -1256,37 +1262,60 @@
public NodeIterator setStartNode(int node) {
if (_isRestartable) {
- if (node >= _firstAttributeNode) node = _parent[node];
- _node = _startNode = node;
- _mom = _parent[_startNode];
+ _ancestorOrSelf.clear();
+
+ if (node >= _firstAttributeNode) {
+ node = _parent[node];
+ }
+ do {
+ _ancestorOrSelf.add(node);
+ } while ((node = _parent[node]) > ROOTNODE);
+
+ _index = _ancestorOrSelf.cardinality() - 1;
+ _node = _ancestorOrSelf.at(_index) + 1;
+ _ancestor = (_index > 0) ? _ancestorOrSelf.at(--_index)
+ : ROOTNODE;
+
+ _last = -1;
return resetPosition();
}
+
return this;
}
-
+
public int next() {
- while (--_node > ROOTNODE) {
- if (_node < _mom) _mom = _parent[_mom];
- if (_node != _mom) return returnNode(_node);
+ while (true) {
+ if (_node < _ancestor) {
+ return returnNode(_node++);
+ }
+ if (--_index < 0) break;
+ _ancestor = _ancestorOrSelf.at(_index);
+ _node++; // skip ancestor
}
- return(NULL);
+ return END;
+ }
+
+ public int getPosition() {
+ return getLast() - _position + 1;
}
- // redefine NodeIteratorBase's reset
public NodeIterator reset() {
- _node = _startNode;
- _mom = _parent[_startNode];
+ _index = _ancestorOrSelf.cardinality() - 1;
+ _node = _ancestorOrSelf.at(_index) + 1;
+ _ancestor = (_index > 0) ? _ancestorOrSelf.at(--_index) : ROOTNODE;
return resetPosition();
}
public void setMark() {
_markedNode = _node;
+ _markedIndex = _index;
}
public void gotoMark() {
_node = _markedNode;
+ _index = _markedIndex;
+ _ancestor = _ancestorOrSelf.at(_markedIndex);
}
-
} // end of PrecedingIterator
@@ -1304,8 +1333,9 @@
public int next() {
int node;
- while ((node = super.next()) != NULL && _type[node] != _nodeType)
+ while ((node = super.next()) != NULL && _type[node] != _nodeType) {
_position--;
+ }
return node;
}
@@ -1386,26 +1416,13 @@
private class AncestorIterator extends NodeIteratorBase {
protected int _index;
- protected int _last = -1;
-
- public final boolean isReverse() {
- return true;
- }
-
- public int getLast() {
- if (_last > -1) return _last;
- int count = 1;
- int node = _startNode;
- while ((node = _parent[node]) != ROOT) count++;
- _last = count;
- return(count);
- }
+ protected IntegerArray _cache = new IntegerArray();
public NodeIterator cloneIterator() {
try {
final AncestorIterator clone = (AncestorIterator)super.clone();
clone.setRestartable(false); // must set to false for any clone
- clone._startNode = _startNode;
+ clone._cache = (IntegerArray) _cache.clone();
return clone.reset();
}
catch (CloneNotSupportedException e) {
@@ -1417,34 +1434,42 @@
public NodeIterator setStartNode(int node) {
if (_isRestartable) {
- _last = -1;
+ _cache.clear();
+
if (_includeSelf) {
- _startNode = node;
- }
- else if (node >= _firstAttributeNode) {
- _startNode = node = _parent[node];
+ _cache.add(node);
}
- else {
- _startNode = _parent[node];
+ while ((node = _parent[node]) != NULL) {
+ _cache.add(node);
}
- _index = _startNode;
+
+ _last = _cache.cardinality();
+ _startNode = _index = _last - 1;
return resetPosition();
}
return this;
}
+ public boolean isReverse() {
+ return true;
+ }
+
+ public int getLast() {
+ return _last;
+ }
+
+ public int getPosition() {
+ return _last - _position + 1;
+ }
+
public NodeIterator reset() {
_index = _startNode;
return resetPosition();
}
public int next() {
- if (_index >= 0) {
- final int node = _index;
- _index = (_index == 0) ? -1 : _parent[_index];
- return returnNode(node);
- }
- return(NULL);
+ return (_index >= 0) ?
+ returnNode(_cache.at(_index--)) : END;
}
public void setMark() {
@@ -1468,26 +1493,25 @@
_nodeType = type;
}
- public int next() {
- int node;
- while ((node = super.next()) != NULL) {
- if (_type[node] == _nodeType) return(node);
- _position--;
- }
- return(NULL);
- }
+ public NodeIterator setStartNode(int node) {
+ if (_isRestartable) {
+ _cache.clear();
- public int getLast() {
- if (_last > -1) return _last;
- int count = 1;
- int node = _startNode;
- do {
- if (_type[node] == _nodeType) count++;
- } while ((node = _parent[node]) != ROOT);
- _last = count;
- return(count);
- }
+ if (_includeSelf && _type[node] == _nodeType) {
+ _cache.add(node);
+ }
+ while ((node = _parent[node]) != NULL) {
+ if (_nodeType == _type[node]) {
+ _cache.add(node);
+ }
+ }
+ _last = _cache.cardinality();
+ _startNode = _index = _last - 1;
+ return resetPosition();
+ }
+ return this;
+ }
} // end of TypedAncestorIterator
@@ -1895,87 +1919,6 @@
*/
public int getParent(final int node) {
return _parent[node];
- }
-
- public int getElementPosition(int node) {
- // Initialize with the first sbiling of the current node
- int match = 0;
- int curr = _offsetOrChild[_parent[node]];
- if (isElement(curr)) match++;
-
- // Then traverse all other siblings up until the current node
- while (curr != node) {
- curr = _nextSibling[curr];
- if (isElement(curr)) match++;
- }
-
- // And finally return number of matches
- return match;
- }
-
- public int getAttributePosition(int attr) {
- // Initialize with the first sbiling of the current node
- int match = 1;
- int curr = _lengthOrAttr[_parent[attr]];
-
- // Then traverse all other siblings up until the current node
- while (curr != attr) {
- curr = _nextSibling[curr];
- match++;
- }
-
- // And finally return number of matches
- return match;
- }
-
- /**
- * Returns a node's position amongst other nodes of the same type
- */
- public int getTypedPosition(int type, int node) {
- // Just return the basic position if no type is specified
- switch(type) {
- case ELEMENT:
- return getElementPosition(node);
- case ATTRIBUTE:
- return getAttributePosition(node);
- case -1:
- type = _type[node];
- }
-
- // Initialize with the first sbiling of the current node
- int match = 0;
- int curr = _offsetOrChild[_parent[node]];
- if (_type[curr] == type) match++;
-
- // Then traverse all other siblings up until the current node
- while (curr != node) {
- curr = _nextSibling[curr];
- if (_type[curr] == type) match++;
- }
-
- // And finally return number of matches
- return match;
- }
-
- /**
- * Returns an iterator's last node of a given type
- */
- public int getTypedLast(int type, int node) {
- // Just return the basic position if no type is specified
- if (type == -1) type = _type[node];
-
- // Initialize with the first sbiling of the current node
- int match = 0;
- int curr = _offsetOrChild[_parent[node]];
- if (_type[curr] == type) match++;
-
- // Then traverse all other siblings up until the very last one
- while (curr != NULL) {
- curr = _nextSibling[curr];
- if (_type[curr] == type) match++;
- }
-
- return match;
}
/**
1.9 +79 -86 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.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- DupFilterIterator.java 26 Sep 2001 13:26:25 -0000 1.8
+++ DupFilterIterator.java 8 Oct 2002 21:44:14 -0000 1.9
@@ -66,128 +66,121 @@
import org.apache.xalan.xsltc.NodeIterator;
import org.apache.xalan.xsltc.TransletException;
+import org.apache.xalan.xsltc.util.IntegerArray;
+import org.apache.xalan.xsltc.runtime.BasisLibrary;
+
+/**
+ * Removes duplicates and sorts a source iterator. The nodes from the
+ * source are collected in an array upon calling setStartNode(). This
+ * array is later sorted and duplicates are ignored in next().
+ */
public final class DupFilterIterator extends NodeIteratorBase {
- private final static int INIT_DATA_SIZE = 16;
+ /**
+ * Reference to source iterator.
+ */
+ private NodeIterator _source;
+
+ /**
+ * Array to cache all nodes from source.
+ */
+ private IntegerArray _nodes = new IntegerArray();
- 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
+ /**
+ * Index in _nodes array to current node.
+ */
private int _current = 0;
/**
- * 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
+ * Cardinality of _nodes array.
+ */
+ private int _nodesSize = 0;
+
+ /**
+ * Last value returned by next().
*/
+ private int _lastNext = END;
+
public DupFilterIterator(NodeIterator source) {
- // Save a reference to the source iterator
_source = source;
+// System.out.println("DFI source = " + source + " this = " + this);
// 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;
+ if (source instanceof KeyIndex) {
+ setStartNode(DOM.ROOTNODE);
+ }
}
- /**
- * 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 (_isRestartable) {
+ // KeyIndex iterators are always relative to the root node, so there
+ // is never any point in re-reading the iterator (and we SHOULD NOT).
+ if (_source instanceof KeyIndex && _startNode == DOM.ROOTNODE) {
+ return this;
+ }
- int i, j; // loop variables declared first for speed - don't move!!!
-
- // KeyIndex iterators are always relative to the root node, so there
- // is never any point in re-reading the iterator (and we SHOULD NOT).
- if ((_source instanceof KeyIndex) && (_data != null)) return this;
-
- // 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;
- _source.setStartNode(node);
- _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 (node != _startNode) {
+ _source.setStartNode(_startNode = node);
- // Go through all nodes in turn
- for (i=0; i<_last; i++) {
- // Is this a duplicate of the new node
- if (_data[i] == node) {
- break;
- }
- // Should the new node be inserted at this position?
- else if (_data[i] > node) {
- for (j = _last++; j>i; j--)
- _data[j] = _data[j-1];
- _data[i] = node;
- break;
- }
+ _nodes.clear();
+ while ((node = _source.next()) != END) {
+ _nodes.add(node);
}
- if (i == _last) _data[_last++] = node;
+ _nodes.sort();
+ _nodesSize = _nodes.cardinality();
+ _current = 0;
+ _lastNext = END;
+ resetPosition();
}
}
-
- _current = 0; // set to beginning
return this;
}
- /**
- * 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 (_current);
+
+ public int next() {
+ while (_current < _nodesSize) {
+ final int next = _nodes.at(_current++);
+ if (next != _lastNext) {
+ return returnNode(_lastNext = next);
+ }
+ }
+ return END;
}
- /**
- * 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;
+ public NodeIterator cloneIterator() {
+ try {
+ final DupFilterIterator clone =
+ (DupFilterIterator) super.clone();
+ clone._nodes = (IntegerArray) _nodes.clone();
+ clone._source = _source.cloneIterator();
+ clone._isRestartable = false;
+ return clone.reset();
+ }
+ catch (CloneNotSupportedException e) {
+ BasisLibrary.runTimeError(BasisLibrary.ITERATOR_CLONE_ERR,
+ e.toString());
+ return null;
+ }
+ }
+
+ public void setRestartable(boolean isRestartable) {
+ _isRestartable = isRestartable;
+ _source.setRestartable(isRestartable);
}
- /**
- * 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;
}
public NodeIterator reset() {
_current = 0;
- return(this);
+ _lastNext = END;
+ return resetPosition();
}
-
}
1.5 +27 -3 xml-xalan/java/src/org/apache/xalan/xsltc/dom/FilterIterator.java
Index: FilterIterator.java
===================================================================
RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/dom/FilterIterator.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- FilterIterator.java 4 Dec 2001 10:30:07 -0000 1.4
+++ FilterIterator.java 8 Oct 2002 21:44:14 -0000 1.5
@@ -66,13 +66,32 @@
import org.apache.xalan.xsltc.NodeIterator;
import org.apache.xalan.xsltc.runtime.BasisLibrary;
+/**
+ * Similar to a CurrentNodeListIterator except that the filter has a
+ * simpler interface (only needs the node, no position, last, etc.)
+ * It takes a source iterator and a Filter object and returns nodes
+ * from the source after filtering them by calling filter.test(node).
+ */
public final class FilterIterator extends NodeIteratorBase {
+
+ /**
+ * Reference to source iterator.
+ */
private NodeIterator _source;
+
+ /**
+ * Reference to a filter object that to be applied to each node.
+ */
private final Filter _filter;
+
+ /**
+ * A flag indicating if position is reversed.
+ */
private final boolean _isReverse;
public FilterIterator(NodeIterator source, Filter filter) {
_source = source;
+// System.out.println("FI souce = " + source + " this = " + this);
_filter = filter;
_isReverse = source.isReverse();
}
@@ -88,9 +107,9 @@
public NodeIterator cloneIterator() {
try {
- final FilterIterator clone = (FilterIterator)super.clone();
- clone.setRestartable(false);
+ final FilterIterator clone = (FilterIterator) super.clone();
clone._source = _source.cloneIterator();
+ clone._isRestartable = false;
return clone.reset();
}
catch (CloneNotSupportedException e) {
@@ -121,6 +140,11 @@
return resetPosition();
}
return this;
+ }
+
+ public int getPosition() {
+ final int last = getLast();
+ return _isReverse ? last - _position + 1 : _position;
}
public void setMark() {
1.6 +8 -20 xml-xalan/java/src/org/apache/xalan/xsltc/dom/FilteredStepIterator.java
Index: FilteredStepIterator.java
===================================================================
RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/dom/FilteredStepIterator.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- FilteredStepIterator.java 4 Dec 2001 10:30:07 -0000 1.5
+++ FilteredStepIterator.java 8 Oct 2002 21:44:14 -0000 1.6
@@ -67,6 +67,10 @@
import org.apache.xalan.xsltc.NodeIterator;
import org.apache.xalan.xsltc.runtime.BasisLibrary;
+/**
+ * Extends a StepIterator by adding the ability to filter nodes. It
+ * uses filters similar to those of a FilterIterator.
+ */
public final class FilteredStepIterator extends StepIterator {
private Filter _filter;
@@ -78,30 +82,14 @@
_filter = filter;
}
- public NodeIterator cloneIterator() {
- try {
- final FilteredStepIterator clone =
- (FilteredStepIterator)super.clone();
- clone._source = _source.cloneIterator();
- clone._iterator = _iterator.cloneIterator();
- clone._filter = _filter;
- clone.setRestartable(false);
- return clone.reset();
- }
- catch (CloneNotSupportedException e) {
- BasisLibrary.runTimeError(BasisLibrary.ITERATOR_CLONE_ERR,
- e.toString());
- return null;
- }
- }
-
public int next() {
int node;
while ((node = super.next()) != END) {
- if (_filter.test(node))
+ if (_filter.test(node)) {
return returnNode(node);
+ }
}
- return(node);
+ return node;
}
}
1.8 +63 -80 xml-xalan/java/src/org/apache/xalan/xsltc/dom/KeyIndex.java
Index: KeyIndex.java
===================================================================
RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/dom/KeyIndex.java,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- KeyIndex.java 4 Dec 2001 10:30:07 -0000 1.7
+++ KeyIndex.java 8 Oct 2002 21:44:14 -0000 1.8
@@ -67,60 +67,48 @@
import org.apache.xalan.xsltc.DOM;
import org.apache.xalan.xsltc.NodeIterator;
+import org.apache.xalan.xsltc.dom.NodeIteratorBase;
import org.apache.xalan.xsltc.runtime.Hashtable;
+import org.apache.xalan.xsltc.util.IntegerArray;
-public class KeyIndex implements NodeIterator {
+public class KeyIndex extends NodeIteratorBase {
private Hashtable _index = new Hashtable();
- private BitArray _nodes = null;
- private int _pos = 0;
+ // private BitArray _nodes = null;
+ private IntegerArray _nodes = null;
private int _mark = 0;
private int _save = 0;
private int _start = 0;
- private int _arraySize = 0;
private int _node = -1;
- /**
- * Creates an index for a key defined by xsl:key
- */
- public KeyIndex(int size) {
- _arraySize = size;
+ public KeyIndex(int dummy) {
}
- public void setRestartable(boolean flag) {
-
- }
-
/**
* Adds a node to the node list for a given value.
- * The BitArray object makes sure duplicate nodes are eliminated.
*/
public void add(Object value, int node) {
- if ((_nodes = (BitArray)_index.get(value)) == null) {
- _nodes = new BitArray(_arraySize);
- _nodes.setMask(node & 0xff000000);
- _index.put(value,_nodes);
- }
- _nodes.setBit(node & 0x00ffffff);
-
- /*
- * TODO: A bit array can currently only hold nodes from one DOM.
- * An index will therefore only return nodes from a single document.
- */
+// System.out.println("KeyIndex.add() value = " + value + " node = " + node);
+
+ if ((_nodes = (IntegerArray) _index.get(value)) == null) {
+ _index.put(value, _nodes = new IntegerArray());
+ }
+ _nodes.add(node);
}
/**
* Merge this node set with nodes from another index
*/
public void merge(KeyIndex other) {
- // Only merge if other node set is not empty
- if (other != null) {
- if (other._nodes != null) {
- // Create new Vector for nodes if this set is empty
- if (_nodes == null)
- _nodes = other._nodes;
- else
- _nodes = _nodes.merge(other._nodes);
+// System.out.println("KeyIndex.merge()");
+ if (other == null) return;
+
+ if (other._nodes != null) {
+ if (_nodes == null) {
+ _nodes = other._nodes;
+ }
+ else {
+ _nodes.merge(other._nodes);
}
}
}
@@ -133,23 +121,29 @@
* key() function.
*/
public void lookupId(Object value) {
+// System.out.println("KeyIndex.lookupId()");
if (value instanceof String) {
final String string = (String)value;
if (string.indexOf(' ') > -1) {
StringTokenizer values = new StringTokenizer(string);
+
while (values.hasMoreElements()) {
- BitArray nodes = (BitArray)_index.get(values.nextElement());
+ final IntegerArray nodes =
+ (IntegerArray)_index.get(values.nextElement());
+
if (nodes != null) {
- if (_nodes == null)
+ if (_nodes == null) {
_nodes = nodes;
- else
- _nodes = _nodes.merge(nodes);
+ }
+ else {
+ _nodes.merge(nodes);
+ }
}
}
return;
}
}
- _nodes = (BitArray)_index.get(value);
+ _nodes = (IntegerArray) _index.get(value);
}
/**
@@ -157,74 +151,76 @@
* prior to returning the node iterator.
*/
public void lookupKey(Object value) {
- _nodes = (BitArray)_index.get(value);
+// System.out.println("KeyIndex.lookupKey() value = " + value);
+ _nodes = (IntegerArray) _index.get(value);
+ _position = 0;
}
/**
* Callers should not call next() after it returns END.
*/
public int next() {
- if (_nodes == null) return(END);
- if ((_node = _nodes.getNextBit(++_node)) == END) return(END);
- _pos++;
- return(_node | _nodes.getMask());
+// System.out.println("KeyIndex.next() _nodes = " + _nodes);
+ if (_nodes == null) return END;
+
+ return (_position < _nodes.cardinality()) ?
+ _nodes.at(_position++) : END;
}
public int containsID(int node, Object value) {
if (value instanceof String) {
final String string = (String)value;
if (string.indexOf(' ') > -1) {
- StringTokenizer values = new StringTokenizer(string);
+ final StringTokenizer values = new StringTokenizer(string);
+
while (values.hasMoreElements()) {
- BitArray nodes = (BitArray)_index.get(values.nextElement());
- if ((nodes != null) && (nodes.getBit(node))) return(1);
+ final IntegerArray nodes =
+ (IntegerArray) _index.get(values.nextElement());
+ if (nodes != null && nodes.indexOf(node) >= 0) {
+ return 1;
+ }
}
- return(0);
+ return 0;
}
}
- BitArray nodes = (BitArray)_index.get(value);
- if ((nodes != null) && (nodes.getBit(node))) return(1);
- return(0);
+ final IntegerArray nodes = (IntegerArray) _index.get(value);
+ return (nodes != null && nodes.indexOf(node) >= 0) ? 1 : 0;
}
public int containsKey(int node, Object value) {
- BitArray nodes = (BitArray)_index.get(value);
- if ((nodes != null) && (nodes.getBit(node))) return(1);
- return(0);
+ final IntegerArray nodes = (IntegerArray) _index.get(value);
+ return (nodes != null && nodes.indexOf(node) >= 0) ? 1 : 0;
}
/**
* Resets the iterator to the last start node.
*/
public NodeIterator reset() {
- _pos = _start;
+ _position = _start;
_node = _start - 1;
- return(this);
+ return this;
}
/**
* Returns the number of elements in this iterator.
*/
public int getLast() {
- if (_nodes == null)
- return(0);
- else
- return(_nodes.size()); // TODO: count actual nodes
+ return (_nodes == null) ? 0 : _nodes.cardinality();
}
/**
* Returns the position of the current node in the set.
*/
public int getPosition() {
- return(_pos);
+ return _position;
}
/**
* Remembers the current node for the next call to gotoMark().
*/
public void setMark() {
- _mark = _pos;
+ _mark = _position;
_save = _node;
}
@@ -232,7 +228,7 @@
* Restores the current node remembered by setMark().
*/
public void gotoMark() {
- _pos = _mark;
+ _position = _mark;
_node = _save;
}
@@ -245,34 +241,21 @@
_nodes = null;
}
else if (_nodes != null) {
- // Node count starts with 1, while bit arrays count from 0. Must
- // subtract one from 'start' to initialize bit array correctly.
- _start = _nodes.getBitNumber(start-1);
- _node = _start - 1;
+ _position = 0;
}
- return((NodeIterator)this);
- }
-
- /**
- * True if this iterator has a reversed axis.
- */
- public boolean isReverse() {
- return(false);
+ return this;
}
/**
* Returns a deep copy of this iterator.
*/
public NodeIterator cloneIterator() {
- KeyIndex other = new KeyIndex(_arraySize);
-
+ KeyIndex other = new KeyIndex(0);
other._index = _index;
- other._nodes = _nodes.cloneArray();
- other._pos = _pos;
+ other._nodes = (_nodes == null) ? _nodes : (IntegerArray)_nodes.clone();
other._start = _start;
other._node = _node;
-
- return(other);
+ return other;
}
}
1.7 +42 -16 xml-xalan/java/src/org/apache/xalan/xsltc/dom/MatchingIterator.java
Index: MatchingIterator.java
===================================================================
RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/dom/MatchingIterator.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- MatchingIterator.java 4 Dec 2001 10:30:07 -0000 1.6
+++ MatchingIterator.java 8 Oct 2002 21:44:14 -0000 1.7
@@ -66,11 +66,36 @@
import org.apache.xalan.xsltc.NodeIterator;
import org.apache.xalan.xsltc.runtime.BasisLibrary;
+/**
+ * This is a special kind of iterator that takes a source iterator and a
+ * node N. If initialized with a node M (the parent of N) it computes the
+ * position of N amongst the children of M. This position can be obtained
+ * by calling getPosition().
+ * It is an iterator even though next() will never be called. It is used to
+ * match patterns with a single predicate like:
+ *
+ * BOOK[position() = last()]
+ *
+ * In this example, the source iterator will return elements of type BOOK,
+ * a call to position() will return the position of N. Notice that because
+ * of the way the pattern matching is implemented, N will always be a node
+ * in the source since (i) it is a BOOK or the test sequence would not be
+ * considered and (ii) the source iterator is initialized with M which is
+ * the parent of N. Also, and still in this example, a call to last() will
+ * return the number of elements in the source (i.e. the number of BOOKs).
+ */
public final class MatchingIterator extends NodeIteratorBase {
+
+ /**
+ * A reference to a source iterator.
+ */
private NodeIterator _source;
- private final int _match;
- private int _matchPos, _matchLast = -1;
-
+
+ /**
+ * The node to match.
+ */
+ private final int _match;
+
public MatchingIterator(int match, NodeIterator source) {
_source = source;
_match = match;
@@ -83,10 +108,10 @@
public NodeIterator cloneIterator() {
try {
- final MatchingIterator clone = (MatchingIterator)super.clone();
+ final MatchingIterator clone = (MatchingIterator) super.clone();
clone._source = _source.cloneIterator();
- clone.setRestartable(false);
- return clone;
+ clone._isRestartable = false;
+ return clone.reset();
}
catch (CloneNotSupportedException e) {
BasisLibrary.runTimeError(BasisLibrary.ITERATOR_CLONE_ERR,
@@ -101,17 +126,17 @@
_source.setStartNode(node);
// Calculate the position of the node in the set
- _matchPos = 1;
- _matchLast = -1;
- while ( ((node = _source.next()) != END) && (node != _match) )
- _matchPos++;
+ _position = 1; _last = -1;
+ while ((node = _source.next()) != END && node != _match) {
+ _position++;
+ }
}
return this;
}
public NodeIterator reset() {
_source.reset();
- return this;
+ return resetPosition();
}
public int next() {
@@ -119,13 +144,14 @@
}
public int getLast() {
- if (_matchLast == -1)
- _matchLast = _source.getLast();
- return _matchLast;
+ if (_last == -1) {
+ _last = _source.getLast();
+ }
+ return _last;
}
public int getPosition() {
- return _matchPos;
+ return _position;
}
public void setMark() {
1.21 +1 -9 xml-xalan/java/src/org/apache/xalan/xsltc/dom/MultiDOM.java
Index: MultiDOM.java
===================================================================
RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/dom/MultiDOM.java,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -r1.20 -r1.21
--- MultiDOM.java 21 Jun 2002 19:15:34 -0000 1.20
+++ MultiDOM.java 8 Oct 2002 21:44:14 -0000 1.21
@@ -355,14 +355,6 @@
return _adapters[node>>>24].getParent(node & CLR) | node&SET;
}
- public int getTypedPosition(int type, int node) {
- return _adapters[node>>>24].getTypedPosition(type, node&CLR);
- }
-
- public int getTypedLast(int type, int node) {
- return _adapters[node>>>24].getTypedLast(type, node&CLR);
- }
-
public int getAttributeNode(final int type, final int el) {
return _adapters[el>>>24].getAttributeNode(type, el&CLR) | el&SET;
}
1.8 +69 -3 xml-xalan/java/src/org/apache/xalan/xsltc/dom/NodeIteratorBase.java
Index: NodeIteratorBase.java
===================================================================
RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/dom/NodeIteratorBase.java,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- NodeIteratorBase.java 14 May 2002 22:12:00 -0000 1.7
+++ NodeIteratorBase.java 8 Oct 2002 21:44:14 -0000 1.8
@@ -68,18 +68,56 @@
import org.apache.xalan.xsltc.runtime.BasisLibrary;
public abstract class NodeIteratorBase implements NodeIterator {
- private int _last = -1;
+
+ /**
+ * Cached computed value of last().
+ */
+ protected int _last = -1;
+
+ /**
+ * Value of position() in this iterator. Incremented in
+ * returnNode().
+ */
protected int _position = 0;
+ /**
+ * Store node in call to setMark().
+ */
protected int _markedNode;
+
+ /**
+ * Store node in call to setStartNode().
+ */
protected int _startNode = NodeIterator.END;
+
+ /**
+ * Flag indicating if "self" should be returned.
+ */
protected boolean _includeSelf = false;
+
+ /**
+ * Flag indicating if iterator can be restarted.
+ */
protected boolean _isRestartable = true;
+ /**
+ * Setter for _isRestartable flag.
+ */
public void setRestartable(boolean isRestartable) {
_isRestartable = isRestartable;
}
+ /**
+ * Initialize iterator using a node. If iterator is not
+ * restartable, then do nothing. If node is equal to END then
+ * subsequent calls to next() must return END.
+ */
+ abstract public NodeIterator setStartNode(int node);
+
+ /**
+ * Reset this iterator using state from last call to
+ * setStartNode().
+ */
public NodeIterator reset() {
final boolean temp = _isRestartable;
_isRestartable = true;
@@ -89,11 +127,19 @@
return this;
}
+ /**
+ * Setter for _includeSelf flag.
+ */
public NodeIterator includeSelf() {
_includeSelf = true;
return this;
}
+ /**
+ * Default implementation of getLast(). Stores current position
+ * and current node, resets the iterator, counts all nodes and
+ * restores iterator to original state.
+ */
public int getLast() {
if (_last == -1) {
final int temp = _position;
@@ -108,14 +154,28 @@
return _last;
}
+ /**
+ * Returns the position() in this iterator.
+ */
public int getPosition() {
return _position == 0 ? 1 : _position;
}
+ /**
+ * Indicates if position in this iterator is computed in reverse
+ * document order. Note that nodes are always returned in document
+ * order.
+ */
public boolean isReverse() {
return false;
}
+ /**
+ * Clones and resets this iterator. Note that the cloned iterator is
+ * not restartable. This is because cloning is needed for variable
+ * references, and the context node of the original variable
+ * declaration must be preserved.
+ */
public NodeIterator cloneIterator() {
try {
final NodeIteratorBase clone = (NodeIteratorBase)super.clone();
@@ -129,14 +189,20 @@
}
}
+ /**
+ * Utility method that increments position and returns its
+ * argument.
+ */
protected final int returnNode(final int node) {
_position++;
return node;
}
+ /**
+ * Reset the position in this iterator.
+ */
protected final NodeIterator resetPosition() {
_position = 0;
return this;
}
-
}
1.10 +21 -20 xml-xalan/java/src/org/apache/xalan/xsltc/dom/NthIterator.java
Index: NthIterator.java
===================================================================
RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/dom/NthIterator.java,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- NthIterator.java 4 Dec 2001 10:30:07 -0000 1.9
+++ NthIterator.java 8 Oct 2002 21:44:14 -0000 1.10
@@ -83,21 +83,33 @@
_source.setRestartable(isRestartable);
}
+ public NodeIterator cloneIterator() {
+ try {
+ final NthIterator clone = (NthIterator) super.clone();
+ clone._source = _source.cloneIterator(); // resets source
+ clone._isRestartable = false;
+ return clone;
+ }
+ catch (CloneNotSupportedException e) {
+ BasisLibrary.runTimeError(BasisLibrary.ITERATOR_CLONE_ERR,
+ e.toString());
+ return null;
+ }
+ }
+
public int next() {
if (_ready && _position > 0) {
_ready = false;
- // skip N-1 nodes
- final int pos = _position;
- for (int n = pos - 1; n-- > 0;) {
- if (_source.next() == NodeIterator.END) {
- return NodeIterator.END;
+ int node;
+ while ((node = _source.next()) != END) {
+ if (_position == _source.getPosition()) {
+ return node;
}
}
- return _source.next();
}
- return NodeIterator.END;
+ return END;
}
-
+
public NodeIterator setStartNode(final int node) {
if (_isRestartable) {
_source.setStartNode(node);
@@ -120,22 +132,11 @@
return 1;
}
- public boolean isReverse() {
- return _source.isReverse();
- }
-
public void setMark() {
_source.setMark();
}
public void gotoMark() {
_source.gotoMark();
- }
-
- public NodeIterator cloneIterator() {
- NodeIterator clone = _source.cloneIterator();
- NthIterator other = new NthIterator(clone, _position);
- other.setRestartable(false);
- return other.reset();
}
}
1.13 +28 -4 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.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- StepIterator.java 13 Jun 2002 12:43:49 -0000 1.12
+++ StepIterator.java 8 Oct 2002 21:44:14 -0000 1.13
@@ -68,29 +68,53 @@
import org.apache.xalan.xsltc.NodeIterator;
import org.apache.xalan.xsltc.runtime.BasisLibrary;
+/**
+ * A step iterator is used to evaluate expressions like "BOOK/TITLE".
+ * A better name for this iterator would have been ParentIterator since
+ * both "BOOK" and "TITLE" are steps in XPath lingo. Step iterators are
+ * constructed from two other iterators which we are going to refer to
+ * as "outer" and "inner". Every node from the outer iterator (the one
+ * for BOOK in our example) is used to initialize the inner iterator.
+ * After this initialization, every node from the inner iterator is
+ * returned (in essence, implementing a "nested loop").
+ */
public class StepIterator extends NodeIteratorBase {
+ /**
+ * A reference to the "outer" iterator.
+ */
protected NodeIterator _source;
+
+ /**
+ * A reference to the "inner" iterator.
+ */
protected NodeIterator _iterator;
+
+ /**
+ * Temp variable to store a marked position.
+ */
private int _pos = -1;
public StepIterator(NodeIterator source, NodeIterator iterator) {
_source = source;
_iterator = iterator;
+// System.out.println("SI source = " + source + " this = " + this);
+// System.out.println("SI iterator = " + iterator + " this = " + this);
}
public void setRestartable(boolean isRestartable) {
_isRestartable = isRestartable;
_source.setRestartable(isRestartable);
- _iterator.setRestartable(true); // must _always_ be restartable
+ _iterator.setRestartable(true); // must be restartable
}
public NodeIterator cloneIterator() {
try {
- final StepIterator clone = (StepIterator)super.clone();
+ final StepIterator clone = (StepIterator) super.clone();
clone._source = _source.cloneIterator();
clone._iterator = _iterator.cloneIterator();
- clone.setRestartable(false);
+ clone._iterator.setRestartable(true); // must be restartable
+ clone._isRestartable = false;
return clone.reset();
}
catch (CloneNotSupportedException e) {
1.1 xml-xalan/java/src/org/apache/xalan/xsltc/dom/ForwardPositionIterator.java
Index: ForwardPositionIterator.java
===================================================================
/*
* @(#)$Id: ForwardPositionIterator.java,v 1.1 2002/10/08 21:44:14 santiagopg Exp $
*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xalan" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 2001, Sun
* Microsystems., http://www.sun.com. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* @author Santiago Pericas-Geertsen
*
*/
package org.apache.xalan.xsltc.dom;
import org.apache.xalan.xsltc.NodeIterator;
import org.apache.xalan.xsltc.runtime.BasisLibrary;
/**
* This iterator is a wrapper that always returns the position of
* a node in document order. It is needed for the case where
* a call to position() occurs in the context of an XSLT element
* such as xsl:for-each, xsl:apply-templates, etc.
*/
public final class ForwardPositionIterator extends NodeIteratorBase {
private NodeIterator _source;
public ForwardPositionIterator(NodeIterator source) {
_source = source;
}
public NodeIterator cloneIterator() {
try {
final ForwardPositionIterator clone =
(ForwardPositionIterator) super.clone();
clone._source = _source.cloneIterator();
clone._isRestartable = false;
return clone.reset();
}
catch (CloneNotSupportedException e) {
BasisLibrary.runTimeError(BasisLibrary.ITERATOR_CLONE_ERR,
e.toString());
return null;
}
}
public int next() {
return returnNode(_source.next());
}
public NodeIterator setStartNode(int node) {
_source.setStartNode(node);
return this;
}
public NodeIterator reset() {
_source.reset();
return resetPosition();
}
public int getPosition() {
return _position == 0 ? 1 : _position;
}
public void setMark() {
_source.setMark();
}
public void gotoMark() {
_source.gotoMark();
}
}
1.3 +53 -2 xml-xalan/java/src/org/apache/xalan/xsltc/util/IntegerArray.java
Index: IntegerArray.java
===================================================================
RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/util/IntegerArray.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- IntegerArray.java 26 Jun 2002 19:03:06 -0000 1.2
+++ IntegerArray.java 8 Oct 2002 21:44:15 -0000 1.3
@@ -120,12 +120,63 @@
_array[_free++] = value;
}
- /** adds new int at the end if not already present */
+ /**
+ * Adds new int at the end if not already present.
+ */
public void addNew(int value) {
for (int i = 0; i < _free; i++) {
if (_array[i] == value) return; // already in array
}
add(value);
+ }
+
+ public void reverse() {
+ int left = 0;
+ int right = _free - 1;
+
+ while (left < right) {
+ int temp = _array[left];
+ _array[left++] = _array[right];
+ _array[right--] = temp;
+ }
+ }
+
+ public void merge(IntegerArray array) {
+ final int n = array._free;
+ for (int i = 0; i < n; i++) {
+ addNew(array.at(i));
+ }
+ sort(); // must be sorted
+ }
+
+ public void sort() {
+ quicksort(_array, 0, _free - 1);
+ }
+
+ private static void quicksort(int[] array, int p, int r) {
+ if (p < r) {
+ final int q = partition(array, p, r);
+ quicksort(array, p, q);
+ quicksort(array, q + 1, r);
+ }
+ }
+
+ private static int partition(int[] array, int p, int r) {
+ final int x = array[p];
+ int i = p - 1; int j = r + 1;
+
+ while (true) {
+ while (x < array[--j]);
+ while (x > array[++i]);
+ if (i < j) {
+ int temp = array[i];
+ array[i] = array[j];
+ array[j] = temp;
+ }
+ else {
+ return j;
+ }
+ }
}
private void growArray(int size) {
---------------------------------------------------------------------
To unsubscribe, e-mail: xalan-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: xalan-cvs-help@xml.apache.org