001 /* 002 * JBoss DNA (http://www.jboss.org/dna) 003 * See the COPYRIGHT.txt file distributed with this work for information 004 * regarding copyright ownership. Some portions may be licensed 005 * to Red Hat, Inc. under one or more contributor license agreements. 006 * See the AUTHORS.txt file in the distribution for a full listing of 007 * individual contributors. 008 * 009 * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA 010 * is licensed to you under the terms of the GNU Lesser General Public License as 011 * published by the Free Software Foundation; either version 2.1 of 012 * the License, or (at your option) any later version. 013 * 014 * JBoss DNA is distributed in the hope that it will be useful, 015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 017 * Lesser General Public License for more details. 018 * 019 * You should have received a copy of the GNU Lesser General Public 020 * License along with this software; if not, write to the Free 021 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 022 * 02110-1301 USA, or see the FSF site: http://www.fsf.org. 023 */ 024 package org.jboss.dna.graph.property.basic; 025 026 import java.util.Collections; 027 import java.util.Iterator; 028 import java.util.List; 029 import net.jcip.annotations.Immutable; 030 import org.jboss.dna.common.text.Inflector; 031 import org.jboss.dna.common.text.TextEncoder; 032 import org.jboss.dna.common.util.CheckArg; 033 import org.jboss.dna.graph.GraphI18n; 034 import org.jboss.dna.graph.property.InvalidPathException; 035 import org.jboss.dna.graph.property.NamespaceRegistry; 036 import org.jboss.dna.graph.property.Path; 037 038 /** 039 * Optimized implementation of {@link Path} that serves as the root path. 040 * 041 * @author Randall Hauch 042 */ 043 @Immutable 044 public class RootPath extends AbstractPath { 045 046 /** 047 * The serializable version. Version {@value} 048 */ 049 private static final long serialVersionUID = 1L; 050 051 public static final Path INSTANCE = new RootPath(); 052 053 private static final Path.Segment[] EMPTY_SEGMENT_ARRAY = new Path.Segment[] {}; 054 private static final List<Path.Segment> EMPTY_SEGMENT_LIST = Collections.emptyList(); 055 056 private RootPath() { 057 } 058 059 /** 060 * {@inheritDoc} 061 * 062 * @see org.jboss.dna.graph.property.Path#getAncestor(int) 063 */ 064 public Path getAncestor( int degree ) { 065 CheckArg.isNonNegative(degree, "degree"); 066 if (degree == 0) { 067 return this; 068 } 069 String msg = GraphI18n.pathAncestorDegreeIsInvalid.text(this.getString(), Inflector.getInstance().ordinalize(degree)); 070 throw new InvalidPathException(msg); 071 } 072 073 /** 074 * {@inheritDoc} 075 * 076 * @see org.jboss.dna.graph.property.basic.AbstractPath#getSegmentsOfParent() 077 */ 078 @Override 079 protected Iterator<Segment> getSegmentsOfParent() { 080 return EMPTY_PATH_ITERATOR; 081 } 082 083 /** 084 * {@inheritDoc} 085 * 086 * @see org.jboss.dna.graph.property.Path#getCanonicalPath() 087 */ 088 @Override 089 public Path getCanonicalPath() { 090 return this; 091 } 092 093 /** 094 * {@inheritDoc} 095 * 096 * @see org.jboss.dna.graph.property.Path#getCommonAncestor(org.jboss.dna.graph.property.Path) 097 */ 098 @Override 099 public Path getCommonAncestor( Path that ) { 100 CheckArg.isNotNull(that, "that"); 101 return this; 102 } 103 104 /** 105 * {@inheritDoc} 106 * 107 * @see org.jboss.dna.graph.property.Path#getLastSegment() 108 */ 109 @Override 110 public Segment getLastSegment() { 111 return null; 112 } 113 114 /** 115 * {@inheritDoc} 116 * 117 * @see org.jboss.dna.graph.property.Path#getNormalizedPath() 118 */ 119 @Override 120 public Path getNormalizedPath() { 121 return this; 122 } 123 124 /** 125 * {@inheritDoc} 126 * 127 * @see org.jboss.dna.graph.property.basic.AbstractPath#resolve(org.jboss.dna.graph.property.Path) 128 */ 129 @Override 130 public Path resolve( Path relativePath ) { 131 CheckArg.isNotNull(relativePath, "relative path"); 132 if (relativePath.isAbsolute()) { 133 String msg = GraphI18n.pathIsNotRelative.text(relativePath); 134 throw new InvalidPathException(msg); 135 } 136 // Make an absolute path out of the supplied relative path ... 137 return new BasicPath(relativePath.getSegmentsList(), true).getNormalizedPath(); 138 } 139 140 /** 141 * {@inheritDoc} 142 * 143 * @see org.jboss.dna.graph.property.Path#getParent() 144 */ 145 @Override 146 public Path getParent() { 147 return null; 148 } 149 150 /** 151 * {@inheritDoc} 152 * 153 * @see org.jboss.dna.graph.property.Path#getSegment(int) 154 */ 155 @Override 156 public Segment getSegment( int index ) { 157 CheckArg.isNonNegative(index, "index"); 158 EMPTY_SEGMENT_LIST.get(index); // throws IndexOutOfBoundsException 159 return null; 160 } 161 162 /** 163 * {@inheritDoc} 164 * 165 * @see org.jboss.dna.graph.property.Path#getSegmentsArray() 166 */ 167 @Override 168 public Segment[] getSegmentsArray() { 169 // Can return the same array every time, since it's empty ... 170 return EMPTY_SEGMENT_ARRAY; 171 } 172 173 /** 174 * {@inheritDoc} 175 * 176 * @see org.jboss.dna.graph.property.Path#getSegmentsList() 177 */ 178 public List<Segment> getSegmentsList() { 179 return EMPTY_SEGMENT_LIST; 180 } 181 182 /** 183 * {@inheritDoc} 184 * 185 * @see org.jboss.dna.graph.property.Path#getString() 186 */ 187 @Override 188 public String getString() { 189 return Path.DELIMITER_STR; 190 } 191 192 /** 193 * {@inheritDoc} 194 * 195 * @see org.jboss.dna.graph.property.Path#getString(org.jboss.dna.common.text.TextEncoder) 196 */ 197 @Override 198 public String getString( TextEncoder encoder ) { 199 return Path.DELIMITER_STR; 200 } 201 202 /** 203 * {@inheritDoc} 204 * 205 * @see org.jboss.dna.graph.property.Path#getString(org.jboss.dna.graph.property.NamespaceRegistry) 206 */ 207 @Override 208 public String getString( NamespaceRegistry namespaceRegistry ) { 209 CheckArg.isNotNull(namespaceRegistry, "namespaceRegistry"); 210 return Path.DELIMITER_STR; 211 } 212 213 /** 214 * {@inheritDoc} 215 * 216 * @see org.jboss.dna.graph.property.Path#getString(org.jboss.dna.graph.property.NamespaceRegistry, 217 * org.jboss.dna.common.text.TextEncoder) 218 */ 219 @Override 220 public String getString( NamespaceRegistry namespaceRegistry, 221 TextEncoder encoder ) { 222 CheckArg.isNotNull(namespaceRegistry, "namespaceRegistry"); 223 return Path.DELIMITER_STR; 224 } 225 226 /** 227 * {@inheritDoc} 228 * 229 * @see org.jboss.dna.graph.property.Path#getString(org.jboss.dna.graph.property.NamespaceRegistry, 230 * org.jboss.dna.common.text.TextEncoder, org.jboss.dna.common.text.TextEncoder) 231 */ 232 @Override 233 public String getString( NamespaceRegistry namespaceRegistry, 234 TextEncoder encoder, 235 TextEncoder delimiterEncoder ) { 236 return (delimiterEncoder == null) ? DELIMITER_STR : delimiterEncoder.encode(DELIMITER_STR); 237 } 238 239 /** 240 * {@inheritDoc} 241 * 242 * @see org.jboss.dna.graph.property.Path#hasSameAncestor(org.jboss.dna.graph.property.Path) 243 */ 244 @Override 245 public boolean hasSameAncestor( Path that ) { 246 CheckArg.isNotNull(that, "that"); 247 return true; 248 } 249 250 /** 251 * {@inheritDoc} 252 * 253 * @see org.jboss.dna.graph.property.Path#isAbsolute() 254 */ 255 public boolean isAbsolute() { 256 return true; 257 } 258 259 /** 260 * {@inheritDoc} 261 * 262 * @see org.jboss.dna.graph.property.Path#isAncestorOf(org.jboss.dna.graph.property.Path) 263 */ 264 @Override 265 public boolean isAncestorOf( Path decendant ) { 266 CheckArg.isNotNull(decendant, "decendant"); 267 return !decendant.isRoot(); 268 } 269 270 /** 271 * {@inheritDoc} 272 * 273 * @see org.jboss.dna.graph.property.Path#isAtOrAbove(org.jboss.dna.graph.property.Path) 274 */ 275 @Override 276 public boolean isAtOrAbove( Path other ) { 277 CheckArg.isNotNull(other, "other"); 278 return true; 279 } 280 281 /** 282 * {@inheritDoc} 283 * 284 * @see org.jboss.dna.graph.property.Path#isAtOrBelow(org.jboss.dna.graph.property.Path) 285 */ 286 @Override 287 public boolean isAtOrBelow( Path other ) { 288 CheckArg.isNotNull(other, "other"); 289 return other.isRoot(); 290 } 291 292 /** 293 * {@inheritDoc} 294 * 295 * @see org.jboss.dna.graph.property.Path#isDecendantOf(org.jboss.dna.graph.property.Path) 296 */ 297 @Override 298 public boolean isDecendantOf( Path ancestor ) { 299 CheckArg.isNotNull(ancestor, "ancestor"); 300 return false; 301 } 302 303 /** 304 * {@inheritDoc} 305 * 306 * @see org.jboss.dna.graph.property.Path#isNormalized() 307 */ 308 public boolean isNormalized() { 309 return true; 310 } 311 312 /** 313 * {@inheritDoc} 314 * 315 * @see org.jboss.dna.graph.property.Path#isRoot() 316 */ 317 public boolean isRoot() { 318 return true; 319 } 320 321 /** 322 * {@inheritDoc} 323 * 324 * @see org.jboss.dna.graph.property.Path#isSameAs(org.jboss.dna.graph.property.Path) 325 */ 326 @Override 327 public boolean isSameAs( Path other ) { 328 CheckArg.isNotNull(other, "other"); 329 return other.isRoot(); 330 } 331 332 /** 333 * {@inheritDoc} 334 * 335 * @see org.jboss.dna.graph.property.Path#iterator() 336 */ 337 @Override 338 public Iterator<Segment> iterator() { 339 return EMPTY_SEGMENT_LIST.iterator(); 340 } 341 342 /** 343 * {@inheritDoc} 344 * 345 * @see org.jboss.dna.graph.property.Path#pathsFromRoot() 346 */ 347 @Override 348 public Iterator<Path> pathsFromRoot() { 349 return new SingleIterator<Path>(this); 350 } 351 352 /** 353 * {@inheritDoc} 354 * 355 * @see org.jboss.dna.graph.property.Path#size() 356 */ 357 public int size() { 358 return 0; 359 } 360 361 /** 362 * {@inheritDoc} 363 * 364 * @see org.jboss.dna.graph.property.Path#subpath(int) 365 */ 366 @Override 367 public Path subpath( int beginIndex ) { 368 CheckArg.isNonNegative(beginIndex, "beginIndex"); 369 if (beginIndex == 0) return this; 370 EMPTY_SEGMENT_LIST.get(1); // throws IndexOutOfBoundsException 371 return null; 372 } 373 374 /** 375 * {@inheritDoc} 376 * 377 * @see org.jboss.dna.graph.property.Path#subpath(int, int) 378 */ 379 @Override 380 public Path subpath( int beginIndex, 381 int endIndex ) { 382 CheckArg.isNonNegative(beginIndex, "beginIndex"); 383 CheckArg.isNonNegative(endIndex, "endIndex"); 384 if (endIndex >= 1) { 385 EMPTY_SEGMENT_LIST.get(endIndex); // throws IndexOutOfBoundsException 386 } 387 return this; 388 } 389 390 /** 391 * {@inheritDoc} 392 * 393 * @see java.lang.Comparable#compareTo(java.lang.Object) 394 */ 395 @Override 396 public int compareTo( Path other ) { 397 return other.isRoot() ? 0 : -1; 398 } 399 400 /** 401 * {@inheritDoc} 402 * 403 * @see java.lang.Object#equals(java.lang.Object) 404 */ 405 @Override 406 public boolean equals( Object obj ) { 407 if (obj == this) return true; 408 if (obj instanceof Path) { 409 Path that = (Path)obj; 410 return that.isRoot(); 411 } 412 return false; 413 } 414 415 }