Log in Help
Print
Homereleasesgate-5.1-beta2-build3402-ALLpluginsOntology_OWLIM2srcgatecreoleontologyowlim 〉 AbstractOWLIMOntologyImpl.java
 
/*
 *  AbstractOWLIMOntologyImpl.java
 *
 *  Niraj Aswani, 09/March/07
 *
 *  $Id: AbstractOWLIMOntologyImpl.java 11598 2009-10-13 13:44:17Z johann_p $
 */
package gate.creole.ontology.owlim;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Writer;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.openrdf.sesame.repository.SesameRepository;
import org.openrdf.vocabulary.XmlSchema;

import gate.creole.AbstractLanguageResource;
import gate.creole.ontology.AllValuesFromRestriction;
import gate.creole.ontology.AnnotationProperty;
import gate.creole.ontology.AnonymousClass;
import gate.creole.ontology.CardinalityRestriction;
import gate.creole.ontology.DataType;
import gate.creole.ontology.DatatypeProperty;
import gate.creole.ontology.HasValueRestriction;
import gate.creole.ontology.InvalidValueException;
import gate.creole.ontology.Literal;
import gate.creole.ontology.MaxCardinalityRestriction;
import gate.creole.ontology.MinCardinalityRestriction;
import gate.creole.ontology.OClass;
import gate.creole.ontology.OConstants;
import gate.creole.ontology.OConstants.Closure;
import gate.creole.ontology.OConstants.OntologyFormat;
import gate.creole.ontology.OConstants.QueryLanguage;
import gate.creole.ontology.OInstance;
import gate.creole.ontology.OResource;
import gate.creole.ontology.OURI;
import gate.creole.ontology.ONodeID;
import gate.creole.ontology.ObjectProperty;
import gate.creole.ontology.Ontology;
import gate.creole.ontology.OntologyBooleanQuery;
import gate.creole.ontology.OntologyModificationListener;
import gate.creole.ontology.OntologyTupleQuery;
import gate.creole.ontology.RDFProperty;
import gate.creole.ontology.SomeValuesFromRestriction;
import gate.creole.ontology.SymmetricProperty;
import gate.creole.ontology.TransitiveProperty;
import gate.creole.ontology.URI;
import gate.util.ClosableIterator;
import java.io.InputStream;
import java.io.Reader;

/**
 * This class provides implementation of most of the methods of Ontology
 * interface. This implementation is based on the OWLIM (a SAIL) that stores
 * data in repository using SESAME.
 * 
 * @author niraj
 * 
 */
public abstract class AbstractOWLIMOntologyImpl
                                               extends
                                                 AbstractLanguageResource
                                                                         implements
                                                                         Ontology {
  /**
   * ID of the repository
   */
  protected String sesameRepositoryID;

  /**
   * instance of the OWLIM
   */
  protected OWLIM owlim;

  /**
   * URL of the ontology
   */
  protected URL ontologyURL;

  /**
   * Ontology Format
   */
  protected byte format;

  /**
   * Default Namespace
   */
  protected String defaultNameSpace;

  /**
   * Parameter that keeps track of if the ontology is modified
   */
  protected boolean isModified;

  /**
   * A List of ontology modification listeners
   */
  protected transient List<OntologyModificationListener> modificationListeners;

  /**
   * Indicates whether the data in repository should be persisted
   */
  protected Boolean persistRepository;

  /**
   * A Map that keeps record of resources given their uris
   */
  protected Map<String, OResource> urisToOResouceMap;

  /**
   * Map where the key is a resource name and value is a list of resources with
   * that name.
   */
  protected Map<String, List<OResource>> resourceNamesToOResourcesMap;

  protected static int anonymousNodeCounter = 0;

  protected static String restrictionPrefix = "Restriction";

  /**
   * Constructor
   */
  public AbstractOWLIMOntologyImpl() {
    urisToOResouceMap = new HashMap<String, OResource>();
    resourceNamesToOResourcesMap = new HashMap<String, List<OResource>>();
    persistRepository = new Boolean(false);
  }

  public String getAutoGeneratedRestrictionName() {
    String toReturn = null;
    while(true) {
      anonymousNodeCounter++;
      toReturn = restrictionPrefix + anonymousNodeCounter;
      List<OResource> resources = resourceNamesToOResourcesMap.get(toReturn);
      if(resources == null || resources.isEmpty()) break;
    }
    return toReturn;
  }

  /*
   * (non-Javadoc)
   * 
   * @see gate.creole.ontology.Ontology#cleanOntology()
   */
  public void cleanOntology() {
    owlim.cleanOntology(sesameRepositoryID);
    urisToOResouceMap.clear();
    resourceNamesToOResourcesMap.clear();
    if(!callFromCleanup)
      fireOntologyReset();
    else callFromCleanup = false;
  }

  /*
   * (non-Javadoc)
   * 
   * @see gate.creole.ontology.Ontology#getOntologyData(byte)
   */
  public String getOntologyData(byte format) {
    return owlim.getOntologyData(sesameRepositoryID, format);
  }

  /*
   * (non-Javadoc)
   * 
   * @see gate.creole.ontology.Ontology#writeOntologyData(java.io.OutputStream,
   * byte)
   */
  public abstract void writeOntologyData(OutputStream out, byte format);

  /*
   * (non-Javadoc)
   * 
   * @see gate.creole.ontology.Ontology#writeOntologyData(java.io.Writer, byte)
   */
  public abstract void writeOntologyData(Writer out, byte format);

  /*
   * (non-Javadoc)
   * 
   * @see gate.creole.ontology.Ontology#getURL()
   */
  public URL getURL() {
    return ontologyURL;
  }

  /*
   * (non-Javadoc)
   * 
   * @see gate.creole.ontology.Ontology#setURL(java.net.URL)
   */
  public void setURL(URL aUrl) {
    this.ontologyURL = aUrl;
  }

  /*
   * (non-Javadoc)
   * 
   * @see
   * gate.creole.ontology.Ontology#setDefaultNameSpace(gate.creole.ontology.URI)
   */
  public void setDefaultNameSpace(String theURI) {
    defaultNameSpace = theURI;
    if(defaultNameSpace != null && -1 == defaultNameSpace.indexOf('#')) {
      defaultNameSpace = defaultNameSpace + '#';
    }
  }

  /*
   * (non-Javadoc)
   * 
   * @see gate.creole.ontology.Ontology#getDefaultNameSpace()
   */
  public String getDefaultNameSpace() {
    return this.defaultNameSpace;
  }

  /*
   * (non-Javadoc)
   * 
   * @see gate.creole.ontology.Ontology#setVersion(java.lang.String)
   */
  public void setVersion(String theVersion) {
    owlim.setVersion(sesameRepositoryID, theVersion);
  }

  /*
   * (non-Javadoc)
   * 
   * @see gate.creole.ontology.Ontology#getVersion()
   */
  public String getVersion() {
    return owlim.getVersion(sesameRepositoryID);
  }

  /*
   * (non-Javadoc)
   * 
   * @see gate.creole.ontology.Ontology#addOClass(gate.creole.ontology.URI)
   */
  public OClass addOClass(OURI aURI, byte classType) {
    OResource resource = getOResourceFromMap(aURI.toString());
    if(resource != null) { return (OClass)resource; }
    owlim.addClass(this.sesameRepositoryID, aURI.toString(), classType);
    OClass oClass =
      Utils.createOClass(this.sesameRepositoryID, this, owlim, aURI.toString(),
        classType);

    fireOntologyResourceAdded(oClass);

    // we need to add a label on this but only after the new class
    // addition event has been fired
    oClass.setLabel(aURI.getResourceName(), null);
    return oClass;
  }

  /*
   * (non-Javadoc)
   * 
   * @see gate.creole.ontology.Ontology#addOClass(gate.creole.ontology.URI,
   * byte)
   */
  public OClass addOClass(OURI aURI) {
    return addOClass(aURI, OConstants.OWL_CLASS);
  }

  /*
   * (non-Javadoc)
   * 
   * @see gate.creole.ontology.Ontology#getOClass(gate.creole.ontology.URI)
   */
  public OClass getOClass(ONodeID theClassURI) {
    OResource resource = getOResourceFromMap(theClassURI.toString());
    if(resource != null) { return (OClass)resource; }
    if(owlim.hasClass(this.sesameRepositoryID, theClassURI.toString())) {
      byte classType =
        owlim.getClassType(this.sesameRepositoryID, theClassURI.toString());
      return Utils.createOClass(this.sesameRepositoryID, this, owlim,
        theClassURI.toString(), classType);
    }
    return null;
  }

  /*
   * (non-Javadoc)
   * 
   * @see
   * gate.creole.ontology.Ontology#removeOClass(gate.creole.ontology.OClass)
   */
  public void removeOClass(OClass theClass) {

    if(!containsOClass(theClass.getURI())) {
      Utils.warning(theClass.getURI().toString() + " does not exist");
      return;
    }

    String[] deletedResources =
      owlim.removeClass(this.sesameRepositoryID, theClass.getURI().toString(),
        true);
    fireOntologyResourcesRemoved(deletedResources);
  }

  /*
   * (non-Javadoc)
   * 
   * @see gate.creole.ontology.Ontology#containsOClass(gate.creole.ontology.URI)
   */
  public boolean containsOClass(ONodeID theURI) {
    return owlim.hasClass(this.sesameRepositoryID, theURI.toString());
  }

  /*
   * (non-Javadoc)
   * 
   * @see
   * gate.creole.ontology.Ontology#containsOClass(gate.creole.ontology.OClass)
   */
  public boolean containsOClass(OClass theClass) {
    return containsOClass(theClass.getURI());
  }

  /*
   * (non-Javadoc)
   * 
   * @see gate.creole.ontology.Ontology#getOClasses(boolean)
   */
  public Set<OClass> getOClasses(boolean top) {
    ResourceInfo[] oClasses = owlim.getClasses(this.sesameRepositoryID, top);
    Set<OClass> set = new HashSet<OClass>();
    for(int i = 0; i < oClasses.length; i++) {
      set.add(Utils.createOClass(this.sesameRepositoryID, this, this.owlim,
        oClasses[i].getUri(), oClasses[i].getClassType()));
    }
    return set;
  }

  /*
   * (non-Javadoc)
   * 
   * @see gate.creole.ontology.Ontology#getDistance(gate.creole.ontology.OClass,
   * gate.creole.ontology.OClass)
   */
  public int getDistance(OClass class1, OClass class2) {

    if(!containsOClass(class1.getURI())) {
      Utils.warning(class1.getURI().toString() + " does not exist");
      return -1;
    }

    if(!containsOClass(class2.getURI())) {
      Utils.warning(class2.getURI().toString() + " does not exist");
      return -1;
    }

    int result = 0;
    OClass c;
    ArrayList<Set<OClass>> supers1 = class1.getSuperClassesVSDistance();
    ArrayList<Set<OClass>> supers2 = class2.getSuperClassesVSDistance();
    for(int i1 = 0; i1 < supers1.size(); i1++) {
      if(supers1.get(i1).contains(class2)) {
        result = i1 + 1;
        break;
      }
    }
    for(int i2 = 0; i2 < supers2.size(); i2++) {
      if(supers2.get(i2).contains(class1)) {
        result = i2 + 1;
        break;
      }
    }
    if(0 == result) {
      for(int i1 = 0; i1 < supers1.size(); i1++) {
        for(int i2 = 0; i2 < supers2.size(); i2++) {
          Set<OClass> s1 = supers1.get(i1);
          Set<OClass> s2 = supers2.get(i2);
          Iterator<OClass> i3 = s1.iterator();
          while(i3.hasNext()) {
            c = i3.next();
            if(s2.contains(c)) {
              result = i1 + i2 + 2;
              i1 = supers1.size();
              i2 = supers2.size();
              break;
            }
          }
        }
      }
    }
    return result;
  }

  /*
   * (non-Javadoc)
   * 
   * @see gate.creole.ontology.Ontology#addOInstance(gate.creole.ontology.URI,
   * gate.creole.ontology.OClass)
   */
  public OInstance addOInstance(OURI theInstanceURI, OClass theClass) {
    if(!containsOClass(theClass.getURI())) {
      Utils.error(theClass.getURI().toString() + " does not exist");
      return null;
    }

    OResource anInst = getOResourceFromMap(theInstanceURI.toString());
    if(anInst != null && !(anInst instanceof OInstance)) {
      Utils.error(anInst.getURI().toString() + " already exists but "
        + " is not an ontology instance!");
      return null;
    }

    if(anInst != null
      && ((OInstance)anInst).getOClasses(OConstants.TRANSITIVE_CLOSURE)
        .contains(theClass)) {
      Utils.warning(theInstanceURI.toString()
        + " is already registered as an instanceof "
        + theClass.getURI().toString());
      return (OInstance)anInst;
    }

    owlim.addIndividual(this.sesameRepositoryID, theClass.getURI().toString(),
      theInstanceURI.toString());
    OInstance oInst =
      Utils.createOInstance(this.sesameRepositoryID, this, owlim,
        theInstanceURI.toString());
    fireOntologyResourceAdded(oInst);

    // we need to add a label on this but after the new class addition
    // event has been fired
    oInst.setLabel(theInstanceURI.getResourceName(), null);

    return oInst;
  }

  /*
   * (non-Javadoc)
   * 
   * @see
   * gate.creole.ontology.Ontology#removeOInstance(gate.creole.ontology.OInstance
   * )
   */
  public void removeOInstance(OInstance theInstance) {
    if(!containsOInstance(theInstance.getURI())) {
      Utils.warning(theInstance.getURI().toString() + " does not exist");
      return;
    }

    String[] deletedResources =
      owlim.removeIndividual(this.sesameRepositoryID, theInstance.getURI()
        .toString());
    fireOntologyResourcesRemoved(deletedResources);
  }

  /*
   * (non-Javadoc)
   * 
   * @see gate.creole.ontology.Ontology#getOInstances()
   */
  public Set<OInstance> getOInstances() {
    String[] oInsts = owlim.getIndividuals(this.sesameRepositoryID);
    Set<OInstance> set = new HashSet<OInstance>();
    for(int i = 0; i < oInsts.length; i++) {
      set.add(Utils.createOInstance(this.sesameRepositoryID, this, this.owlim,
        oInsts[i]));
    }
    return set;
  }

  public ClosableIterator<OInstance> getOInstancesIterator() {
    throw new UnsupportedOperationException("Not supported in this implementation");
  }

  /*
   * (non-Javadoc)
   * 
   * @see
   * gate.creole.ontology.Ontology#getOInstances(gate.creole.ontology.OClass,
   * boolean)
   */
  public Set<OInstance> getOInstances(OClass theClass, Closure closure) {
    throw new UnsupportedOperationException("Not supported in this implementation");
  }

  public ClosableIterator<OInstance>
      getOInstancesIterator(OClass theClass, Closure closure) {
    throw new UnsupportedOperationException("Not supported in this implementation");
  }
  public Set<OInstance> getOInstances(OClass theClass, byte closure) {
    String[] oInsts =
      owlim.getIndividuals(this.sesameRepositoryID, theClass.getURI()
        .toString(), closure);
    Set<OInstance> set = new HashSet<OInstance>();

    if(!containsOClass(theClass.getURI())) {
      Utils.warning(theClass.getURI().toString() + " does not exist");
      return set;
    }

    for(int i = 0; i < oInsts.length; i++) {
      set.add(Utils.createOInstance(this.sesameRepositoryID, this, this.owlim,
        oInsts[i]));
    }
    return set;
  }

  /*
   * (non-Javadoc)
   * 
   * @see gate.creole.ontology.Ontology#getOInstance(gate.creole.ontology.URI)
   */
  public OInstance getOInstance(OURI theInstanceURI) {
    OResource resource = getOResourceFromMap(theInstanceURI.toString());
    if(resource != null) return (OInstance)resource;
    List<String> individuals =
      Arrays.asList(owlim.getIndividuals(this.sesameRepositoryID));
    if(individuals.contains(theInstanceURI.toString())) { return Utils
      .createOInstance(this.sesameRepositoryID, this, owlim, theInstanceURI
        .toString()); }
    return null;
  }

  /*
   * (non-Javadoc)
   * 
   * @see
   * gate.creole.ontology.Ontology#containsOInstance(gate.creole.ontology.OInstance
   * )
   */
  public boolean containsOInstance(OInstance theInstance) {
    return containsOInstance(theInstance.getURI());
  }

  /*
   * (non-Javadoc)
   * 
   * @see
   * gate.creole.ontology.Ontology#containsOInstance(gate.creole.ontology.URI)
   */
  public boolean containsOInstance(OURI theInstanceURI) {
    List<String> individuals =
      Arrays.asList(owlim.getIndividuals(this.sesameRepositoryID));
    return individuals.contains(theInstanceURI.toString());
  }

  /*
   * (non-Javadoc)
   * 
   * @see gate.creole.ontology.Ontology#addRDFProperty(gate.creole.ontology.URI,
   * java.util.Set, java.util.Set)
   */
  public RDFProperty addRDFProperty(OURI aPropertyURI, Set<OResource> domain,
    Set<OResource> range) {
    OResource res = getOResourceFromMap(aPropertyURI.toString());
    if(res != null) {
      if(res instanceof RDFProperty) {
        Utils.warning(aPropertyURI.toString() + " already exists");
        return (RDFProperty)res;
      }
      else {
        Utils.error(aPropertyURI.toString()
          + " already exists but it is not an RDFProperty");
        return null;
      }
    }

    String[] domainURIs = new String[domain.size()];
    String[] rangeURIs = new String[range.size()];
    Iterator<OResource> iter = domain.iterator();
    int counter = 0;
    while(iter.hasNext()) {
      domainURIs[counter] = iter.next().getURI().toString();
    }
    iter = range.iterator();
    counter = 0;
    while(iter.hasNext()) {
      rangeURIs[counter] = iter.next().getURI().toString();
    }
    owlim.addRDFProperty(this.sesameRepositoryID, aPropertyURI.toString(),
      domainURIs, rangeURIs);
    RDFProperty rp =
      Utils.createOProperty(this.sesameRepositoryID, this, owlim, aPropertyURI
        .toString(), OConstants.RDF_PROPERTY);
    fireOntologyResourceAdded(rp);

    // we need to add a label on this but after the new resource
    // addition event has been fired
    rp.setLabel(aPropertyURI.getResourceName(), null);

    return rp;
  }

  /*
   * (non-Javadoc)
   * 
   * @see gate.creole.ontology.Ontology#getRDFProperties()
   */
  public Set<RDFProperty> getRDFProperties() {
    Property[] properties = owlim.getRDFProperties(this.sesameRepositoryID);
    Set<RDFProperty> set = new HashSet<RDFProperty>();
    for(int i = 0; i < properties.length; i++) {
      set.add((RDFProperty)Utils.createOProperty(this.sesameRepositoryID, this,
        owlim, properties[i].getUri(), properties[i].getType()));
    }
    return set;
  }

  /*
   * (non-Javadoc)
   * 
   * @see gate.creole.ontology.Ontology#isRDFProperty(gate.creole.ontology.URI)
   */
  public boolean isRDFProperty(OURI thePropertyURI) {
    return owlim.isRDFProperty(this.sesameRepositoryID, thePropertyURI
      .toString());
  }

  /*
   * (non-Javadoc)
   * 
   * @see
   * gate.creole.ontology.Ontology#addAnnotationProperty(gate.creole.ontology
   * .URI)
   */
  public AnnotationProperty addAnnotationProperty(OURI aPropertyURI) {
    OResource res = getOResourceFromMap(aPropertyURI.toString());
    if(res != null) {
      if(res instanceof AnnotationProperty) {
        Utils.warning(aPropertyURI.toString() + " already exists");
        return (AnnotationProperty)res;
      }
      else {
        Utils.error(aPropertyURI.toString()
          + " already exists but it is not an AnnotationProperty");
        return null;
      }
    }

    owlim.addAnnotationProperty(this.sesameRepositoryID, aPropertyURI
      .toString());
    AnnotationProperty ap =
      (AnnotationProperty)Utils.createOProperty(this.sesameRepositoryID, this,
        owlim, aPropertyURI.toString(), OConstants.ANNOTATION_PROPERTY);
    fireOntologyResourceAdded(ap);

    // we need to add a label on this but after the new resource
    // addition event has been fired
    ap.setLabel(aPropertyURI.getResourceName(), null);

    return ap;
  }

  /*
   * (non-Javadoc)
   * 
   * @see gate.creole.ontology.Ontology#getAnnotationProperties()
   */
  public Set<AnnotationProperty> getAnnotationProperties() {
    Property[] properties =
      owlim.getAnnotationProperties(this.sesameRepositoryID);
    Set<AnnotationProperty> set = new HashSet<AnnotationProperty>();
    for(int i = 0; i < properties.length; i++) {
      set.add((AnnotationProperty)Utils.createOProperty(
        this.sesameRepositoryID, this, owlim, properties[i].getUri(),
        properties[i].getType()));
    }
    return set;
  }

  /*
   * (non-Javadoc)
   * 
   * @see
   * gate.creole.ontology.Ontology#isAnnotationProperty(gate.creole.ontology
   * .URI)
   */
  public boolean isAnnotationProperty(OURI thePropertyURI) {
    return owlim.isAnnotationProperty(this.sesameRepositoryID, thePropertyURI
      .toString());
  }

  /*
   * (non-Javadoc)
   * 
   * @see
   * gate.creole.ontology.Ontology#addDatatypeProperty(gate.creole.ontology.URI,
   * java.util.Set, gate.creole.ontology.DataType)
   */
  public DatatypeProperty addDatatypeProperty(OURI aPropertyURI,
    Set<OClass> domain, DataType aDatatype) {
    OResource res = getOResourceFromMap(aPropertyURI.toString());
    if(res != null) {
      if(res instanceof DatatypeProperty) {
        Utils.warning(aPropertyURI.toString() + " already exists");
        return (DatatypeProperty)res;
      }
      else {
        Utils.error(aPropertyURI.toString()
          + " already exists but it is not a DatatypeProperty");
        return null;
      }
    }

    String[] domainURIs = new String[domain.size()];
    Iterator<OClass> iter = domain.iterator();
    int counter = 0;
    while(iter.hasNext()) {
      domainURIs[counter] = iter.next().getURI().toString();
    }
    owlim.addDataTypeProperty(this.sesameRepositoryID, aPropertyURI.toString(),
      domainURIs, aDatatype.getXmlSchemaURIString());
    DatatypeProperty dp =
      (DatatypeProperty)Utils.createOProperty(this.sesameRepositoryID, this,
        owlim, aPropertyURI.toString(), OConstants.DATATYPE_PROPERTY);
    fireOntologyResourceAdded(dp);

    // we need to add a label on this but after the new resource
    // addition event has been fired
    dp.setLabel(aPropertyURI.getResourceName(), null);

    return dp;
  }

  /*
   * (non-Javadoc)
   * 
   * @see gate.creole.ontology.Ontology#getDatatypeProperties()
   */
  public Set<DatatypeProperty> getDatatypeProperties() {
    Property[] properties =
      owlim.getDatatypeProperties(this.sesameRepositoryID);
    Set<DatatypeProperty> set = new HashSet<DatatypeProperty>();
    for(int i = 0; i < properties.length; i++) {
      set.add((DatatypeProperty)Utils.createOProperty(this.sesameRepositoryID,
        this, owlim, properties[i].getUri(), properties[i].getType()));
    }
    return set;
  }

  /*
   * (non-Javadoc)
   * 
   * @see
   * gate.creole.ontology.Ontology#isDatatypeProperty(gate.creole.ontology.URI)
   */
  public boolean isDatatypeProperty(OURI thePropertyURI) {
    return owlim.isDatatypeProperty(this.sesameRepositoryID, thePropertyURI
      .toString());
  }

  /*
   * (non-Javadoc)
   * 
   * @see
   * gate.creole.ontology.Ontology#addObjectProperty(gate.creole.ontology.URI,
   * java.util.Set, java.util.Set)
   */
  public ObjectProperty addObjectProperty(OURI aPropertyURI, Set<OClass> domain,
    Set<OClass> range) {
    OResource res = getOResourceFromMap(aPropertyURI.toString());
    if(res != null) {
      if(res instanceof ObjectProperty) {
        Utils.warning(aPropertyURI.toString() + " already exists");
        return (ObjectProperty)res;
      }
      else {
        Utils.error(aPropertyURI.toString()
          + " already exists but it is not an ObjectProperty");
        return null;
      }
    }

    String[] domainURIs = new String[domain.size()];
    String[] rangeURIs = new String[range.size()];
    Iterator<OClass> iter = domain.iterator();
    int counter = 0;
    while(iter.hasNext()) {
      domainURIs[counter] = iter.next().getURI().toString();
      counter++;
    }
    iter = range.iterator();
    counter = 0;
    while(iter.hasNext()) {
      rangeURIs[counter] = iter.next().getURI().toString();
      counter++;
    }
    owlim.addObjectProperty(this.sesameRepositoryID, aPropertyURI.toString(),
      domainURIs, rangeURIs);
    ObjectProperty op =
      (ObjectProperty)Utils.createOProperty(this.sesameRepositoryID, this,
        owlim, aPropertyURI.toString(), OConstants.OBJECT_PROPERTY);
    fireOntologyResourceAdded(op);

    // we need to add a label on this but after the new resource
    // addition event has been fired
    op.setLabel(aPropertyURI.getResourceName(), null);

    return op;
  }

  /*
   * (non-Javadoc)
   * 
   * @see gate.creole.ontology.Ontology#getObjectProperties()
   */
  public Set<ObjectProperty> getObjectProperties() {
    Property[] properties = owlim.getObjectProperties(this.sesameRepositoryID);
    Set<ObjectProperty> set = new HashSet<ObjectProperty>();
    for(int i = 0; i < properties.length; i++) {
      set.add((ObjectProperty)Utils.createOProperty(this.sesameRepositoryID,
        this, owlim, properties[i].getUri(), properties[i].getType()));
    }
    return set;
  }

  /*
   * (non-Javadoc)
   * 
   * @see
   * gate.creole.ontology.Ontology#isObjectProperty(gate.creole.ontology.URI)
   */
  public boolean isObjectProperty(OURI thePropertyURI) {
    return owlim.isObjectProperty(this.sesameRepositoryID, thePropertyURI
      .toString());
  }

  /*
   * (non-Javadoc)
   * 
   * @see
   * gate.creole.ontology.Ontology#addSymmetricProperty(gate.creole.ontology
   * .URI, java.util.Set)
   */
  public SymmetricProperty addSymmetricProperty(OURI aPropertyURI,
    Set<OClass> domainAndRange) {
    OResource res = getOResourceFromMap(aPropertyURI.toString());
    if(res != null) {
      if(res instanceof SymmetricProperty) {
        Utils.warning(aPropertyURI.toString() + " already exists");
        return (SymmetricProperty)res;
      }
      else {
        Utils.error(aPropertyURI.toString()
          + " already exists but it is not an SymmetricProperty");
        return null;
      }
    }

    String[] domainURIs = new String[domainAndRange.size()];
    Iterator<OClass> iter = domainAndRange.iterator();
    int counter = 0;
    while(iter.hasNext()) {
      domainURIs[counter] = iter.next().getURI().toString();
      counter++;
    }
    owlim.addSymmetricProperty(this.sesameRepositoryID,
      aPropertyURI.toString(), domainURIs);
    SymmetricProperty sp =
      (SymmetricProperty)Utils.createOProperty(this.sesameRepositoryID, this,
        owlim, aPropertyURI.toString(), OConstants.SYMMETRIC_PROPERTY);
    fireOntologyResourceAdded(sp);

    // we need to add a label on this but after the new resource
    // addition event has been fired
    sp.setLabel(aPropertyURI.getResourceName(), null);

    return sp;
  }

  /*
   * (non-Javadoc)
   * 
   * @see gate.creole.ontology.Ontology#getSymmetricProperties()
   */
  public Set<SymmetricProperty> getSymmetricProperties() {
    Property[] properties =
      owlim.getSymmetricProperties(this.sesameRepositoryID);
    Set<SymmetricProperty> set = new HashSet<SymmetricProperty>();
    for(int i = 0; i < properties.length; i++) {
      set.add((SymmetricProperty)Utils.createOProperty(this.sesameRepositoryID,
        this, owlim, properties[i].getUri(), properties[i].getType()));
    }
    return set;
  }

  /*
   * (non-Javadoc)
   * 
   * @see
   * gate.creole.ontology.Ontology#isSymmetricProperty(gate.creole.ontology.URI)
   */
  public boolean isSymmetricProperty(OURI thePropertyURI) {
    return owlim.isSymmetricProperty(this.sesameRepositoryID, thePropertyURI
      .toString());
  }

  /*
   * (non-Javadoc)
   * 
   * @see
   * gate.creole.ontology.Ontology#addTransitiveProperty(gate.creole.ontology
   * .URI, java.util.Set, java.util.Set)
   */
  public TransitiveProperty addTransitiveProperty(OURI aPropertyURI,
    Set<OClass> domain, Set<OClass> range) {
    OResource res = getOResourceFromMap(aPropertyURI.toString());
    if(res != null) {
      if(res instanceof TransitiveProperty) {
        Utils.warning(aPropertyURI.toString() + " already exists");
        return (TransitiveProperty)res;
      }
      else {
        Utils.error(aPropertyURI.toString()
          + " already exists but it is not a TransitiveProperty");
        return null;
      }
    }

    String[] domainURIs = new String[domain.size()];
    String[] rangeURIs = new String[range.size()];
    Iterator<OClass> iter = domain.iterator();
    int counter = 0;
    while(iter.hasNext()) {
      domainURIs[counter] = iter.next().getURI().toString();
      counter++;
    }
    iter = range.iterator();
    counter = 0;
    while(iter.hasNext()) {
      rangeURIs[counter] = iter.next().getURI().toString();
      counter++;
    }
    owlim.addTransitiveProperty(this.sesameRepositoryID, aPropertyURI
      .toString(), domainURIs, rangeURIs);
    TransitiveProperty tp =
      (TransitiveProperty)Utils.createOProperty(this.sesameRepositoryID, this,
        owlim, aPropertyURI.toString(), OConstants.TRANSITIVE_PROPERTY);
    fireOntologyResourceAdded(tp);

    // we need to add a label on this but after the new resource
    // addition event has been fired
    tp.setLabel(aPropertyURI.getResourceName(), null);

    return tp;
  }

  /*
   * (non-Javadoc)
   * 
   * @see gate.creole.ontology.Ontology#getTransitiveProperties()
   */
  public Set<TransitiveProperty> getTransitiveProperties() {
    Property[] properties =
      owlim.getTransitiveProperties(this.sesameRepositoryID);
    Set<TransitiveProperty> set = new HashSet<TransitiveProperty>();
    for(int i = 0; i < properties.length; i++) {

      set.add((TransitiveProperty)Utils.createOProperty(
        this.sesameRepositoryID, this, owlim, properties[i].getUri(),
        properties[i].getType()));
    }
    return set;
  }

  /*
   * (non-Javadoc)
   * 
   * @see
   * gate.creole.ontology.Ontology#isTransitiveProperty(gate.creole.ontology
   * .URI)
   */
  public boolean isTransitiveProperty(OURI thePropertyURI) {
    return owlim.isTransitiveProperty(this.sesameRepositoryID, thePropertyURI
      .toString());
  }

  /*
   * (non-Javadoc)
   * 
   * @see gate.creole.ontology.Ontology#getPropertyDefinitions()
   */
  public Set<RDFProperty> getPropertyDefinitions() {
    Set<RDFProperty> set = new HashSet<RDFProperty>();
    set.addAll(getAnnotationProperties());
    set.addAll(getDatatypeProperties());
    set.addAll(getObjectProperties());
    set.addAll(getRDFProperties());
    return set;
  }

  /*
   * (non-Javadoc)
   * 
   * @see gate.creole.ontology.Ontology#getProperty(gate.creole.ontology.URI)
   */
  public RDFProperty getProperty(OURI thePropertyURI) {
    Property property =
      owlim.getPropertyFromOntology(this.sesameRepositoryID, thePropertyURI
        .toString());
    if(property == null) return null;
    return Utils.createOProperty(this.sesameRepositoryID, this, owlim,
      thePropertyURI.toString(), property.getType());
  }

  public AnnotationProperty getAnnotationProperty(OURI theURI) {
    if(owlim.isAnnotationProperty(this.sesameRepositoryID, theURI.toString())) {
      return (AnnotationProperty) Utils.createOProperty(this.sesameRepositoryID,
          this,owlim,
          theURI.toString(), OConstants.ANNOTATION_PROPERTY);
    } else {
      return null;
    }
  }
  public DatatypeProperty getDatatypeProperty(OURI theURI) {
    if(owlim.isDatatypeProperty(this.sesameRepositoryID, theURI.toString())) {
      return (DatatypeProperty) Utils.createOProperty(this.sesameRepositoryID, this,owlim,
          theURI.toString(), OConstants.DATATYPE_PROPERTY);
    } else {
      return null;
    }
  }
  public ObjectProperty getObjectProperty(OURI theURI) {
    if(owlim.isObjectProperty(this.sesameRepositoryID,theURI.toString())) {
      return (ObjectProperty) Utils.createOProperty(this.sesameRepositoryID,this,owlim,
          theURI.toString(), OConstants.OBJECT_PROPERTY);
    } else {
      return null;
    }
  }



  /*
   * (non-Javadoc)
   * 
   * @see
   * gate.creole.ontology.Ontology#removeProperty(gate.creole.ontology.RDFProperty
   * )
   */
  public void removeProperty(RDFProperty theProperty) {
    OResource res = getOResourceFromMap(theProperty.getURI().toString());
    if(res == null) {
      Utils.warning(theProperty.getURI().toString() + " does not exist");
      return;
    }

    String[] deletedResources =
      owlim.removePropertyFromOntology(this.sesameRepositoryID, theProperty
        .getURI().toString(), true);
    fireOntologyResourcesRemoved(deletedResources);
  }

  /**
   * Adds a new MinCardinality Restriction to the ontology. It automatically
   * creates a randon anonymous class, which it uses to denote the restriction.
   * The default datatype is set to NonNegativeIntegerNumber
   * 
   * @param onProperty
   *          - Specifies the property for which the restriction is being set.
   * @param minCardinalityValue
   *          - generally a numeric number.
   * @return
   * @throws InvalidValueException
   *           - if a value is not compatible with the nonNegativeIntegerNumber
   *           datatype.
   */
  public MinCardinalityRestriction addMinCardinalityRestriction(
    RDFProperty onProperty, String minCardinalityValue)
    throws InvalidValueException {
    String restId = getAutoGeneratedRestrictionName();
    DataType datatype =
      OntologyUtilities.getDataType(XmlSchema.NON_NEGATIVE_INTEGER);

    owlim.addClass(this.sesameRepositoryID, restId,
      OConstants.MIN_CARDINALITY_RESTRICTION);

    owlim.setOnPropertyValue(this.sesameRepositoryID, restId, onProperty
      .getURI().toString());

    if(!datatype.isValidValue(minCardinalityValue))
      throw new InvalidValueException(minCardinalityValue
        + " is not valid for datatype " + datatype.getXmlSchemaURIString());

    owlim.setPropertyValue(this.sesameRepositoryID, restId,
      OConstants.MIN_CARDINALITY_RESTRICTION, minCardinalityValue, datatype
        .getXmlSchemaURIString());

    MinCardinalityRestriction mcr =
      (MinCardinalityRestriction)Utils.createOClass(this.sesameRepositoryID,
        this, owlim, restId, OConstants.MIN_CARDINALITY_RESTRICTION);

    fireOntologyResourceAdded(mcr);
    return mcr;
  }

  /**
   * Adds a new MaxCardinality Restriction to the ontology. It automatically
   * creates a randon anonymous class, which it uses to denote the restriction.
   * The default datatype is set to NonNegativeIntegerNumber
   * 
   * @param onProperty
   *          - Specifies the property for which the restriction is being set.
   * @param maxCardinalityValue
   *          - generally a numeric number.
   * @return
   * @throws InvalidValueException
   *           - if a value is not compatible with the nonNegativeIntegerNumber
   *           datatype.
   */
  public MaxCardinalityRestriction addMaxCardinalityRestriction(
    RDFProperty onProperty, String maxCardinalityValue)
    throws InvalidValueException {
    String restId = getAutoGeneratedRestrictionName();
    DataType datatype =
      OntologyUtilities.getDataType(XmlSchema.NON_NEGATIVE_INTEGER);

    owlim.addClass(this.sesameRepositoryID, restId,
      OConstants.MAX_CARDINALITY_RESTRICTION);

    owlim.setOnPropertyValue(this.sesameRepositoryID, restId, onProperty
      .getURI().toString());

    if(!datatype.isValidValue(maxCardinalityValue))
      throw new InvalidValueException(maxCardinalityValue
        + " is not valid for datatype " + datatype.getXmlSchemaURIString());

    owlim.setPropertyValue(this.sesameRepositoryID, restId,
      OConstants.MAX_CARDINALITY_RESTRICTION, maxCardinalityValue, datatype
        .getXmlSchemaURIString());

    MaxCardinalityRestriction mcr =
      (MaxCardinalityRestriction)Utils.createOClass(this.sesameRepositoryID,
        this, owlim, restId, OConstants.MAX_CARDINALITY_RESTRICTION);
    fireOntologyResourceAdded(mcr);
    return mcr;
  }

  /**
   * Adds a new Cardinality Restriction to the ontology. It automatically
   * creates a randon anonymous class, which it uses to denote the restriction.
   * The default datatype is set to NonNegativeIntegerNumber
   * 
   * @param onProperty
   *          - Specifies the property for which the restriction is being set.
   * @param cardinalityValue
   *          - generally a numeric number.
   * @return
   * @throws InvalidValueException
   *           - if a value is not compatible with the nonNegativeIntegerNumber
   *           datatype.
   */
  public CardinalityRestriction addCardinalityRestriction(
    RDFProperty onProperty, String cardinalityValue)
    throws InvalidValueException {
    String restId = getAutoGeneratedRestrictionName();
    DataType datatype =
      OntologyUtilities.getDataType(XmlSchema.NON_NEGATIVE_INTEGER);

    owlim.addClass(this.sesameRepositoryID, restId,
      OConstants.CARDINALITY_RESTRICTION);

    owlim.setOnPropertyValue(this.sesameRepositoryID, restId, onProperty
      .getURI().toString());

    if(!datatype.isValidValue(cardinalityValue))
      throw new InvalidValueException(cardinalityValue
        + " is not valid for datatype " + datatype.getXmlSchemaURIString());

    owlim.setPropertyValue(this.sesameRepositoryID, restId,
      OConstants.CARDINALITY_RESTRICTION, cardinalityValue, datatype
        .getXmlSchemaURIString());

    CardinalityRestriction cr =
      (CardinalityRestriction)Utils.createOClass(this.sesameRepositoryID, this,
        owlim, restId, OConstants.CARDINALITY_RESTRICTION);

    fireOntologyResourceAdded(cr);
    return cr;
  }

  /**
   * Adds a new HasValue Restriction to the ontology. It automatically creates a
   * randon anonymous class, which it uses to denote the restriction.
   * 
   * @param onProperty
   *          - Specifies the property for which the restriction is being set.
   * @param hasValue
   *          - a resource or a literal used as a value for hasValue element of
   *          the restriction.
   * @return
   */
  public HasValueRestriction addHasValueRestriction(RDFProperty onProperty,
    OResource hasValue) {

    String restId = getAutoGeneratedRestrictionName();

    owlim.addClass(this.sesameRepositoryID, restId,
      OConstants.HAS_VALUE_RESTRICTION);

    owlim.setOnPropertyValue(this.sesameRepositoryID, restId, onProperty
      .getURI().toString());

    String valueString =
      hasValue instanceof Literal
        ? ((Literal)hasValue).getValue()
        : ((OResource)hasValue).getURI().toString();
    owlim.setRestrictionValue(this.sesameRepositoryID, restId,
      OConstants.HAS_VALUE_RESTRICTION, valueString);

    HasValueRestriction hvr =
      (HasValueRestriction)Utils.createOClass(this.sesameRepositoryID, this,
        owlim, restId, OConstants.HAS_VALUE_RESTRICTION);
    fireOntologyResourceAdded(hvr);
    return hvr;
  }

  /**
   * Adds a new AllValuesFrom Restriction to the ontology. It automatically
   * creates a randon anonymous class, which it uses to denote the restriction.
   * 
   * @param onProperty
   *          - Specifies the property for which the restriction is being set.
   * @param hasValue
   *          - a resource used as a value for hasValue element of the
   *          restriction.
   * @return
   */
  public AllValuesFromRestriction addAllValuesFromRestriction(
    RDFProperty onProperty, OResource hasValue) {
    String restId = getAutoGeneratedRestrictionName();

    owlim.addClass(this.sesameRepositoryID, restId,
      OConstants.ALL_VALUES_FROM_RESTRICTION);

    owlim.setOnPropertyValue(this.sesameRepositoryID, restId, onProperty
      .getURI().toString());

    owlim.setRestrictionValue(this.sesameRepositoryID, restId,
      OConstants.ALL_VALUES_FROM_RESTRICTION, hasValue.getURI().toString());

    AllValuesFromRestriction avfr =
      (AllValuesFromRestriction)Utils.createOClass(this.sesameRepositoryID,
        this, owlim, restId, OConstants.ALL_VALUES_FROM_RESTRICTION);
    fireOntologyResourceAdded(avfr);
    return avfr;
  }
  /**
   * Adds a new AllValuesFrom Restriction to the ontology. It automatically
   * creates a randon anonymous class, which it uses to denote the restriction.
   *
   * @param onProperty
   *          - Specifies the property for which the restriction is being set.
   * @param hasValue
   *          - a resource used as a value for hasValue element of the
   *          restriction.
   * @return
   */
  public AllValuesFromRestriction addAllValuesFromRestriction(
    ObjectProperty onProperty, OClass hasValue) {
    String restId = getAutoGeneratedRestrictionName();

    owlim.addClass(this.sesameRepositoryID, restId,
      OConstants.ALL_VALUES_FROM_RESTRICTION);

    owlim.setOnPropertyValue(this.sesameRepositoryID, restId, onProperty
      .getURI().toString());

    owlim.setRestrictionValue(this.sesameRepositoryID, restId,
      OConstants.ALL_VALUES_FROM_RESTRICTION, hasValue.getURI().toString());

    AllValuesFromRestriction avfr =
      (AllValuesFromRestriction)Utils.createOClass(this.sesameRepositoryID,
        this, owlim, restId, OConstants.ALL_VALUES_FROM_RESTRICTION);
    fireOntologyResourceAdded(avfr);
    return avfr;
  }

  /**
   * Adds a new AllValuesFrom Restriction to the ontology. It automatically
   * creates a randon anonymous class, which it uses to denote the restriction.
   * 
   * @param onProperty
   *          - Specifies the property for which the restriction is being set.
   * @param hasValue
   *          - a resource used as a value for hasValue element of the
   *          restriction.
   * @return
   */
  public SomeValuesFromRestriction addSomeValuesFromRestriction(
    RDFProperty onProperty, OResource hasValue) {
    String restId = getAutoGeneratedRestrictionName();

    owlim.addClass(this.sesameRepositoryID, restId,
      OConstants.SOME_VALUES_FROM_RESTRICTION);

    owlim.setOnPropertyValue(this.sesameRepositoryID, restId, onProperty
      .getURI().toString());

    owlim.setRestrictionValue(this.sesameRepositoryID, restId,
      OConstants.SOME_VALUES_FROM_RESTRICTION, hasValue.getURI().toString());

    SomeValuesFromRestriction svfr =
      (SomeValuesFromRestriction)Utils.createOClass(this.sesameRepositoryID,
        this, owlim, restId, OConstants.SOME_VALUES_FROM_RESTRICTION);
    fireOntologyResourceAdded(svfr);
    return svfr;
  }

  /*
   * (non-Javadoc)
   * 
   * @see gate.creole.ontology.Ontology#setModified(boolean)
   */
  public void setModified(boolean isModified) {
    this.isModified = isModified;
  }

  /*
   * (non-Javadoc)
   * 
   * @see gate.creole.ontology.Ontology#isModified()
   */
  public boolean isModified() {
    return this.isModified;
  }

  /*
   * (non-Javadoc)
   * 
   * @see
   * gate.creole.ontology.Ontology#addOntologyModificationListener(gate.creole
   * .ontology.OntologyModificationListener)
   */
  public synchronized void addOntologyModificationListener(
    OntologyModificationListener oml) {
    List<OntologyModificationListener> newListeners =
      new ArrayList<OntologyModificationListener>();
    if(this.modificationListeners != null) {
      newListeners.addAll(this.modificationListeners);
    }
    newListeners.add(oml);
    this.modificationListeners = newListeners;
  }

  /*
   * (non-Javadoc)
   * 
   * @see
   * gate.creole.ontology.Ontology#removeOntologyModificationListener(gate.creole
   * .ontology.OntologyModificationListener)
   */
  public synchronized void removeOntologyModificationListener(
    OntologyModificationListener oml) {
    if(this.modificationListeners == null
      || !this.modificationListeners.contains(oml)) {
      return;
    }
    else {
      List<OntologyModificationListener> newListeners =
        new ArrayList<OntologyModificationListener>();
      for(OntologyModificationListener l : this.modificationListeners) {
        if(l != oml) {
          newListeners.add(l);
        }
      }
      this.modificationListeners = newListeners;
    }
  }

  /**
   * A method to invoke when a resource's property value is changed
   * 
   * @param resource
   * @param eventType
   */
  public void fireResourcePropertyValueChanged(OResource resource,
    RDFProperty property, Object value, int eventType) {
    List<OntologyModificationListener> listeners = this.modificationListeners;
    if(listeners != null) {
      for(OntologyModificationListener l : listeners) {
        l.resourcePropertyValueChanged(this, resource, property, value,
          eventType);
      }
    }
  }

  /**
   * A method to invoke when a resource's property value is changed
   * 
   * @param resource
   * @param eventType
   */
  public void fireResourceRelationChanged(OResource resource1,
    OResource resource2, int eventType) {
    List<OntologyModificationListener> listeners = this.modificationListeners;
    if(listeners != null) {
      for(OntologyModificationListener l : listeners) {
        l.resourceRelationChanged(this, resource1, resource2, eventType);
      }
    }
  }

  public void fireOntologyReset() {
    List<OntologyModificationListener> listeners = this.modificationListeners;
    if(listeners != null) {
      for(OntologyModificationListener l : listeners) {
        l.ontologyReset(this);
      }
    }
  }

  /**
   * A Method to invoke an event for newly added ontology resource
   * 
   * @param resource
   */
  public void fireOntologyResourceAdded(OResource resource) {
    List<OntologyModificationListener> listeners = this.modificationListeners;
    if(listeners != null) {
      for(OntologyModificationListener l : listeners) {
        l.resourceAdded(this, resource);
      }
    }
  }

  /**
   * A Method to invoke an event for a removed ontology resource
   * 
   * @param resource
   */
  public void fireOntologyResourcesRemoved(String[] resources) {
    // we need to delete this resource from our maps
    for(int i = 0; i < resources.length; i++) {
      removeOResourceFromMap(resources[i]);
    }

    List<OntologyModificationListener> listeners = this.modificationListeners;
    if(listeners != null) {
      for(OntologyModificationListener l : listeners) {
        l.resourcesRemoved(this, resources);
      }
    }
  }

  /*
   * (non-Javadoc)
   * 
   * @see gate.creole.ontology.Ontology#startTransaction()
   */
  public abstract void startTransaction();

  /*
   * (non-Javadoc)
   * 
   * @see gate.creole.ontology.Ontology#commitTransaction()
   */
  public abstract void commitTransaction();

  /*
   * (non-Javadoc)
   * 
   * @see gate.creole.ontology.Ontology#transationStarted()
   */
  public abstract boolean transationStarted();

  /*
   * (non-Javadoc)
   * 
   * @see gate.creole.ontology.Ontology#getSesameRepository()
   */
  public abstract SesameRepository getSesameRepository();

  /*
   * (non-Javadoc)
   * 
   * @see gate.creole.ontology.Ontology#getSesameRepositoryID()
   */
  public String getSesameRepositoryID() {
    return this.sesameRepositoryID;
  }

  /*
   * (non-Javadoc)
   * 
   * @see gate.creole.ontology.Ontology#getOResourceFromMap(java.lang.String)
   */
  public OResource getOResourceFromMap(String uri) {
    return urisToOResouceMap.get(uri);
  }

  /*
   * (non-Javadoc)
   * 
   * @see gate.creole.ontology.Ontology#addOResourceToMap(java.lang.String,
   * gate.creole.ontology.OResource)
   */
  public void addOResourceToMap(String uri, OResource resource) {
    urisToOResouceMap.put(uri, resource);
    String resourceName = OntologyUtilities.getResourceName(uri);
    List<OResource> resources = resourceNamesToOResourcesMap.get(resourceName);
    if(resources == null) {
      resources = new ArrayList<OResource>();
      resourceNamesToOResourcesMap.put(resourceName, resources);
    }
    resources.add(resource);
  }

  /*
   * (non-Javadoc)
   * 
   * @see gate.creole.ontology.Ontology#removeOResourceFromMap(java.lang.String)
   */
  public void removeOResourceFromMap(String uri) {
    urisToOResouceMap.remove(uri);
    String resourceName = OntologyUtilities.getResourceName(uri);
    resourceNamesToOResourcesMap.remove(resourceName);
  }

  private boolean callFromCleanup = false;

  /*
   * (non-Javadoc)
   * 
   * @see gate.Resource#cleanup()
   */
  public void cleanup() {
    if(owlim != null && !getPersistRepository().booleanValue()) {
      callFromCleanup = true;
      cleanOntology();
      owlim.removeRepository(this.sesameRepositoryID, getPersistRepository()
        .booleanValue());
    }
    urisToOResouceMap.clear();
  }

  /**
   * Returns an instance of OWLIM
   * 
   * @return
   */
  public OWLIM getOwlim() {
    return owlim;
  }

  /**
   * Sets an instance of OWLIM
   * 
   * @param owlim
   */
  public void setOwlim(OWLIM owlim) {
    this.owlim = owlim;
  }

  /**
   * Indicates whether the repository should be persisted.
   * 
   * @return
   */
  public Boolean getPersistRepository() {
    return persistRepository;
  }

  /**
   * Indicates whether the repository should be persisted.
   * 
   * @param persistRepository
   */
  public void setPersistRepository(Boolean persistRepository) {
    this.persistRepository = persistRepository;
  }

  /**
   * This method checks in its cache find out the URI for the given resource
   * name. However, doesn't guranttee that it will be able to return the URI. It
   * is also possible for two resources to have a same name but different name
   * spaces. This method returns a List containing all such URIs.
   * 
   * @param resourceName
   * @return
   */
  public OResource getOResourceByName(String resourceName) {
    List<OResource> resources = resourceNamesToOResourcesMap.get(resourceName);
    if(resources != null) {
      if(resources.size() > 1)
        System.err
          .print("Warning : there are more than one resources matching with the name "
            + resourceName);

      return resources.get(0);
    }
    return null;
  }

  /**
   * This method checks in its cache to find out the OResources for the given
   * resource name. It is possible for two resources to have a same name but
   * different name spaces. This method returns a list of resources with the
   * common name. Please note that deleting an instance from this list (e.g.
   * list.remove(int/Object)) does not delete the resource from an ontology. One
   * must use appropriate method from the Ontology interface to delete such
   * resources.
   * 
   * @param resourceName
   * @return
   */
  public List<OResource> getOResourcesByName(String resourceName) {
    List<OResource> resources = resourceNamesToOResourcesMap.get(resourceName);
    if(resources == null) return null;
    List<OResource> toReturn = new ArrayList<OResource>();
    toReturn.addAll(resources);
    return toReturn;
  }

  /**
   * This method returns a list of OResources from the ontology. Please note
   * that deleting an instance from this list (e.g. list.remove(int/Object))
   * does not delete the resource from an ontology. One must use appropriate
   * method from the Ontology interface to delete such resources.
   * 
   * @return
   */
  public List<OResource> getAllResources() {
    getOClasses(false);
    getOInstances();
    getPropertyDefinitions();
    List<OResource> toReturn = new ArrayList<OResource>();
    Iterator<String> keys = resourceNamesToOResourcesMap.keySet().iterator();
    while(keys.hasNext()) {
      toReturn.addAll(resourceNamesToOResourcesMap.get(keys.next()));
    }
    return toReturn;
  }

  /**
   * Tries to save the ontology at the provided File
   */
  public void store(File newOntology) throws IOException {
    String output =
      owlim.getOntologyData(sesameRepositoryID,
        OConstants.ONTOLOGY_FORMAT_NTRIPLES);
    BufferedWriter writer = new BufferedWriter(new FileWriter(newOntology));
    writer.write(output);
    writer.flush();
    writer.close();
  }

  /**
   * This method given a property (either an annotation or datatype), retrieves
   * a list of resources which have the provided literal set as a value.
   * 
   * @param aProperty
   * @param aValue
   * @return
   */
  public List<OResource> getOResourcesWith(RDFProperty aProperty, Literal aValue) {
    List<OResource> toReturn = new ArrayList<OResource>();

    int propType = 1;

    if(aProperty instanceof AnnotationProperty) {
      propType = 1;
    }
    else if(aProperty instanceof DatatypeProperty) {
      propType = 2;
    }
    else {
      return toReturn;
    }

    // here the first thing is to obtain all the resources
    List<OResource> resources = getAllResources();

    // and on each resource we need to check if it has the above
    // property set on it
    for(OResource aResource : resources) {
      switch(propType){
        case 1:
          if(aResource.hasAnnotationPropertyWithValue(
            (AnnotationProperty)aProperty, aValue)) toReturn.add(aResource);
          break;
        case 2:
          if(aResource instanceof OInstance
            && ((OInstance)aResource).hasDatatypePropertyWithValue(
              (DatatypeProperty)aProperty, aValue)) toReturn.add(aResource);
          break;
      }
    }
    return toReturn;
  }

  /**
   * This method given a property (either object, transitive, symmetric or rdf),
   * retrieves a list of resources which have the provided resource set as a
   * value.
   * 
   * @param aProperty
   * @param aValue
   * @return
   */
  public List<OResource> getOResourcesWith(RDFProperty aProperty,
    OResource aValue) {
    List<OResource> toReturn = new ArrayList<OResource>();

    int propType = 1;

    if(aProperty instanceof ObjectProperty) {
      propType = 1;
    }
    else if(!(aProperty instanceof DatatypeProperty)) {
      propType = 2;
    }
    else {
      return toReturn;
    }

    // here the first thing is to obtain all the resources
    List<OResource> resources = getAllResources();

    // and on each resource we need to check if it has the above
    // property set on it
    for(OResource aResource : resources) {
      switch(propType){
        case 1:
          if(aResource instanceof OInstance
            && aValue instanceof OInstance
            && ((OInstance)aResource).hasObjectPropertyWithValue(
              (ObjectProperty)aProperty, (OInstance)aValue))
            toReturn.add(aResource);
          break;
        case 2:
          if(aResource instanceof OInstance
            && ((OInstance)aResource)
              .hasRDFPropertyWithValue(aProperty, aValue))
            toReturn.add(aResource);
          break;
      }
    }
    return toReturn;
  }

  /**
   * The method executes the query on repository and returns the toString()
   * result of the QueryResultTable.
   * 
   * @param serqlQuery
   * @return
   */
  public String executeQuery(String serqlQuery) {
    return owlim.executeQuery(sesameRepositoryID, serqlQuery);
  }

  public List<OURI> getOntologyURIs() {
    throw new UnsupportedOperationException("Not supported in this implementation");
  }

  public OURI createOURI(String uri) {
    return (new URI(uri,false));
  }

  public AnonymousClass addAnonymousClass() {
    throw new UnsupportedOperationException("Not supported in this implementation");
  }

  //public OClass getOClass(ONodeID id) {
  //  throw new UnsupportedOperationException("Not supported in this implementation");
  //}


  public void writeOntologyData(OutputStream out, OntologyFormat format, boolean includeExports) {
    throw new UnsupportedOperationException("Not supported in this implementation");
  }

  public void writeOntologyData(Writer out, OntologyFormat format, boolean includeExports) {
    throw new UnsupportedOperationException("Not supported in this implementation");
  }

  public void readOntologyData(InputStream in, String baseURI, OntologyFormat format, boolean asImport) {
    throw new UnsupportedOperationException("Not supported in this implementation");
  }

  public Set<OURI> getImportURIs() {
    throw new UnsupportedOperationException("Not supported in this implementation");
  }

  public void readOntologyData(Reader in, String baseURI, OntologyFormat format, boolean asImport) {
    throw new UnsupportedOperationException("Not supported in this implementation");
  }

  public void resolveImports(Map<String, String> importMappings) {
    throw new UnsupportedOperationException("Not supported in this implementation");
  }

  public List<URL> getURLs(boolean includeImports) {
    throw new UnsupportedOperationException("Not supported in this implementation");
  }

  public void setCheckingEnabled(boolean flag) {
    throw new UnsupportedOperationException("Not supported in this implementation");
  }

  public OntologyBooleanQuery createBooleanQuery(String query, QueryLanguage lang) {
    throw new UnsupportedOperationException("Not supported in this implementation");
  }

  public OntologyTupleQuery createTupleQuery(String query, QueryLanguage lang) {
    throw new UnsupportedOperationException("Not supported in this implementation");
  }

  public OURI createOURIForName(String resourceName) {
    throw new UnsupportedOperationException("Not supported in this implementation");
  }

  public OURI createOURIForName(String resourceName, String baseURI) {
    throw new UnsupportedOperationException("Not supported in this implementation");
  }

  public OURI generateOURI(String resourceName) {
    throw new UnsupportedOperationException("Not supported in this implementation");
  }

  public OURI generateOURI(String resourceName, String baseURI) {
    throw new UnsupportedOperationException("Not supported in this implementation");
  }

  public List<Literal> getOntologyAnnotationValues(AnnotationProperty ann) {
    throw new UnsupportedOperationException("Not supported in this implementation");
  }

  public void setOntologyAnnotation(AnnotationProperty ann, Literal val)  {
    throw new UnsupportedOperationException("Not supported in this implementation");
  }

  public void setOntologyURI(OURI uri)  {
    throw new UnsupportedOperationException("Not supported in this implementation");
  }

  public OURI getOntologyURI()  {
    throw new UnsupportedOperationException("Not supported in this implementation");
  }

  public ClosableIterator getOClassesIterator(boolean toponly)  {
    throw new UnsupportedOperationException("Not supported in this implementation");
  }
}