KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > commons > jxpath > ri > model > beans > PropertyIterator


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 org.apache.commons.jxpath.JXPathException;
19 import org.apache.commons.jxpath.ri.model.NodeIterator;
20 import org.apache.commons.jxpath.ri.model.NodePointer;
21
22 /**
23  * Iterates property values of an object pointed at with a PropertyOwnerPointer.
24  * Examples of such objects are JavaBeans and objects with Dynamic Properties.
25  *
26  * @author Dmitri Plotnikov
27  * @version $Revision: 1.13 $ $Date: 2004/03/25 03:49:50 $
28  */

29 public class PropertyIterator implements NodeIterator {
30     private boolean empty = false;
31     private boolean reverse;
32     private String JavaDoc name;
33     private int startIndex = 0;
34     private boolean targetReady = false;
35     private int position = 0;
36     private PropertyPointer propertyNodePointer;
37     private int startPropertyIndex;
38
39     private boolean ready = false;
40     private boolean includeStart = false;
41
42     public PropertyIterator(
43         PropertyOwnerPointer pointer,
44         String JavaDoc name,
45         boolean reverse,
46         NodePointer startWith)
47     {
48         propertyNodePointer =
49             (PropertyPointer) pointer.getPropertyPointer().clone();
50         this.name = name;
51         this.reverse = reverse;
52         this.includeStart = true;
53         if (reverse) {
54             this.startPropertyIndex = PropertyPointer.UNSPECIFIED_PROPERTY;
55             this.startIndex = -1;
56         }
57         if (startWith != null) {
58             while (startWith != null
59                     && startWith.getImmediateParentPointer() != pointer) {
60                 startWith = startWith.getImmediateParentPointer();
61             }
62             if (startWith == null) {
63                 throw new JXPathException(
64                     "PropertyIerator startWith parameter is "
65                         + "not a child of the supplied parent");
66             }
67             this.startPropertyIndex =
68                 ((PropertyPointer) startWith).getPropertyIndex();
69             this.startIndex = startWith.getIndex();
70             if (this.startIndex == NodePointer.WHOLE_COLLECTION) {
71                 this.startIndex = 0;
72             }
73             this.includeStart = false;
74             if (reverse && startIndex == -1) {
75                 this.includeStart = true;
76             }
77         }
78     }
79
80     protected NodePointer getPropertyPointer() {
81         return propertyNodePointer;
82     }
83
84     public void reset() {
85         position = 0;
86         targetReady = false;
87     }
88
89     public NodePointer getNodePointer() {
90         if (position == 0) {
91             if (name != null) {
92                 if (!targetReady) {
93                     prepareForIndividualProperty(name);
94                 }
95                 // If there is no such property - return null
96
if (empty) {
97                     return null;
98                 }
99             }
100             else {
101                 if (!setPosition(1)) {
102                     return null;
103                 }
104                 reset();
105             }
106         }
107         try {
108             return propertyNodePointer.getValuePointer();
109         }
110         catch (Throwable JavaDoc ex) {
111             // @todo: should this exception be reported in any way?
112
NullPropertyPointer npp =
113                 new NullPropertyPointer(
114                         propertyNodePointer.getImmediateParentPointer());
115             npp.setPropertyName(propertyNodePointer.getPropertyName());
116             npp.setIndex(propertyNodePointer.getIndex());
117             return npp.getValuePointer();
118         }
119     }
120
121     public int getPosition() {
122         return position;
123     }
124
125     public boolean setPosition(int position) {
126         if (name != null) {
127             return setPositionIndividualProperty(position);
128         }
129         else {
130             return setPositionAllProperties(position);
131         }
132     }
133
134     private boolean setPositionIndividualProperty(int position) {
135         this.position = position;
136         if (position < 1) {
137             return false;
138         }
139
140         if (!targetReady) {
141             prepareForIndividualProperty(name);
142         }
143
144         if (empty) {
145             return false;
146         }
147
148         int length = getLength();
149         int index;
150         if (!reverse) {
151             index = position + startIndex;
152             if (!includeStart) {
153                 index++;
154             }
155             if (index > length) {
156                 return false;
157             }
158         }
159         else {
160             int end = startIndex;
161             if (end == -1) {
162                 end = length - 1;
163             }
164             index = end - position + 2;
165             if (!includeStart) {
166                 index--;
167             }
168             if (index < 1) {
169                 return false;
170             }
171         }
172         propertyNodePointer.setIndex(index - 1);
173         return true;
174     }
175
176     private boolean setPositionAllProperties(int position) {
177         this.position = position;
178         if (position < 1) {
179             return false;
180         }
181
182         int offset;
183         int count = propertyNodePointer.getPropertyCount();
184         if (!reverse) {
185             int index = 1;
186             for (int i = startPropertyIndex; i < count; i++) {
187                 propertyNodePointer.setPropertyIndex(i);
188                 int length = getLength();
189                 if (i == startPropertyIndex) {
190                     length -= startIndex;
191                     if (!includeStart) {
192                         length--;
193                     }
194                     offset = startIndex + position - index;
195                     if (!includeStart) {
196                         offset++;
197                     }
198                 }
199                 else {
200                     offset = position - index;
201                 }
202                 if (index <= position && position < index + length) {
203                     propertyNodePointer.setIndex(offset);
204                     return true;
205                 }
206                 index += length;
207             }
208         }
209         else {
210             int index = 1;
211             int start = startPropertyIndex;
212             if (start == PropertyPointer.UNSPECIFIED_PROPERTY) {
213                 start = count - 1;
214             }
215             for (int i = start; i >= 0; i--) {
216                 propertyNodePointer.setPropertyIndex(i);
217                 int length = getLength();
218                 if (i == startPropertyIndex) {
219                     int end = startIndex;
220                     if (end == -1) {
221                         end = length - 1;
222                     }
223                     length = end + 1;
224                     offset = end - position + 1;
225                     if (!includeStart) {
226                         offset--;
227                         length--;
228                     }
229                 }
230                 else {
231                     offset = length - (position - index) - 1;
232                 }
233
234                 if (index <= position && position < index + length) {
235                     propertyNodePointer.setIndex(offset);
236                     return true;
237                 }
238                 index += length;
239             }
240         }
241         return false;
242     }
243
244     protected void prepareForIndividualProperty(String JavaDoc name) {
245         targetReady = true;
246         empty = true;
247
248         String JavaDoc names[] = propertyNodePointer.getPropertyNames();
249         if (!reverse) {
250             if (startPropertyIndex == PropertyPointer.UNSPECIFIED_PROPERTY) {
251                 startPropertyIndex = 0;
252             }
253             if (startIndex == NodePointer.WHOLE_COLLECTION) {
254                 startIndex = 0;
255             }
256             for (int i = startPropertyIndex; i < names.length; i++) {
257                 if (names[i].equals(name)) {
258                     propertyNodePointer.setPropertyIndex(i);
259                     if (i != startPropertyIndex) {
260                         startIndex = 0;
261                         includeStart = true;
262                     }
263                     empty = false;
264                     break;
265                 }
266             }
267         }
268         else {
269             if (startPropertyIndex == PropertyPointer.UNSPECIFIED_PROPERTY) {
270                 startPropertyIndex = names.length - 1;
271             }
272             if (startIndex == NodePointer.WHOLE_COLLECTION) {
273                 startIndex = -1;
274             }
275             for (int i = startPropertyIndex; i >= 0; i--) {
276                 if (names[i].equals(name)) {
277                     propertyNodePointer.setPropertyIndex(i);
278                     if (i != startPropertyIndex) {
279                         startIndex = -1;
280                         includeStart = true;
281                     }
282                     empty = false;
283                     break;
284                 }
285             }
286         }
287     }
288
289     /**
290      * Computes length for the current pointer - ignores any exceptions
291      */

292     private int getLength() {
293         int length;
294         try {
295             length = propertyNodePointer.getLength(); // TBD: cache length
296
}
297         catch (Throwable JavaDoc t) {
298             // @todo: should this exception be reported in any way?
299
length = 0;
300         }
301         return length;
302     }
303 }
Popular Tags