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