package eworks.RDF.model;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.Hashtable;
import eworks.RDF.util.UriFactory;

/**
 * <p>Represents an URI literal.</p>
 * 
 * @author Fabian Wleklinski (<a href="mailto:fabian@wleklinski.de">fabian@wleklinski.de</a>)
 * @version 1.00 (2003-11-03)
 */
public class UriLiteralValue extends LiteralValue {
	
	private static Hashtable namespaceCache = new Hashtable();

	private URI namespace;	
	private URI uri;
	private String localName;

	/**
	 * Creates a new instance representing the given URI literal <code>literal</code>.
	 * 
	 * @param literal The URI literal to use.
	 * @throws URISyntaxException if the given <code>literal</code> is no valid URI.
	 */
	public UriLiteralValue(String literal) throws URISyntaxException {
		super();
		
		this.uri = UriFactory.getURI(literal);
		
		// get local name
		String uriFragment = this.uri.getFragment();
		if (uriFragment == null)
			this.localName = literal;
		else
			this.localName = uriFragment;

		// get namespace
		if (uriFragment != null) {
			this.namespace = UriFactory.getURI(this.uri.getScheme() +
				":" + this.uri.getSchemeSpecificPart());
		}
	}

	/**
	 * Returns the encapsulated URI.
	 * 
	 * @return The encapsulated URI.
	 */	
	public URI getURI() {
		return this.uri;
	}
	
	/**
	 * Returns the URI's namespace component.
	 * 
	 * @return The URI's namespace component.
	 */
	public URI getNamespace() {
		return this.namespace;
	}

	/**
	 * Returns the URI's local name component.
	 * 
	 * @return The URI's local name component.
	 */
	public String getLocalName() { 
		return this.localName;
	}

	/**
	 * Returns the URI's string representation.
	 * 
	 * @return The URI's string representation.
	 */
	public String toString() {
		return this.uri.toString();
	}

	/**
	 * Returns the URI's hash code.
	 * 
	 * @return The URI's hash code.
	 */
	public int hashCode() {
		return this.uri.hashCode();
	}
	
	/**
	 * Checks if the URI is equal to a given object. To do so it is checked if the
	 * given object <code>o</code> is an instance of <code>UriLiteralValue</code>,
	 * too. If so, both encapsulated URIs are checked for equality. Otherwise the
	 * call is propagated to the inhertied implementation
	 * {@link LiteralValue#equals(Object)}.
	 * 
	 * @return <code>true</code> if and only if the URI is equal to <code>o</code>.
	 */
	public boolean equals( Object o ) {
		if (o instanceof UriLiteralValue) {
			return ((UriLiteralValue) o).uri.equals(this.uri);
		}
		return super.equals(o);
	}
}