Log in Help
Print
Homereleasesgate-6.1-build3913-ALLpluginsOntology_OWLIM2srcgatecreoleontologyowlim 〉 AbstractOWLIMOntologyImpl.java
 
/*
 *  AbstractOWLIMOntologyImpl.java
 *
 *  Niraj Aswani, 09/March/07
 *
 *  $Id: AbstractOWLIMOntologyImpl.java 12973 2010-08-18 20:23:11Z ian_roberts $
 */
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() {
    return new ResourceIterator<OInstance>(getOInstances());
  }

  /*
   * (non-Javadoc)
   * 
   * @see
   * gate.creole.ontology.Ontology#getOInstances(gate.creole.ontology
   * .OClass, boolean)
   */
  public Set<OInstance> getOInstances(OClass theClass, Closure closure) {
    byte bclosure = closure == Closure.DIRECT_CLOSURE
            ? OConstants.DIRECT_CLOSURE
            : OConstants.TRANSITIVE_CLOSURE;
    return getOInstances(theClass, bclosure);
  }

  public ClosableIterator<OInstance> getOInstancesIterator(OClass theClass,
          Closure closure) {

    byte bclosure = closure == Closure.DIRECT_CLOSURE
            ? OConstants.DIRECT_CLOSURE
            : OConstants.TRANSITIVE_CLOSURE;
    return new ResourceIterator<OInstance>(getOInstances(theClass, bclosure));
  }

  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 OURI createOURIForName(String resourceName) {
    return createOURIForName(resourceName, defaultNameSpace);
  }

  public OURI createOURIForName(String resourceName, String baseURI) {
    return new URI(baseURI + resourceName, 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 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) {
    return new ResourceIterator<OClass>(getOClasses(toponly));
  }
}