1 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 29 public class PropertyIterator implements NodeIterator { 30 private boolean empty = false; 31 private boolean reverse; 32 private String 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 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 (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 ex) { 111 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 name) { 245 targetReady = true; 246 empty = true; 247 248 String 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 292 private int getLength() { 293 int length; 294 try { 295 length = propertyNodePointer.getLength(); } 297 catch (Throwable t) { 298 length = 0; 300 } 301 return length; 302 } 303 } | Popular Tags |