001: /*
002: * Copyright 1999-2004 The Apache Software Foundation
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.apache.commons.jxpath.ri.model.beans;
017:
018: import java.util.ArrayList;
019: import java.util.List;
020:
021: import org.apache.commons.jxpath.JXPathException;
022: import org.apache.commons.jxpath.ri.model.NodeIterator;
023: import org.apache.commons.jxpath.ri.model.NodePointer;
024:
025: /**
026: * Combines node iterators of all elements of a collection into one
027: * aggregate node iterator.
028: *
029: * @author Dmitri Plotnikov
030: * @version $Revision: 1.3 $ $Date: 2004/02/29 14:17:41 $
031: */
032: public abstract class CollectionNodeIterator implements NodeIterator {
033: private CollectionPointer pointer;
034: private boolean reverse;
035: private NodePointer startWith;
036: private int position;
037: private List collection;
038:
039: protected CollectionNodeIterator(CollectionPointer pointer,
040: boolean reverse, NodePointer startWith) {
041: this .pointer = pointer;
042: this .reverse = reverse;
043: this .startWith = startWith;
044: }
045:
046: /**
047: * Implemened by subclasses to produce child/attribute node iterators.
048: */
049: protected abstract NodeIterator getElementNodeIterator(
050: NodePointer elementPointer);
051:
052: public int getPosition() {
053: return position;
054: }
055:
056: public boolean setPosition(int position) {
057: if (collection == null) {
058: prepare();
059: }
060:
061: if (position < 1 || position > collection.size()) {
062: return false;
063: }
064: this .position = position;
065: return true;
066: }
067:
068: public NodePointer getNodePointer() {
069: if (position == 0) {
070: return null;
071: }
072: return (NodePointer) collection.get(position - 1);
073: }
074:
075: private void prepare() {
076: collection = new ArrayList();
077: NodePointer ptr = (NodePointer) pointer.clone();
078: int length = ptr.getLength();
079: for (int i = 0; i < length; i++) {
080: ptr.setIndex(i);
081: NodePointer elementPointer = ptr.getValuePointer();
082: NodeIterator iter = getElementNodeIterator(elementPointer);
083:
084: for (int j = 1; iter.setPosition(j); j++) {
085: NodePointer childPointer = iter.getNodePointer();
086: if (reverse) {
087: collection.add(0, childPointer);
088: } else {
089: collection.add(childPointer);
090: }
091: }
092: }
093: if (startWith != null) {
094: int index = collection.indexOf(startWith);
095: if (index == -1) {
096: throw new JXPathException(
097: "Invalid starting pointer for iterator: "
098: + startWith);
099: }
100: while (collection.size() > index) {
101: if (!reverse) {
102: collection.remove(collection.size() - 1);
103: } else {
104: collection.remove(0);
105: }
106: }
107: }
108: }
109: }
|