package org.exist.collections;
/**
* URI to represent a Collection path internally in eXist
* */
public class CollectionURI
{
public final static char FRAGMENT_SEPARATOR = '/';
private char[] uri = null;
private int length = 0;
private int hash; // Default to 0
public CollectionURI(String path) {
// uri = new char[path.length()];
// path.getChars(0, path.length(), uri, 0);
// length = path.length();
append(path);
}
public CollectionURI(CollectionURI other) {
this.uri = new char[other.uri.length];
System.arraycopy(other.uri, 0, this.uri, 0, other.length);
this.length = other.length;
this.hash = other.hash;
}
public void append(final String segment)
{
int startOffset = 0;
if (segment.charAt(0) == FRAGMENT_SEPARATOR) {
startOffset = 1;
}
if(uri == null)
{
uri = new char[segment.length() + 1 - startOffset];
uri[0] = FRAGMENT_SEPARATOR;
segment.getChars(startOffset, segment.length(), uri, 1);
}
else
{
char newURI[] = new char[length + 1 + segment.length() - startOffset];
System.arraycopy(uri, 0, newURI, 0, length);
newURI[length] = FRAGMENT_SEPARATOR;
segment.getChars(startOffset, segment.length(), newURI, length+1);
uri = newURI;
}
length += segment.length() + 1 - startOffset;
//reset the cache
hash = 0;
}
public void removeLastSegment()
{
char c;
int pos = length - 1;
while((c = uri[pos]) != FRAGMENT_SEPARATOR)
{
pos--;
}
length = pos;
//reset the cache
hash = 0;
}
public String toString() {
return new String(uri, 0, length);
}
/**
* Copied from java.lang.String.hashCode();
*
* Returns a hash code for this string. The hash code for a
* <code>String</code> object is computed as
* <blockquote><pre>
* s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
* </pre></blockquote>
* using <code>int</code> arithmetic, where <code>s[i]</code> is the
* <i>i</i>th character of the string, <code>n</code> is the length of
* the string, and <code>^</code> indicates exponentiation.
* (The hash value of the empty string is zero.)
*
* @return a hash code value for this object.
*/
public int hashCode()
{
int h = hash;
if(h == 0)
{
int off = 0;
for(int i = 0; i < length; i++)
{
h = 31*h + uri[off++];
}
hash = h;
}
return h;
}
public boolean equals(Object object)
{
if(object instanceof CollectionURI)
{
CollectionURI otherCollectionURI = (CollectionURI)object;
if(this.length == otherCollectionURI.length)
{
int pos = length - 1;
while(pos > -1)
{
if(this.uri[pos] != otherCollectionURI.uri[pos--])
return false;
}
return true;
}
}
return false;
}
}