// $Id: DynamicModel.java,v 1.5 2002/02/03 10:32:42 mdean Exp $


package org.daml.jena;


public class DynamicModel
    extends com.hp.hpl.mesa.rdf.jena.mem.ModelMem
{
    /**
     * URLs that have been read into this model
     */
    java.util.TreeSet urls = new java.util.TreeSet();

    /**
     * should we dynamically load URIs (not thread safe)
     */
    public static boolean dynamic = true;

    public DynamicModel()
    {
	super();
    }

    /**
     * property to use for reifying the URI source of each statement.
     * If nil, the statement won't be reified.
     */
    public com.hp.hpl.mesa.rdf.jena.model.Property reificationSourceProperty = null;

    static class Resource
	extends com.hp.hpl.mesa.rdf.jena.common.ResourceImpl
    {
	Resource(String uri,
		 com.hp.hpl.mesa.rdf.jena.model.Model model)
	    throws com.hp.hpl.mesa.rdf.jena.model.RDFException
	{
	    super(uri, model);
	}

	Resource()
	{
	    super();
	}

	/**
	 * load the page containing this URI if it hasn't been loaded already
	 */
	void maybeLoad()
	    throws com.hp.hpl.mesa.rdf.jena.model.RDFException
	{
	    if (! dynamic)
		return;

	    String uri = getURI();
	    int hash = uri.lastIndexOf('#');
	    if (hash != (-1))
		uri = uri.substring(0, hash);
	    DynamicModel model = (DynamicModel) getModel(); 
	    if (! model.urls.contains(uri))
		{
		    System.out.println("dynamically reading " + uri); // XXX
		    model.read(uri);
		}
	}

	public com.hp.hpl.mesa.rdf.jena.model.StmtIterator listProperties()
	    throws com.hp.hpl.mesa.rdf.jena.model.RDFException
	{
	    maybeLoad();
	    return super.listProperties();
	}

	public com.hp.hpl.mesa.rdf.jena.model.StmtIterator listProperties(com.hp.hpl.mesa.rdf.jena.model.Property p)
	    throws com.hp.hpl.mesa.rdf.jena.model.RDFException
	{
	    maybeLoad();
	    return super.listProperties(p);
	}

	public com.hp.hpl.mesa.rdf.jena.model.Resource port(com.hp.hpl.mesa.rdf.jena.model.Model m)
	    throws com.hp.hpl.mesa.rdf.jena.model.RDFException
	{
	    if (getModel() == m)
		return this;
	    else return new Resource(getURI(), m);
	}
    }

    static class Property
	extends com.hp.hpl.mesa.rdf.jena.common.PropertyImpl
    {
	Property(String uri,
		 com.hp.hpl.mesa.rdf.jena.model.Model model)
	    throws com.hp.hpl.mesa.rdf.jena.model.RDFException
	{
	    super(uri, model);
	}

	Property(String namespace,
		 String localName,
		 com.hp.hpl.mesa.rdf.jena.model.Model model)
	    throws com.hp.hpl.mesa.rdf.jena.model.RDFException
	{
	    super(namespace, localName, model);
	}

	/**
	 * load the page containing this URI if it hasn't been loaded already
	 */
	void maybeLoad()
	    throws com.hp.hpl.mesa.rdf.jena.model.RDFException
	{
	    if (! dynamic)
		return;

	    String uri = getURI();
	    int hash = uri.lastIndexOf('#');
	    if (hash != (-1))
		uri = uri.substring(0, hash);
	    DynamicModel model = (DynamicModel) getModel(); 
	    if (! model.urls.contains(uri))
		{
		    System.out.println("dynamically reading " + uri); // XXX
		    model.read(uri);
		}
	}

	public com.hp.hpl.mesa.rdf.jena.model.StmtIterator listProperties()
	    throws com.hp.hpl.mesa.rdf.jena.model.RDFException
	{
	    maybeLoad();
	    return super.listProperties();
	}

	public com.hp.hpl.mesa.rdf.jena.model.StmtIterator listProperties(com.hp.hpl.mesa.rdf.jena.model.Property p)
	    throws com.hp.hpl.mesa.rdf.jena.model.RDFException
	{
	    maybeLoad();
	    return super.listProperties(p);
	}

	public com.hp.hpl.mesa.rdf.jena.model.Resource port(com.hp.hpl.mesa.rdf.jena.model.Model m)
	    throws com.hp.hpl.mesa.rdf.jena.model.RDFException
	{
	    if (getModel() == m)
		return this;
	    else return new Property(getURI(), m);
	}
    }

    public com.hp.hpl.mesa.rdf.jena.model.Model read(String url)
	throws com.hp.hpl.mesa.rdf.jena.model.RDFException
    {
	if (reificationSourceProperty == null)
	    super.read(url);
	else
	    {
		// com.hp.hpl.mesa.rdf.jena.model.Model newModel = new com.hp.hpl.mesa.rdf.jena.mem.ModelMem();
		DynamicModel newModel = new DynamicModel();
		newModel.read(url);
		this.add(newModel);
		com.hp.hpl.mesa.rdf.jena.model.StmtIterator statements = newModel.listStatements();
		while (statements.hasNext())
		    {
			com.hp.hpl.mesa.rdf.jena.model.Statement statement = statements.next();
			this.add(statement,
				 reificationSourceProperty,
				 url);
		    }
	    }
	urls.add(url);
	return this;
    }

    public com.hp.hpl.mesa.rdf.jena.model.Resource createResource(String uri)
	throws com.hp.hpl.mesa.rdf.jena.model.RDFException
    {
	return new Resource(uri, this);
    }

    public com.hp.hpl.mesa.rdf.jena.model.Resource getResource(String uri)
	throws com.hp.hpl.mesa.rdf.jena.model.RDFException
    {
	com.hp.hpl.mesa.rdf.jena.model.Resource retval = super.getResource(uri);
	if (retval instanceof Resource)
	    return retval;
	else
	    {
		System.out.println("getResource creating " + uri); // XXX
		return new Resource(uri, this);
	    }
    }

    public com.hp.hpl.mesa.rdf.jena.model.Property createProperty(String namespace,
								  String localName)
	throws com.hp.hpl.mesa.rdf.jena.model.RDFException
    {
	return new Property(namespace, localName, this);
    }

    public com.hp.hpl.mesa.rdf.jena.model.Property createProperty(String uri)
	throws com.hp.hpl.mesa.rdf.jena.model.RDFException
    {
	return new Property(uri, this);
    }
}
