View Javadoc

1   /*
2    * Copyright 1999-2004 The Apache Software Foundation
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.apache.commons.jxpath.ri.model.beans;
17  
18  import java.util.ArrayList;
19  import java.util.List;
20  
21  import org.apache.commons.jxpath.JXPathException;
22  import org.apache.commons.jxpath.ri.model.NodeIterator;
23  import org.apache.commons.jxpath.ri.model.NodePointer;
24  
25  /***
26   * Combines node iterators of all elements of a collection into one
27   * aggregate node iterator.
28   *
29   * @author Dmitri Plotnikov
30   * @version $Revision: 1.3 $ $Date: 2004/02/29 14:17:41 $
31   */
32  public abstract class CollectionNodeIterator implements NodeIterator {
33      private CollectionPointer pointer;
34      private boolean reverse;
35      private NodePointer startWith; 
36      private int position;
37      private List collection;
38  
39      protected CollectionNodeIterator(
40          CollectionPointer pointer,
41          boolean reverse,
42          NodePointer startWith) 
43      {
44          this.pointer = pointer;
45          this.reverse = reverse;
46          this.startWith = startWith;
47      }
48      
49      /***
50       * Implemened by subclasses to produce child/attribute node iterators.
51       */
52      protected abstract NodeIterator 
53              getElementNodeIterator(NodePointer elementPointer);
54  
55      public int getPosition() {
56          return position;
57      }
58  
59      public boolean setPosition(int position) {
60          if (collection == null) {
61              prepare();
62          }
63          
64          if (position < 1 || position > collection.size()) {
65              return false;
66          }
67          this.position = position;
68          return true;
69      }
70  
71      public NodePointer getNodePointer() {
72          if (position == 0) {
73              return null;
74          }
75          return (NodePointer) collection.get(position - 1);
76      }
77      
78      private void prepare() {
79          collection = new ArrayList();
80          NodePointer ptr = (NodePointer) pointer.clone();
81          int length = ptr.getLength();
82          for (int i = 0; i < length; i++) {
83              ptr.setIndex(i);
84              NodePointer elementPointer = ptr.getValuePointer();
85              NodeIterator iter = getElementNodeIterator(elementPointer);
86  
87              for (int j = 1; iter.setPosition(j); j++) {
88                  NodePointer childPointer = iter.getNodePointer();
89                  if (reverse) {
90                      collection.add(0, childPointer);
91                  }
92                  else {
93                      collection.add(childPointer);
94                  }
95              }
96          }
97          if (startWith != null) {
98              int index = collection.indexOf(startWith);
99              if (index == -1) {
100                 throw new JXPathException(
101                     "Invalid starting pointer for iterator: " + startWith);
102             }
103             while (collection.size() > index) {
104                 if (!reverse) {
105                     collection.remove(collection.size() - 1);
106                 }
107                 else {
108                     collection.remove(0);
109                 }
110             }
111         }
112     }
113 }