Log in Help
Print
Homereleasesgate-5.1-beta2-build3402-ALLpluginsOntologysrcgatecreoleontologyimpl 〉 OInstanceImpl.java
 
/*
 *  OInstanceImpl.java
 *
 *  Niraj Aswani, 09/March/07
 *
 *  $Id: OInstanceImpl.java 11884 2009-11-03 17:21:45Z johann_p $
 */
package gate.creole.ontology.impl;


import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import gate.creole.ontology.DataType;
import gate.creole.ontology.DatatypeProperty;
import gate.creole.ontology.GateOntologyException;
import gate.creole.ontology.InvalidValueException;
import gate.creole.ontology.Literal;
import gate.creole.ontology.OClass;
import gate.creole.ontology.OConstants;
import gate.creole.ontology.OConstants.Closure;
import gate.creole.ontology.OInstance;
import gate.creole.ontology.OResource;
import gate.creole.ontology.OURI;
import gate.creole.ontology.ObjectProperty;
import gate.creole.ontology.Ontology;
import gate.creole.ontology.RDFProperty;
import gate.util.ClosableIterator;

/**
 * Implementation of the OInstance
 * 
 * @author niraj
 * 
 */
public class OInstanceImpl extends OResourceImpl implements OInstance {
  /**
   * Constructor
   * 
   * @param aURI
   * @param ontology
   * @param repositoryID
   * @param owlimPort
   */
  public OInstanceImpl(OURI aURI, Ontology ontology,
          OntologyService owlimPort) {
    super(aURI, ontology, owlimPort);
  }

  /*
   * (non-Javadoc)
   * 
   * @see gate.creole.ontology.OInstance#getOClasses(byte)
   */
  public Set<OClass> getOClasses(byte closure) {
    //throw new UnsupportedOperationException("Method with this parameter not longer supported");
    Closure theClosure = closure == OConstants.DIRECT_CLOSURE ?
      Closure.DIRECT_CLOSURE : Closure.TRANSITIVE_CLOSURE;
    return getOClasses(theClosure);
  }
  
  public Set<OClass> getOClasses(Closure closure) {
      ResourceInfo[] oClasses = ontologyService.getClassesOfIndividual(
              this.nodeId.toString(), closure);
      Set<OClass> set = new HashSet<OClass>();
      for(int i = 0; i < oClasses.length; i++) {
        set.add(Utils.createOClass(this.ontology,
                this.ontologyService, oClasses[i].getUri(),
                oClasses[i].getClassType()));
      }
      return set;
  }

  /*
   * (non-Javadoc)
   * 
   * @see gate.creole.ontology.OInstance#isInstanceOf(gate.creole.ontology.OClass,
   *      byte)
   */
  public boolean isInstanceOf(OClass aClass, byte closure) {
    //throw new UnsupportedOperationException("Method with these parameters not longer supported");
    Closure theClosure = closure == OConstants.DIRECT_CLOSURE ?
      Closure.DIRECT_CLOSURE : Closure.TRANSITIVE_CLOSURE;
    return isInstanceOf(aClass, theClosure);
  }

  public boolean isInstanceOf(OClass aClass, Closure closure) {
      //return ontologyService.hasIndividual(aClass.getONodeID().toString(),
      //        this.nodeId.toString(), closure);
      return ontologyService.hasInstance(this.getOURI(), aClass.getONodeID(), closure);
  }

  /*
   * (non-Javadoc)
   * 
   * @see gate.creole.ontology.OInstance#setDifferentFrom(gate.creole.ontology.OInstance)
   */
  public void setDifferentFrom(OInstance theInstance) {
      if(this == theInstance) {
        Utils
                .warning("setDifferentFrom(theInstance) : the source and the argument instances refer to the same instance and therefore cannot be set as different from each other");
        return;
      }

      ontologyService.setDifferentIndividualFrom(this.nodeId.toString(),
              theInstance.getOURI().toString());
      ontology.fireResourceRelationChanged(this, theInstance, OConstants.DIFFERENT_INSTANCE_EVENT);      
  }

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

  /*
   * (non-Javadoc)
   * 
   * @see gate.creole.ontology.OInstance#isDifferentFrom(gate.creole.ontology.OInstance)
   */
  public boolean isDifferentFrom(OInstance theInstance) {
      return ontologyService.isDifferentIndividualFrom(this.nodeId
              .toString(), theInstance.getOURI().toString());
  }

  /*
   * (non-Javadoc)
   * 
   * @see gate.creole.ontology.OInstance#setSameInstanceAs(gate.creole.ontology.OInstance)
   */
  public void setSameInstanceAs(OInstance theInstance) {
      if(this == theInstance) {
        Utils
                .warning("setDifferentFrom(theInstance) : the source and the argument instances refer to the same instance and therefore cannot be set as same");
        return;
      }

      ontologyService.setSameIndividualAs(this.nodeId.toString(),
              theInstance.getOURI().toString());
      ontology.fireResourceRelationChanged(this, theInstance, OConstants.SAME_INSTANCE_EVENT);
  }

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

  /*
   * (non-Javadoc)
   * 
   * @see gate.creole.ontology.OInstance#isSameInstanceAs(gate.creole.ontology.OInstance)
   */
  public boolean isSameInstanceAs(OInstance theInstance) {
      return ontologyService.isSameIndividualAs(this.nodeId.toString(),
              theInstance.getOURI().toString());
  }

  /*
   * (non-Javadoc)
   * 
   * @see gate.creole.ontology.OInstance#addRDFPropertyValue(gate.creole.ontology.RDFProperty,
   *      gate.creole.ontology.OResource)
   */
  public void addRDFPropertyValue(RDFProperty aProperty, OResource value)
          throws InvalidValueException {
      // we need to check if the current instance is a valid domain for
      // the property
      if(!aProperty.isValidDomain(this)) {
        Utils.error(this.getOURI().toTurtle()
                + " is not a valid domain for the property "
                + aProperty.getOURI().toString());
        return;
      }

      // we need to check if the current instance is a valid domain for
      // the property
      if(!aProperty.isValidRange(value)) {
        Utils.error(value.getONodeID().toTurtle()
                + " is not a valid range for the property "
                + aProperty.getOURI().toTurtle());
        return;
      }

      ontologyService.addRDFPropertyValue(this.nodeId.toString(),
              aProperty.getOURI().toString(), value.getONodeID().toString());
      ontology.fireResourcePropertyValueChanged(this, aProperty,
          value, OConstants.RDF_PROPERTY_VALUE_ADDED_EVENT);
  }

  /*
   * (non-Javadoc)
   * 
   * @see gate.creole.ontology.OInstance#removeRDFPropertyValue(gate.creole.ontology.RDFProperty,
   *      gate.creole.ontology.OResource)
   */
  public void removeRDFPropertyValue(RDFProperty aProperty, OResource value) {
      ontologyService.removeRDFPropertyValue(this.nodeId.toString(),
              aProperty.getOURI().toString(), value.getONodeID().toString());
      ontology.fireResourcePropertyValueChanged(this, aProperty, value,
          OConstants.RDF_PROPERTY_VALUE_REMOVED_EVENT);
  }

  /*
   * (non-Javadoc)
   * 
   * @see gate.creole.ontology.OInstance#getRDFPropertyValues(gate.creole.ontology.RDFProperty)
   */
  // TODO: this must be deprecated and/or done differently!

  // It is highly inefficient as it retrieves all individuals in here to
  // check, we should do this in the query, if posible!
  // DONE: we have replaced this with hasInstance

  // TODO: why does this not check for property values that coul be
  // literals?
  public List<OResource> getRDFPropertyValues(RDFProperty aProperty) {
    //System.out.println(aProperty.getOURI().toString());
    //Utils.warnDeprecation("getREDFPropertyValues");
    ResourceInfo[] list = ontologyService.getRDFPropertyValues(nodeId
              .toString(), aProperty.getOURI().toString());
      List<OResource> values = new ArrayList<OResource>();
      //List<String> individuals = Arrays.asList(ontologyService
      //        .getIndividuals());
      //ClosableIterator<OInstance> ii = ontologyService.getInstancesIterator(null,null);
      //List<String> individuals = new ArrayList<String>();
      //while(ii.hasNext()) {
      //  individuals.add(ii.next().getOURI().toString());
      //}
      // these resources can be anything - an instance, a property, or a
      // class
      // TODO: do something about the use of the map here!!!!
      for(int i = 0; i < list.length; i++) {
        // is it an individual
        if(ontologyService.hasInstance(ontology.createOURI(list[i].getUri()),null,null)) {
        //if(individuals.contains(list[i].toString())) {
          values.add(Utils.createOInstance(this.ontology,
                  this.ontologyService, list[i].getUri()));
          continue;
        }
        // is it a class
        if(ontologyService.hasClass(list[i].getUri())) {
          values.add(Utils.createOClass(this.ontology,
                  this.ontologyService, list[i].getUri(), list[i].getClassType()));
          continue;
        }

        // TODO: if we get something here that is not defined in the ontology,
        // we assume it is a property but that could be wrong if it is
        // the URI of a class or instance that is not defined as class or
        // instance in the ontology.
        // We probably should warn about this at some point but will
        // ignore it for now ...

        Property prop = ontologyService.getPropertyFromOntology(
                list[i].getUri());
        if(prop == null) {
          // System.err.println("Property is null for "+list[i]+"/"+list[i].getUri());
          continue;
        } else {
        values.add(Utils.createOProperty(this.ontology,
                this.ontologyService, prop.getUri(), prop.getType()));
        }
      }
      return values;
  }

  /**
   * This method returns the RDF properties set on this resource.
   * 
   * @return
   */
  public Set<RDFProperty> getSetRDFProperties() {
      Property[] properties = ontologyService.getRDFProperties(
              this.nodeId.toString());
      Set<RDFProperty> rdfProps = new HashSet<RDFProperty>();
      for(int i = 0; i < properties.length; i++) {
        if(properties[i].getType() != OConstants.RDF_PROPERTY) {
          throw new GateOntologyException("The property :"
                  + properties[i].getUri()
                  + " returned from the repository is not an RDFProperty");
        }
        String propUri = properties[i].getUri();
        OResource resource = null;
        resource = new RDFPropertyImpl(ontology.createOURI(propUri),
                  this.ontology, ontologyService);
        rdfProps.add((RDFProperty)resource);
      }
      return rdfProps;
  }

  /**
   * Checks if the resource has the provided RDF property set on it with
   * the specified value.
   * 
   * @param aProperty
   * @param aResource
   * @return
   */
  public boolean hasRDFPropertyWithValue(RDFProperty aProperty,
          OResource aResource) {
    List<OResource> resources = getRDFPropertyValues(aProperty);
    for(OResource r : resources) {
      if(r.equals(aResource)) return true;
    }
    return false;
  }

  /*
   * (non-Javadoc)
   * 
   * @see gate.creole.ontology.OInstance#removeRDFPropertyValues(gate.creole.ontology.RDFProperty)
   */
  public void removeRDFPropertyValues(RDFProperty aProperty) {
      ontologyService.removeRDFPropertyValues(this.nodeId.toString(),
              aProperty.getOURI().toString());
      ontology.fireResourcePropertyValueChanged(this, aProperty, null, OConstants.RDF_PROPERTY_VALUE_REMOVED_EVENT);
  }

  /*
   * (non-Javadoc)
   * 
   * @see gate.creole.ontology.OInstance#addDatatypePropertyValue(gate.creole.ontology.DatatypeProperty,
   *      gate.creole.ontology.Literal)
   */
  public void addDatatypePropertyValue(DatatypeProperty aProperty, Literal value)
          throws InvalidValueException {
      // we need to check if the current instance is a valid domain for
      // the property
      if(!aProperty.isValidDomain(this)) {
        Utils.error(this.getOURI().toTurtle()
                + " is not a valid domain for the property "
                + aProperty.getOURI().toTurtle());
        return;
      }

      DataType type = aProperty.getDataType();
      if(value.getDataType() == null) {
        type = aProperty.getDataType();
      }
      else {
        if(!type.getXmlSchemaURIString().equals(
                value.getDataType().getXmlSchemaURIString()))
          throw new GateOntologyException("Datatype :"
                  + value.getDataType().getXmlSchemaURIString()
                  + " doesn't match with the property's datatype :"
                  + type.getXmlSchemaURIString());
      }

      ontologyService.addDatatypePropertyValue(this.nodeId.toString(),
              aProperty.getOURI().toString(), type.getXmlSchemaURIString(),
              value.getValue());
      ontology.fireResourcePropertyValueChanged(this, aProperty, value, OConstants.DATATYPE_PROPERTY_VALUE_ADDED_EVENT);  
  }

  /*
   * (non-Javadoc)
   * 
   * @see gate.creole.ontology.OInstance#removeDatatypePropertyValue(gate.creole.ontology.DatatypeProperty,
   *      gate.creole.ontology.Literal)
   */
  public void removeDatatypePropertyValue(DatatypeProperty aProperty,
          Literal value) {
      ontologyService.removeDatatypePropertyValue(this.nodeId.toString(),
              aProperty.getOURI().toString(), value.getDataType()
                      .getXmlSchemaURIString(), value.getValue());
      ontology.fireResourcePropertyValueChanged(this, aProperty, value, OConstants.DATATYPE_PROPERTY_VALUE_REMOVED_EVENT);
  }

  /*
   * (non-Javadoc)
   * 
   * @see gate.creole.ontology.OInstance#getDatatypePropertyValues(gate.creole.ontology.DatatypeProperty)
   */
  public List<Literal> getDatatypePropertyValues(DatatypeProperty aProperty) {
    try {
      PropertyValue[] values = ontologyService.getDatatypePropertyValues(
              this.nodeId.toString(), aProperty.getOURI()
                      .toString());
      List<Literal> list = new ArrayList<Literal>();
      for(int i = 0; i < values.length; i++) {
        list.add(new Literal(values[i].getValue(), OntologyUtilities
                .getDataType(values[i].getDatatype())));
      }
      return list;
    }
    catch(InvalidValueException ive) {
      throw new GateOntologyException(ive);
    }
  }

  /*
   * (non-Javadoc)
   * 
   * @see gate.creole.ontology.OInstance#removeDatatypePropertyValues(gate.creole.ontology.DatatypeProperty)
   */
  public void removeDatatypePropertyValues(DatatypeProperty aProperty) {

      ontologyService.removeDatatypePropertyValues(
              this.nodeId.toString(), aProperty.getOURI().toString());
      ontology.fireResourcePropertyValueChanged(this, aProperty, null, OConstants.DATATYPE_PROPERTY_VALUE_REMOVED_EVENT);
  }

  /**
   * This method returns the datatype properties set on this resource.
   * 
   * @return
   */
  public Set<DatatypeProperty> getSetDatatypeProperties() {
      Property[] properties = ontologyService.getDatatypeProperties(
              this.nodeId.toString());
      Set<DatatypeProperty> dataProps = new HashSet<DatatypeProperty>();
      for(int i = 0; i < properties.length; i++) {
        if(properties[i].getType() != OConstants.DATATYPE_PROPERTY) {
          throw new GateOntologyException("The property :"
                  + properties[i].getUri()
                  + " returned from the repository is not an DatatypeProperty");
        }
        String propUri = properties[i].getUri();
        OResource resource = null;
        resource = new DatatypePropertyImpl(ontology.createOURI(propUri),
                  this.ontology, ontologyService);
        dataProps.add((DatatypeProperty)resource);
      }
      return dataProps;
  }

  /**
   * Checks if the resource has the provided datatype property set on it
   * with the specified value.
   * 
   * @param aProperty
   * @param aValue
   * @return
   */
  public boolean hasDatatypePropertyWithValue(DatatypeProperty aProperty,
          Literal aValue) {

    List<Literal> literals = getDatatypePropertyValues(aProperty);
    for(Literal l : literals) {
      if(l.getValue().equals(aValue.getValue())) {
        if(l.getDataType() != null && aValue.getDataType() != null) {
          if(!aValue.getDataType().getXmlSchemaURIString().equals(
                  l.getDataType().getXmlSchemaURIString())) continue;
        }
        
        if(l.getLanguage() != null && aValue.getLanguage() != null) {
          if(!aValue.getLanguage().toString().equals(l.getLanguage().toString())) continue;          
        }
        return true;
      }
    }
    return false;
  }

  /*
   * (non-Javadoc)
   * 
   * @see gate.creole.ontology.OInstance#addObjectPropertyValue(gate.creole.ontology.ObjectProperty,
   *      gate.creole.ontology.OInstance)
   */
  public void addObjectPropertyValue(ObjectProperty aProperty, OInstance value)
          throws InvalidValueException {
      // we need to check if the current instance is a valid domain for
      // the property
      if(!aProperty.isValidDomain(this)) {
        Utils.error(this.getOURI().toTurtle()
                + " is not a valid domain for the property "
                + aProperty.getOURI().toTurtle());
        return;
      }

      // we need to check if the current instance is a valid domain for
      // the property
      if(!aProperty.isValidRange(value)) {
        Utils.error(value.getOURI().toTurtle()
                + " is not a valid range for the property "
                + aProperty.getOURI().toTurtle());
        return;
      }

      ontologyService.addObjectPropertyValue(this.nodeId.toString(),
              aProperty.getOURI().toString(), value.getOURI().toString());
      ontology.fireResourcePropertyValueChanged(this, aProperty, value, OConstants.OBJECT_PROPERTY_VALUE_ADDED_EVENT);
  }

  /*
   * (non-Javadoc)
   * 
   * @see gate.creole.ontology.OInstance#removeObjectPropertyValue(gate.creole.ontology.ObjectProperty,
   *      gate.creole.ontology.OInstance)
   */
  public void removeObjectPropertyValue(ObjectProperty aProperty,
          OInstance value) {
      ontologyService.removeObjectPropertyValue(this.nodeId.toString(),
              aProperty.getOURI().toString(), value.getOURI().toString());
      ontology.fireResourcePropertyValueChanged(this, aProperty, value, OConstants.OBJECT_PROPERTY_VALUE_REMOVED_EVENT);  
  }

  /*
   * (non-Javadoc)
   * 
   * @see gate.creole.ontology.OInstance#getObjectPropertyValues(gate.creole.ontology.ObjectProperty)
   */
  public List<OInstance> getObjectPropertyValues(ObjectProperty aProperty) {
      String[] list = ontologyService.getObjectPropertyValues(nodeId
              .toString(), aProperty.getOURI().toString());
      List<OInstance> values = new ArrayList<OInstance>();
      for(int i = 0; i < list.length; i++) {
        values.add(Utils.createOInstance(this.ontology,
                this.ontologyService, list[i]));
      }
      return values;
  }

  /*
   * (non-Javadoc)
   * 
   * @see gate.creole.ontology.OInstance#removeObjectPropertyValues(gate.creole.ontology.ObjectProperty)
   */
  public void removeObjectPropertyValues(ObjectProperty aProperty) {
      ontologyService.removeObjectPropertyValues(this.nodeId.toString(),
              aProperty.getOURI().toString());
      ontology.fireResourcePropertyValueChanged(this, aProperty, null, OConstants.OBJECT_PROPERTY_VALUE_REMOVED_EVENT);
  }

  /**
   * This method returns the object properties set on this resource.
   * 
   * @return
   */
  public Set<ObjectProperty> getSetObjectProperties() {
      Property[] properties = ontologyService.getObjectProperties(
              this.nodeId.toString());
      Set<ObjectProperty> objectProps = new HashSet<ObjectProperty>();
      for(int i = 0; i < properties.length; i++) {
        if(properties[i].getType() != OConstants.OBJECT_PROPERTY) {
          throw new GateOntologyException("The property :"
                  + properties[i].getUri()
                  + " returned from the repository is not an ObjectProperty");
        }
        String propUri = properties[i].getUri();
        OResource resource = new ObjectPropertyImpl(ontology.createOURI(propUri),
                  this.ontology, ontologyService);
        objectProps.add((ObjectProperty)resource);
      }
      return objectProps;
  }

  /**
   * Checks if the resource has the provided object property set on it
   * with the specified value.
   * 
   * @param aProperty
   * @param aValue
   * @return
   */
  public boolean hasObjectPropertyWithValue(ObjectProperty aProperty,
          OInstance aValue) {
    List<OInstance> instances = getObjectPropertyValues(aProperty);
    for(OInstance i : instances) {
      if(i.equals(aValue)) {
        return true;
      }
    }
    return false;
  }

  /**
   * This method returns all the set properties set on this resource.
   * 
   * @return
   */
  public Set<RDFProperty> getAllSetProperties() {
    Set<RDFProperty> toReturn = new HashSet<RDFProperty>();
    toReturn.addAll(getSetAnnotationProperties());
    toReturn.addAll(getSetDatatypeProperties());
    toReturn.addAll(getSetObjectProperties());
    toReturn.addAll(getSetRDFProperties());
    return toReturn;
  }

  public OURI getOURI() {
    // an instance may not be a blank node so we can always cast to OURI
    // but we better make sure anyways ...
    if(getONodeID().isAnonymousResource()) {
      throw new GateOntologyException(
          "Cannot return OInstance OURI, instance is a blank node: "+
          getONodeID().toTurtle());
    }
    return (OURI)getONodeID();
  }


}