📄 path.java
字号:
for (int i = 0; i < elements.length; i++) { h = 37 * h + elements[i].hashCode(); } hash = h; } return h; } /** * Compares the specified object with this path for equality. * * @param obj the object to be compared for equality with this path. * @return <tt>true</tt> if the specified object is equal to this path. */ public boolean equals(Object obj) { if (this == obj) { return true; } if (obj instanceof Path) { Path other = (Path) obj; return Arrays.equals(elements, other.getElements()); } return false; } //--------------------------------------------------------< inner classes > /** * Internal helper class used to build a path from pre-parsed path elements. * <p/> * <strong>Warning!</strong> This class does neither validate the format of * the path elements nor does it validate the format of the entire path! * This class should therefore only be used in special situations. The * regular way of creating/building a <code>Path</code> object is by calling * any of the overloaded <code>Path.create()</code> factory methods. */ public static final class PathBuilder implements Cloneable { /** * the list of path elements of the constructed path */ private final LinkedList queue; /** * flag indicating if the current path is normalized */ boolean isNormalized = true; /** * flag indicating if the current path has leading parent '..' elements */ boolean leadingParent = true; /** * Creates a new PathBuilder. */ public PathBuilder() { queue = new LinkedList(); } /** * Creates a new PathBuilder and initialized it with the given path * elements. * * @param elements */ public PathBuilder(PathElement[] elements) { this(); addAll(elements); } /** * Creates a new PathBuilder and initialized it with elements of the * given path. * * @param parent */ public PathBuilder(Path parent) { this(); addAll(parent.getElements()); } /** * Adds the {@link Path#ROOT_ELEMENT}. */ public void addRoot() { addFirst(ROOT_ELEMENT); } /** * Adds the given elemenets * * @param elements */ public void addAll(PathElement[] elements) { for (int i = 0; i < elements.length; i++) { addLast(elements[i]); } } /** * Inserts the element at the beginning of the path to be built. * * @param elem */ public void addFirst(PathElement elem) { if (queue.isEmpty()) { isNormalized &= !elem.denotesCurrent(); leadingParent = elem.denotesParent(); } else { isNormalized &= !elem.denotesCurrent() && (!leadingParent || elem.denotesParent()); leadingParent |= elem.denotesParent(); } queue.addFirst(elem); } /** * Inserts the element at the beginning of the path to be built. * * @param name */ public void addFirst(QName name) { addFirst(PathElement.create(name)); } /** * Inserts the element at the beginning of the path to be built. * * @param name * @param index */ public void addFirst(QName name, int index) { addFirst(PathElement.create(name, index)); } /** * Inserts the element at the end of the path to be built. * * @param elem */ public void addLast(PathElement elem) { queue.addLast(elem); leadingParent &= elem.denotesParent(); isNormalized &= !elem.denotesCurrent() && (leadingParent || !elem.denotesParent()); } /** * Inserts the element at the end of the path to be built. * * @param name */ public void addLast(QName name) { addLast(PathElement.create(name)); } /** * Inserts the element at the end of the path to be built. * * @param name * @param index */ public void addLast(QName name, int index) { addLast(PathElement.create(name, index)); } /** * Assembles the built path and returns a new {@link Path}. * * @return a new {@link Path} * @throws MalformedPathException if the internal path element queue is empty. */ public Path getPath() throws MalformedPathException { PathElement[] elements = (PathElement[]) queue.toArray(new PathElement[queue.size()]); // validate path if (elements.length == 0) { throw new MalformedPathException("empty path"); } // no need to check the path format, assuming all names correct return new Path(elements, isNormalized); } } //---------------------------------------------< PathElement & subclasses > /** * Object representation of a single JCR path element. A PathElement * object contains the qualified name and optional index of a single * JCR path element. * <p/> * Once created, a PathElement object is immutable. */ public abstract static class PathElement implements Serializable { /** * Qualified name of the path element. */ private final QName name; /** * Optional index of the path element. Set to zero, if not * explicitly specified, otherwise contains the 1-based index. */ private final int index; /** * Private constructor for creating a path element with the given * qualified name and index. Instead of using this constructor directly * the factory methods {@link #create(QName)} and {@link #create(QName, int)} * should be used. * * @param name qualified name * @param index index */ private PathElement(QName name, int index) { this.index = index; this.name = name; } /** * Creates a path element with the given qualified name. * The created path element does not contain an explicit index. * <p/> * If the specified name denotes a <i>special</i> path element (either * {@link Path#PARENT_ELEMENT}, {@link Path#CURRENT_ELEMENT} or * {@link Path#ROOT_ELEMENT}) then the associated constant is returned. * * @param name the name of the element * @return a path element * @throws IllegalArgumentException if the name is <code>null</code> */ public static PathElement create(QName name) { if (name == null) { throw new IllegalArgumentException("name must not be null"); } else if (name.equals(PARENT_ELEMENT.getName())) { return PARENT_ELEMENT; } else if (name.equals(CURRENT_ELEMENT.getName())) { return CURRENT_ELEMENT; } else if (name.equals(ROOT_ELEMENT.getName())) { return ROOT_ELEMENT; } else { return new NameElement(name, INDEX_UNDEFINED); } } /** * Same as {@link #create(QName)} except that an explicit index can be * specified. * <p/> * Note that an IllegalArgumentException will be thrown if the specified * name denotes a <i>special</i> path element (either * {@link Path#PARENT_ELEMENT}, {@link Path#CURRENT_ELEMENT} or * {@link Path#ROOT_ELEMENT}) since an explicit index is not allowed * in this context. * * @param name the name of the element * @param index the 1-based index. * @return a path element * @throws IllegalArgumentException if the name is <code>null</code>, * if the given index is less than 1 * or if name denoting a special path * element and an index greater than 1 * have been specified. */ public static PathElement create(QName name, int index) { if (index < INDEX_DEFAULT) { throw new IllegalArgumentException("index is 1-based."); } else if (name == null) { throw new IllegalArgumentException("name must not be null"); } else if (name.equals(PARENT_ELEMENT.getName()) || name.equals(CURRENT_ELEMENT.getName()) || name.equals(ROOT_ELEMENT.getName())) { throw new IllegalArgumentException( "special path elements (root, '.' and '..') can not have an explicit index"); } else { return new NameElement(name, index); } } /** * Returns the qualified name of this path element. * * @return qualified name */ public QName getName() { return name; } /** * Returns the 1-based index or 0 if no index was specified (which is * equivalent to specifying 1). * * @return Returns the 1-based index or 0 if no index was specified. */ public int getIndex() { return index; } /** * Returns the normalized index of this path element, i.e. the index * is always equals or greater that {@link Path#INDEX_DEFAULT}. */ public int getNormalizedIndex() { if (index == INDEX_UNDEFINED) { return INDEX_DEFAULT; } else { return index; } } /** * Returns the JCR name representation of this path element. * Note that strictly speaking the returned value is in fact * a JCR relative path instead of a JCR name, as it contains * the index value if the index is greater than one. * * @param resolver namespace resolver * @return JCR name representation of the path element * @throws NoPrefixDeclaredException if the namespace of the path * element name can not be resolved */ public String toJCRName(NamespaceResolver resolver) throws NoPrefixDeclaredException { StringBuffer sb = new StringBuffer(); toJCRName(resolver, sb); return sb.toString(); } /** * Appends the JCR name representation of this path element to the * given string buffer. * * @param resolver namespace resolver * @param buf string buffer where the JCR name representation * should be appended to * @throws NoPrefixDeclaredException if the namespace of the path * element name can not be resolved * @see #toJCRName(NamespaceResolver) */ public void toJCRName(NamespaceResolver resolver, StringBuffer buf) throws NoPrefixDeclaredException { // name NameFormat.format(name, resolver, buf); // index int index = getIndex(); /** * FIXME the [1] subscript should only be suppressed if the item * in question can't have same-name siblings. */ //if (index > 0) { if (index > 1) { buf.append('['); buf.append(index); buf.append(']'); } } /** * Returns a string representation of this path element. Note that * the path element name is expressed using the <code>{uri}name</code> * syntax. Use the {@link #toJCRName(NamespaceResolver) toJCRName} * method to get the prefixed string representation of the path element. * * @return string representation of the path element * @see Object#toString() */ public String toString() { StringBuffer sb = new StringBuffer(); // name sb.append(name.toString()); // index int index = getIndex(); if (index > INDEX_UNDEFINED) { sb.append('['); sb.append(index); sb.append(']'); } return sb.toString(); } /** * Parses the given path element string into a path element object. * * @param s path element string * @return path element object * @throws IllegalArgumentException if the given path element string * is <code>null</code> or if its
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -