/*
* Copyright (c) 1998-2009, The University of Sheffield.
*
* This file is part of GATE (see http://gate.ac.uk/), and is free
* software, licenced under the GNU Library General Public License,
* Version 2, June 1991 (in the distribution as file licence.html,
* and also available at http://gate.ac.uk/gate/licence.html).
*
* $Id: OntologyServiceImplSesame.java 11600 2009-10-13 17:13:22Z johann_p $
*/
package gate.creole.ontology.impl.sesame;
// TODO: we still get two different kinds of bnodeids: the old one without
// _: and the new one with _:
// Figure out where the version without the prefix comes from and make
// all methods use the same convention!
// TODO: !!!!
// - replace generic Exception with something better
// - make replacement for repositoryConnection.isClass and repositoryConnection.isProperty
// - handle "system namespaces/URIs" etc better: have one array of these
// URIS declared somewhere and derive all the constants and tests from there.
// Have that array defined in the ontology namespace!
//
// !!!! Change all the return types used by GOS to either OResource objects
// or ONodeID or NodeIDorLiteral
// Create a class NodeIDorLiteral that *contains* either a NodeID or a
// Literal value. Use that class to pass back search results. Since this
// could be useful in the API, define that interface in the API!
// (For now and during testing, define in package impl)
//
// oneOf restrictions are simply returned as some anonymous class for now!
// check if it makes sense to actually use transactions somewhere? at the
// moment, by default the repositoryconnection is in autocommit mode and
// each modification is automatically commited.
import gate.creole.ontology.GateOntologyException;
import gate.creole.ontology.LiteralOrONodeID;
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.OURI;
import gate.creole.ontology.OBNodeID;
import gate.creole.ontology.OConstants.QueryLanguage;
import gate.creole.ontology.OInstance;
import gate.creole.ontology.ONodeID;
import gate.creole.ontology.RDFProperty;
import gate.creole.ontology.impl.*;
import gate.util.ClosableIterator;
import java.io.File;
import java.util.Vector;
import java.util.Collection;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.log4j.Logger;
import org.openrdf.model.BNode;
import org.openrdf.model.Literal;
import org.openrdf.model.Statement;
import org.openrdf.model.URI;
import org.openrdf.query.MalformedQueryException;
import org.openrdf.query.QueryEvaluationException;
import org.openrdf.rio.RDFWriter;
import org.openrdf.rio.n3.N3Writer;
import org.openrdf.rio.ntriples.NTriplesWriter;
import org.openrdf.rio.rdfxml.RDFXMLWriter;
import org.openrdf.rio.turtle.TurtleWriter;
import org.openrdf.model.vocabulary.RDFS;
import org.openrdf.model.vocabulary.OWL;
import org.openrdf.rio.RDFFormat;
import org.openrdf.model.Resource;
import org.openrdf.model.vocabulary.RDF;
import org.openrdf.repository.RepositoryConnection;
import org.openrdf.repository.RepositoryException;
import org.openrdf.repository.RepositoryResult;
import org.openrdf.model.Value;
import org.openrdf.model.impl.BNodeImpl;
import org.openrdf.model.impl.URIImpl;
import org.openrdf.query.BindingSet;
import org.openrdf.query.TupleQueryResult;
/**
* Implementation of the GATE Ontology Services. This class provides an
* implementation of each and every service defined under the OntologyService interface.
*
* @author Niraj Aswani
* @author Johann Petrak
*/
public class OntologyServiceImplSesame implements OntologyService {
// ***************************************************************************
// **** CONSTANTS ************************************************************
// ***************************************************************************
private static final org.openrdf.model.URI IMPORT_CONTEXT_URI =
new org.openrdf.model.impl.URIImpl(
"http://gate.ac.uk/dummyuri/OWLIM3OntologyPlugin/#ImportContext");
private static final org.openrdf.model.URI DATA_CONTEXT_URI =
new org.openrdf.model.impl.URIImpl(
"http://gate.ac.uk/dummyuri/OWLIM3OntologyPlugin/#DataContext");
private static final org.openrdf.model.URI SYSTEM_IMPORT_CONTEXT_URI =
new org.openrdf.model.impl.URIImpl(
"http://gate.ac.uk/dummyuri/OWLIM3OntologyPlugin/#SystemImportContext");
// ***************************************************************************
// **** CONSTANTS for prepared queries and the assiciated query variables
// ***************************************************************************
private Logger logger;
protected SesameManager sesameManager;
private RepositoryConnection repositoryConnection;
public final AbstractOntologyImplSesame ontology;
private String ontologyUrl;
/**
* Constructor
*/
public OntologyServiceImplSesame(AbstractOntologyImplSesame o) {
super();
ontology = o;
logger = Logger.getLogger(this.getClass().getName());
}
// ***************************************************************************
// *** METHODS RELATED TO THE ONTOLOGY AS A WHOLE
// ***************************************************************************
// ********** CREATION, INITIALIZATION, SHUTDOWN
/**
* Create an unmanaged repository in the given data directory from the
* given configuration data string.
*
* @param dataDir
* @param configData
*/
public void createRepository(File dataDir, String configData) {
sesameManager = new SesameManager();
sesameManager.createUnmanagedRepository(dataDir, configData);
repositoryConnection = sesameManager.getRepositoryConnection();
try {
repositoryConnection.setAutoCommit(true);
} catch (RepositoryException ex) {
sesameManager.disconnect();
throw new GateOntologyException("Could not set autocommit");
}
init();
}
/**
* Create a managed repository at the given repository location, which could
* either be a directory or a sesame server, with the given repository ID
* from theconfiguration file at the given URL. The configuration fiel should
* be a configuration file template with the template variable "id" which
* will be replaced with the repository ID.
*
* @param repoLoc
* @param repositoryID
* @param configFileURL
*/
void createManagedRepository(URL repoLoc, String repositoryID, URL configFileURL) {
HashMap<String, String> map = new HashMap<String, String>();
map.put("id", repositoryID);
sesameManager = new SesameManager();
String configData;
try {
InputStream is = configFileURL.openStream();
configData = IOUtils.toString(is);
IOUtils.closeQuietly(is);
} catch (IOException ex) {
throw new GateOntologyException("Cannot read config file " + configFileURL, ex);
}
sesameManager.connectToLocation(repoLoc);
Set<String> repositories = sesameManager.getRepositories();
if (repositories.contains(repositoryID)) {
sesameManager.disconnect();
throw new GateOntologyException("Repository with this ID already exists: " + repositoryID);
}
configData = SesameManager.substituteConfigTemplate(configData, map);
//logger.debug("Config file is: \n" + configData);
sesameManager.createRepository(configData);
repositoryConnection = sesameManager.getRepositoryConnection();
try {
repositoryConnection.setAutoCommit(true);
} catch (RepositoryException ex) {
sesameManager.disconnect();
throw new GateOntologyException("Could not set autocommit");
}
init();
}
/**
* Conect to the repository with the given repository ID
* at the given repository URL location, which could
* be either a directory or a sesame server.
*
* @param repositoryURL
* @param repositoryID
*/
void connectToRepository(URL repositoryURL, String repositoryID) {
sesameManager = new SesameManager();
logger.debug("Service: calling connectToRepository for id " + repositoryID);
sesameManager.connectToRepository(repositoryURL, repositoryID);
repositoryConnection = sesameManager.getRepositoryConnection();
try {
repositoryConnection.setAutoCommit(true);
} catch (RepositoryException ex) {
sesameManager.disconnect();
throw new GateOntologyException("Could not set autocommit");
}
init();
}
/**
* Initialize the ontology service. This methods prepares the ontology service
* for use. It must be called right after the repository has been created
* or has been connected to.
*/
private void init() {
// once we have created a repository or connected to a repository,
// do all the init stuff for which we need the repository
// connection: mainly prepare queries.
initQueries("default");
}
/**
* Shutdown the repository. This must be done before the the object of this
* class is destroyed!
*/
public void shutdown() {
sesameManager.disconnect();
}
// *************** IMPORT / EXPORT *******************************************
public void readOntologyData(File selectedFile, String baseURI,
OntologyFormat ontologyFormat, boolean asImport) {
org.openrdf.model.URI contextURI;
if (!asImport) {
contextURI = DATA_CONTEXT_URI;
} else {
contextURI = IMPORT_CONTEXT_URI;
}
try {
repositoryConnection.add(selectedFile, baseURI,
ontologyFormat2RDFFormat(ontologyFormat), contextURI);
} catch (Exception ex) {
throw new GateOntologyException(
"Could not load/import ontology data from file " +
selectedFile.getAbsolutePath(), ex);
}
}
public void readOntologyData(InputStream is, String baseURI,
OntologyFormat ontologyFormat, boolean asImport) {
org.openrdf.model.URI contextURI;
if (!asImport) {
contextURI = DATA_CONTEXT_URI;
} else {
contextURI = IMPORT_CONTEXT_URI;
}
try {
repositoryConnection.add(is, baseURI,
ontologyFormat2RDFFormat(ontologyFormat), contextURI);
} catch (Exception ex) {
throw new GateOntologyException(
"Could not load/import ontology data from input stream ", ex);
}
}
public void readOntologyData(Reader ir, String baseURI,
OntologyFormat ontologyFormat, boolean asImport) {
org.openrdf.model.URI contextURI;
if (!asImport) {
contextURI = DATA_CONTEXT_URI;
} else {
contextURI = IMPORT_CONTEXT_URI;
}
try {
repositoryConnection.add(ir, baseURI,
ontologyFormat2RDFFormat(ontologyFormat), contextURI);
} catch (Exception ex) {
throw new GateOntologyException(
"Could not load/import ontology data from reader ", ex);
}
}
public void writeOntologyData(Writer out, OntologyFormat ontologyFormat,
boolean includeImports) {
RDFWriter writer = getRDFWriter4Format(out, ontologyFormat);
try {
if (includeImports) {
repositoryConnection.export(writer, DATA_CONTEXT_URI, IMPORT_CONTEXT_URI);
} else {
repositoryConnection.export(writer, DATA_CONTEXT_URI);
}
} catch (Exception ex) {
throw new GateOntologyException("Could not write ontology data",ex);
}
}
public void writeOntologyData(OutputStream out, OntologyFormat ontologyFormat,
boolean includeImports) {
RDFWriter writer = getRDFWriter4Format(out, ontologyFormat);
try {
if (includeImports) {
repositoryConnection.export(writer, DATA_CONTEXT_URI, IMPORT_CONTEXT_URI);
} else {
repositoryConnection.export(writer, DATA_CONTEXT_URI);
}
} catch (Exception ex) {
throw new GateOntologyException("Could not write ontology data",ex);
}
}
public void loadSystemImport(File selectedFile,
String baseURI, OntologyFormat ontologyFormat) {
org.openrdf.model.URI contextURI = SYSTEM_IMPORT_CONTEXT_URI;
try {
repositoryConnection.add(selectedFile,
baseURI, ontologyFormat2RDFFormat(ontologyFormat),
contextURI);
} catch (Exception ex) {
throw new GateOntologyException("Could not import system file " +
selectedFile.getAbsolutePath(), ex);
}
}
// *************** OTHER METHODS RELATED TO THE ONTOLOGY AS A WHOLE **********
/**
* The method removes all data from the ontology, including imports and
* the system imports.
*/
public void cleanOntology() throws GateOntologyException {
try {
repositoryConnection.clear();
} catch (Exception sue) {
throw new GateOntologyException("error while cleaning repository:",
sue);
}
}
/**
* From all the data and imports so far loaded, gather the set of
* all ontology import URIs.
*
* @return
*/
public Set<String> getImportURIStrings() {
Set<String> uris = new HashSet<String>();
RepositoryResult<Statement> result;
try {
// TODO: should we remove "system" import URIs here?
// I tend to not do this here, instead ignore them in the resolveImports
// method ...
result = repositoryConnection.getStatements(null, OWL.IMPORTS, null, false);
while(result.hasNext()) {
String v = result.next().getObject().stringValue();
uris.add(v);
}
} catch (RepositoryException ex) {
throw new GateOntologyException("Problem getting the import statements",ex);
}
return uris;
}
public Set<OURI> getOntologyURIs() {
// apparently, this can return several ontology URIs, of which only
// the one that is not object of an owl:priorVersion property is the
// the one we want?
// TODO: this just checks if the URI found is equal to one of the
// import uri strings as present in the ontology, but does not check
// against the actual import URI as it will be created from those
// improt URI strings by replacing relative URI references.
// Not sure how to really deal with this for now .... JP
Set<OURI> theURIs =
new HashSet<OURI>();
Set<String> importURIs = getImportURIStrings();
qp_getOntologyURIs.evaluate();
while(qp_getOntologyURIs.hasNext()) {
String someURI = qp_getOntologyURIs.nextFirstAsString();
OURI u = new OURIImpl(someURI);
if(!importURIs.contains(u.toString())) {
theURIs.add(u);
}
}
return theURIs;
}
/**
* The method allows adding version information to the repository.
*
* @param versionInfo
*/
public void setVersion(String versionInfo) {
addUULStatement(this.ontologyUrl, OWL.VERSIONINFO.toString(), versionInfo, null);
}
/**
* The method returns the version information of the repository.
*
* @return
*/
public String getVersion() throws GateOntologyException {
try {
RepositoryResult<Statement> iter =
repositoryConnection.getStatements(getResource(this.ontologyUrl),
makeSesameURI(OWL.VERSIONINFO.toString()), null, true);
while (iter.hasNext()) {
Statement stmt = iter.next();
return stmt.getObject().toString();
}
} catch (Exception e) {
throw new GateOntologyException("Problem getting the ontology version: ", e);
}
return null;
}
public void setOntologyURI(OURI theURI) {
addUUUStatement(theURI.toString(), RDF.TYPE.toString(), OWL.ONTOLOGY.toString());
}
// ***************************************************************************
// **** CLASS RELATED METHODS
// ***************************************************************************
/**
* The method allows adding a class to repository.
*
* @param classURI
*/
public void addClass(String classURI, byte classType) {
switch (classType) {
case OConstants.OWL_CLASS:
addUUUStatement(classURI, RDF.TYPE.toString(), OWL.CLASS.toString());
return;
default:
addUUUStatement(classURI, RDF.TYPE.toString(), OWL.RESTRICTION.toString());
return;
}
}
/**
* Given a class to delete, it removes it from the repository.
*
* @param classURI
* @param removeSubTree
* - if set to true, removes all its subclasses and instances as
* well, otherwise shifts all subclasses and instances to its parent
* node
* @return a list of other resources, which got removed as a result of this
* deletion
*/
// TODO: !!! "its instances:" what if instances also belong to other classes
// that do not get removed?
// TODO: subclasses: what if a subclass also is a subclass of some other
// class that does not get removed?
// test/clarify in API!
public String[] removeClass(String classURI,
boolean removeSubTree) throws GateOntologyException {
logger.debug("removeClass");
//System.out.println("removeClass: "+classURI);
ResourceInfo[] superClasses =
getSuperClasses(classURI, OConstants.Closure.DIRECT_CLOSURE);
List<String> deletedResources = new ArrayList<String>();
// TODO: JP !!!! need a different way to check for explicit !!
//if(removeUUUStatement(classURI, RDF.TYPE.toString(), null) == 0) {
// throw new GateOntologyException(classURI + " is not an explicit resource");
//}
//else {
// currentEventsLog.addEvent(new OEvent(classURI, RDF.TYPE.toString(), null, false));
// deletedResources.add(classURI);
//}
removeUUUStatement(classURI, RDF.TYPE.toString(), null);
deletedResources.add(classURI);
try {
startTransaction(null);
repositoryConnection.remove(getResource(classURI), makeSesameURI(RDFS.SUBCLASSOF.toString()),
null);
endTransaction(null);
} catch (Exception sue) {
throw new GateOntologyException("error while removing a class:" + classURI, sue);
}
// this should happen only if removeSubTree is set to true
if (removeSubTree) {
//ResourceInfo[] subClasses =
// getSubClassesOld(classURI, OConstants.Closure.DIRECT_CLOSURE);
Set<OClass> subClasses = getSubClasses(
string2ONodeID(classURI), OConstants.Closure.DIRECT_CLOSURE);
//for (int i = 0; i < subClasses.length; i++) {
for (OClass subclass : subClasses) {
String[] removedResources =
//removeClass(subClasses[i].getUri(), true);
removeClass(subclass.getONodeID().toString(), true);
deletedResources.addAll(Arrays.asList(removedResources));
}
ClosableIterator<OInstance> instIt =
getInstancesIterator(string2ONodeID(classURI), Closure.DIRECT_CLOSURE);
while (instIt.hasNext()) {
String[] removedResources = removeIndividual(instIt.next().toString());
deletedResources.addAll(Arrays.asList(removedResources));
}
} else {
//ResourceInfo[] subClasses =
// getSubClassesOld(classURI, OConstants.Closure.DIRECT_CLOSURE);
Set<OClass> subClasses = getSubClasses(
string2ONodeID(classURI), OConstants.Closure.DIRECT_CLOSURE);
//for (int i = 0; i < subClasses.length; i++) {
for (OClass subclass : subClasses) {
//removeSubClass(classURI, subClasses[i].getUri());
removeSubClass(classURI,subclass.getONodeID().toString());
for (int j = 0; j < superClasses.length; j++) {
//addSubClass(superClasses[j].getUri(), subClasses[i].getUri());
addSubClass(superClasses[j].getUri(), subclass.getONodeID().toString());
}
}
ClosableIterator<OInstance> instIt =
getInstancesIterator(string2ONodeID(classURI), Closure.DIRECT_CLOSURE);
//for (int i = 0; i < individuals.length; i++) {
while(instIt.hasNext()) {
removeUUUStatement(instIt.next().toString(), RDF.TYPE.toString(), classURI);
for (int j = 0; j < superClasses.length; j++) {
addUUUStatement(instIt.next().toString(), RDF.TYPE.toString(), superClasses[j].getUri());
}
}
}
try {
startTransaction(null);
RepositoryResult<Statement> iter =
repositoryConnection.getStatements(null, makeSesameURI(RDFS.DOMAIN.toString()), getResource(classURI), true);
endTransaction(null);
while (iter.hasNext()) {
Statement stmt = iter.next();
Resource resource = stmt.getSubject();
String[] removedResources =
removePropertyFromOntology(resource.toString(), removeSubTree);
deletedResources.addAll(Arrays.asList(removedResources));
}
startTransaction(null);
iter = repositoryConnection.getStatements(null, makeSesameURI(RDFS.RANGE.toString()), getResource(classURI), true);
endTransaction(null);
while (iter.hasNext()) {
Statement stmt = iter.next();
Resource resource = stmt.getSubject();
String[] removedResources =
removePropertyFromOntology(resource.toString(), removeSubTree);
deletedResources.addAll(Arrays.asList(removedResources));
}
} catch (Exception e) {
throw new GateOntologyException(e);
}
// finaly remove all statements concerning this resource
try {
startTransaction(null);
repositoryConnection.remove(getResource(classURI), null, null);
if (!(getResource(classURI) instanceof BNode)) {
repositoryConnection.remove((Resource) null, makeSesameURI(classURI), null);
}
repositoryConnection.remove((Resource) null, null, getResource(classURI));
endTransaction(null);
} catch (Exception sue) {
throw new GateOntologyException("error while removing a class:" + classURI, sue);
}
Collections.reverse(deletedResources);
//System.out.println("deletedResources is: "+deletedResources);
return listToArray(deletedResources);
}
/**
* The method returns if the current repository has a class with URI that
* matches with the class parameter.
*
* @return
*/
public boolean hasClass(String classURI)
{
//System.out.println("Checking for class: "+classURI);
try {
// TODO: make two versions: one taking ONodeID and one String
boolean hasOWLClass =
repositoryConnection.hasStatement(string2SesameResource(classURI),
RDF.TYPE, OWL.CLASS, true);
if (!hasOWLClass) {
boolean hasRDFSClass =
repositoryConnection.hasStatement(string2SesameResource(classURI),
RDF.TYPE, RDFS.CLASS, true);
//System.out.println("OWL class not found, RDFS class "+hasRDFSClass);
return hasRDFSClass;
} else {
//System.out.println("OWL class found");
return true;
}
} catch (RepositoryException ex) {
throw new GateOntologyException("Could not do hasStatement for class "+classURI);
}
}
public boolean containsURI(OURI theURI) {
try {
return
repositoryConnection.hasStatement(oNodeID2SesameResource(theURI), null, null, true) ||
repositoryConnection.hasStatement(null, (URI) oNodeID2SesameResource(theURI), null, true) ||
repositoryConnection.hasStatement(null, null, oNodeID2SesameResource(theURI), true);
} catch (RepositoryException ex) {
throw new GateOntologyException("Problem when looking up URI "+theURI,ex);
}
}
public Set<OClass> getClasses(boolean topOnly) {
Set<OClass> theClasses = new HashSet<OClass>();
ClosableIterator<OClass> ci = getClassesIterator(topOnly);
while(ci.hasNext()) {
theClasses.add(ci.next());
}
return theClasses;
}
public ClosableIterator<OClass> getClassesIterator(boolean top) {
if(top) {
return new UtilResourceQueryIterator<OClass>(this, qp_getClassesTopAll, OClass.class);
} else {
return new UtilResourceQueryIterator<OClass>(this, qp_getClassesAllAll, OClass.class);
}
}
public Set<OClass> getClassesByName(String name) {
String query;
Set<OClass> classes = new HashSet<OClass>();
UtilTupleQueryIterator q;
String qs = qs_getClassesByNameNoW3.replaceAll("yyy1", "\""+name+"\"");
q = new UtilTupleQueryIterator(
repositoryConnection, qs, ql_getClassesByNameNoW3);
while (q.hasNext()) {
Vector<Value> tuple = q.nextAsValue();
Value t1 = tuple.get(0);
String uristring = ((org.openrdf.model.URI) t1).toString();
OURI ourURI = ontology.createOURI(uristring);
classes.add(new OClassImpl(ourURI, ontology, this));
}
q.close();
return classes;
}
private OClass createRestrictionFromURI(String uriString, String bnodeID) {
OBNodeID uri = new OBNodeIDImpl(bnodeID);
return createRestrictionFromURI(uriString, uri);
}
private OClass createRestrictionFromURI(String uriString, ONodeID uri) {
if (uriString.equals("http://www.w3.org/2002/07/owl#cardinality")) {
return new CardinalityRestrictionImpl(uri, ontology, this);
} else if (uriString.equals("http://www.w3.org/2002/07/owl#allValuesFrom")) {
return new AllValuesFromRestrictionImpl(uri, ontology, this);
} else if (uriString.equals("http://www.w3.org/2002/07/owl#minCardinality")) {
return new MinCardinalityRestrictionImpl(uri, ontology, this);
} else if (uriString.equals("http://www.w3.org/2002/07/owl#maxCardinality")) {
return new MaxCardinalityRestrictionImpl(uri, ontology, this);
} else if (uriString.equals("http://www.w3.org/2002/07/owl#someValuesFrom")) {
return new SomeValuesFromRestrictionImpl(uri, ontology, this);
} else if (uriString.equals("http://www.w3.org/2002/07/owl#hasValue")) {
return new HasValueRestrictionImpl(uri, ontology, this);
} else if (uriString.equals("http://www.w3.org/2002/07/owl#oneOf")) {
System.out.println("Warning: restriction oneOf not yet implemented in createRestrictionFromURI"+uri);
return new AnonymousClassImpl(uri, ontology, this);
}
throw new GateOntologyException("createRestrictionFromURI not for this yet: " + uriString);
}
/**
* Returns if the given class is a topOnly class.
*
* @param classURI
* @return
*/
public boolean isTopClass(String classURI) {
// TODO: maybe this can be done more efficiently?
return getSuperClasses(classURI, OConstants.Closure.DIRECT_CLOSURE).length == 0;
}
/**
* Returns whether the theSuperClass is indeed a super class of the
* theSubClassURI.
*
* @param theSuperClassURI
* @param theSubClassURI
* @param direct
* @return
*/
public boolean isSuperClassOf(String theSuperClassURI,
String theSubClassURI, Closure direct)
{
Resource r = getResource(theSubClassURI);
String queryRep = string2Turtle(theSubClassURI);
String query = "";
query =
"Select distinct SUPER FROM {" + queryRep + "} rdfs:subClassOf {SUPER}" + " WHERE SUPER!=" + queryRep + " AND SUPER != ALL ( " + " select distinct B FROM {B} owl:equivalentClass {" + queryRep + "} )";
List<String> list = new ArrayList<String>();
addSerqlQueryResultToCollection(query, list);
if (direct == OConstants.Closure.DIRECT_CLOSURE) {
Set<String> toDelete = new HashSet<String>();
for (int i = 0; i < list.size(); i++) {
String string = list.get(i);
if (toDelete.contains(string)) {
continue;
}
queryRep = string2Turtle(string);
query =
"Select distinct SUPER FROM {" + queryRep + "} rdfs:subClassOf {SUPER}" +
" WHERE SUPER!=" + queryRep + " AND SUPER != ALL ( " +
" select distinct B FROM {B} owl:equivalentClass {" + queryRep + "})";
addSerqlQueryResultToCollection(query, toDelete);
}
list.removeAll(toDelete);
}
// here if the list contains the uri of the super class
// we return true;
return list.contains(theSuperClassURI);
}
protected void addSerqlQueryResultToCollection(String query, Collection<String> coll) {
addSerqlQueryResultToCollection(query, coll, false);
}
protected void addSerqlQueryResultToCollection(String query, Collection<String> coll,
boolean internIt) {
UtilTupleQueryIterator result =
new UtilTupleQueryIterator(repositoryConnection,query,QueryLanguage.SERQL);
//UtilTupleQueryIterator result = performSerqlQuery(query);
while (result.hasNext()) {
if (internIt) {
coll.add(result.nextFirstAsString().intern());
} else {
String tmp = result.nextFirstAsString();
//System.out.println("Adding to collection: "+tmp);
coll.add(tmp);
}
}
result.close();
}
protected void addSerqlQueryResultValuesToCollection(String query, Collection<Value> coll) {
UtilTupleQueryIterator result =
new UtilTupleQueryIterator(repositoryConnection,query,QueryLanguage.SERQL);
//UtilTupleQueryIterator result = performSerqlQuery(query);
while (result.hasNext()) {
coll.add(result.nextFirstAsValue());
}
result.close();
}
protected boolean hasSerqlQueryResultRows(String query) {
//UtilTupleQueryIterator result = performSerqlQuery(query);
UtilTupleQueryIterator result =
new UtilTupleQueryIterator(repositoryConnection,query,QueryLanguage.SERQL);
boolean hasResult = result.hasNext();
result.close();
return hasResult;
}
protected UtilTupleQueryIterator performSerqlQuery(String serqlQuery) {
return
new UtilTupleQueryIterator(repositoryConnection,serqlQuery,QueryLanguage.SERQL);
}
/**
* Returns whether the theSubClass is indeed a sub class of the
* theSuperClassURI.
*
* @param theSuperClassURI
* @param theSubClassURI
* @param direct
* @return
*/
public boolean isSubClassOf(String theSuperClassURI,
String theSubClassURI, Closure direct) {
return isSuperClassOf(theSuperClassURI, theSubClassURI,
direct);
}
/**
* Given a property URI, this method returns an object of Property
*
* @param repositoryID
* @param thePropertyURI
* @return
* @throws GateOntologyException
*/
public Property getPropertyFromOntology(String thePropertyURI)
{
// here we need to check which type of property it is
return createPropertyObject(thePropertyURI);
}
/**
* Checks whether the two classes defined as same in the ontology.
*
* @param theClassURI1
* @param theClassURI2
* @return
* @throws Exception
*/
public boolean isEquivalentClassAs(String theClassURI1,
String theClassURI2)
{
String queryRep1 = string2Turtle(theClassURI1);
String queryRep2 = string2Turtle(theClassURI2);
String query =
"SELECT * FROM {" + queryRep1 + "} owl:equivalentClass {" + queryRep2 + "}";
return hasSerqlQueryResultRows(query);
}
// *******************************************************************
// property methods
// *******************************************************************
// **************
// Annotation Property
// ************
/**
* Creates a new AnnotationProperty.
*
* @param aPropertyURI
* URI of the property to be added into the ontology. Done
*/
public void addAnnotationProperty(String aPropertyURI)
throws GateOntologyException {
addUUUStatement(aPropertyURI, RDF.TYPE.toString(), OWL.ANNOTATIONPROPERTY.toString());
}
/**
* This method returns a set of all properties where the current resource has
* been specified as one of the domain resources. Please note that this method
* is different from the getAllSetProperties() method which returns a set of
* properties set on the resource. For each property in the ontology, this
* method checks if the current resource is valid domain. If so, the property
* is said to be applicable, and otherwise not..
*
* @param theResourceURI
* @return
*/
public Property[] getPropertiesWithResourceAsDomain(
String theResourceURI)
{
List<Property> list = new ArrayList<Property>();
HashSet<String> toCheck = new HashSet<String>();
try {
if (repositoryConnection.hasStatement(
string2SesameResource(theResourceURI),
RDF.TYPE,
OWL.CLASS,
true // TODO: include inferred: true or false here?
)) {
String queryRep1 = string2Turtle(theResourceURI);
String queryRep = "{"+queryRep1+"}";
String query =
"Select distinct SUPER FROM " + queryRep + " rdfs:subClassOf {SUPER}" + " WHERE SUPER!=" + queryRep1 + " AND SUPER != ALL ( " + " select distinct B FROM {B} owl:equivalentClass " + queryRep + ")";
addSerqlQueryResultToCollection(query, toCheck);
toCheck.add(theResourceURI);
} else if (repositoryConnection.hasStatement(
string2SesameResource(theResourceURI),
RDF.TYPE,
RDF.PROPERTY, true)) {
String queryRep1 = string2Turtle(theResourceURI);
String queryRep = "{"+queryRep1+"}";
String query =
"Select distinct SUPER FROM " + queryRep + " rdfs:subPropertyOf {SUPER}" + " WHERE SUPER!=" + queryRep1 + " AND SUPER != ALL ( " + " select distinct B FROM {B} owl:equivalentProperty " + queryRep + ")";
addSerqlQueryResultToCollection(query, toCheck);
toCheck.add(theResourceURI);
} else {
// it is an instance
String queryRep1 = string2Turtle(theResourceURI);
String query =
"Select DISTINCT B from {X} rdf:type {B} WHERE X=" + queryRep1 ;
addSerqlQueryResultToCollection(query, toCheck, true);
}
} catch (Exception e) {
throw new GateOntologyException("Error getting statements", e);
}
String query =
"Select distinct X FROM {X} rdf:type {<" + OWL.ANNOTATIONPROPERTY + ">}";
UtilTupleQueryIterator result = performSerqlQuery(query);
while (result.hasNext()) {
String anAnnProp = result.nextFirstAsString();
list.add(new Property(OConstants.ANNOTATION_PROPERTY, anAnnProp));
}
result.close();
boolean allowSystemStatements = this.returnSystemStatements;
this.returnSystemStatements = true;
Property[] props = listToPropertyArray(list);
this.returnSystemStatements = allowSystemStatements;
// now we obtain all datatype properties
list = new ArrayList<Property>();
query = "Select X FROM {X} rdf:type {<" + OWL.DATATYPEPROPERTY + ">}";
//iter = performQuery(query);
result = performSerqlQuery(query);
while (result.hasNext()) {
String anAnnProp = result.nextFirstAsString();
// for each property we obtain its domain and search for the
// resourceURI in it
query =
"select distinct Y from {<" + anAnnProp + ">} rdfs:domain {Y}";
Set<String> set = new HashSet<String>();
addSerqlQueryResultToCollection(query, set, true);
if (set.isEmpty()) {
list.add(new Property(OConstants.DATATYPE_PROPERTY, anAnnProp.toString()));
}
set = new HashSet<String>(reduceToMostSpecificClasses(set));
set.retainAll(toCheck);
if (!set.isEmpty()) {
list.add(new Property(OConstants.DATATYPE_PROPERTY, anAnnProp.toString()));
}
}
result.close();
query = "Select X FROM {X} rdf:type {<" + OWL.OBJECTPROPERTY + ">}";
result = performSerqlQuery(query);
while (result.hasNext()) {
String anAnnProp = result.nextFirstAsString();
// for each property we obtain its domain and search for the
// resourceURI in it
query =
"select distinct Y from {<" + anAnnProp + ">} rdfs:domain {Y}";
Set<String> set = new HashSet<String>();
addSerqlQueryResultToCollection(query, set, true);
set = new HashSet<String>(reduceToMostSpecificClasses(set));
byte type = OConstants.OBJECT_PROPERTY;
if (set.isEmpty()) {
if (isSymmetricProperty(anAnnProp.toString().intern())) {
type = OConstants.SYMMETRIC_PROPERTY;
} else if (isTransitiveProperty(anAnnProp.toString().intern())) {
type = OConstants.TRANSITIVE_PROPERTY;
}
list.add(new Property(type, anAnnProp.toString()));
continue;
}
set.retainAll(toCheck);
if (!set.isEmpty()) {
if (isSymmetricProperty(anAnnProp.toString().intern())) {
type = OConstants.SYMMETRIC_PROPERTY;
} else if (isTransitiveProperty(anAnnProp.toString().intern())) {
type = OConstants.TRANSITIVE_PROPERTY;
}
list.add(new Property(type, anAnnProp.toString()));
}
}
result.close();
Property[] props1 = listToPropertyArray(list);
Property[] toProps = new Property[props.length + props1.length];
for (int i = 0; i < props.length; i++) {
toProps[i] = props[i];
}
for (int i = 0; i < props1.length; i++) {
toProps[props.length + i] = props1[i];
}
return toProps;
}
/**
* This method returns a set of all properties where the current resource has
* been specified as one of the range resources. Please note that this method
* is different from the getAllSetProperties() method which returns a set of
* properties set on the resource. For each property in the ontology, this
* method checks if the current resource is valid range. If so, the property
* is said to be applicable, and otherwise not.
*
* @return
*/
public Property[] getPropertiesWithResourceAsRange(String theResourceURI)
{
List<Property> list = new ArrayList<Property>();
HashSet<String> toCheck = new HashSet<String>();
try {
if (repositoryConnection.hasStatement(getResource(theResourceURI), makeSesameURI(RDF.TYPE.toString()),
getResource(OWL.CLASS.toString()), true)) {
String queryRep = string2Turtle(theResourceURI);
String query =
"Select distinct SUPER FROM {" + queryRep + "} rdfs:subClassOf {SUPER}" + " WHERE SUPER!=" + queryRep + " AND SUPER != ALL ( " + " select distinct B FROM {B} owl:equivalentClass {" + queryRep + "} )";
addSerqlQueryResultToCollection(query, toCheck);
toCheck.add(theResourceURI);
} else if (repositoryConnection.hasStatement(getResource(theResourceURI), makeSesameURI(RDF.TYPE.toString()),
getResource(RDF.PROPERTY.toString()), true)) {
String queryRep = string2Turtle(theResourceURI);
String query =
"Select distinct SUPER FROM {"+queryRep+"} rdfs:subPropertyOf {SUPER}" +
" WHERE SUPER!=" + queryRep +
" AND SUPER != ALL ( " +
" select distinct B FROM {B} owl:equivalentProperty {" + queryRep + "})";
addSerqlQueryResultToCollection(query, toCheck);
toCheck.add(theResourceURI);
} else {
// it is an instance
String query =
"Select DISTINCT B from {X} rdf:type {B} WHERE X=<" + theResourceURI + ">";
addSerqlQueryResultToCollection(query, toCheck, true);
}
} catch (Exception e) {
throw new GateOntologyException("Could not get statements", e);
}
String query =
"Select distinct X FROM {X} rdf:type {<" + OWL.ANNOTATIONPROPERTY + ">}";
UtilTupleQueryIterator result = performSerqlQuery(query);
while (result.hasNext()) {
String anAnnProp = result.nextFirstAsString();
list.add(new Property(OConstants.ANNOTATION_PROPERTY, anAnnProp));
}
result.close();
boolean allowSystemStatements = this.returnSystemStatements;
this.returnSystemStatements = true;
Property[] props = listToPropertyArray(list);
this.returnSystemStatements = allowSystemStatements;
// now we obtain all datatype properties
list = new ArrayList<Property>();
query = "Select X FROM {X} rdf:type {<" + OWL.OBJECTPROPERTY + ">}";
result = performSerqlQuery(query);
while (result.hasNext()) {
String anAnnProp = result.nextFirstAsString();
// for each property we obtain its domain and search for the
// resourceURI in it
query =
"select distinct Y from {<" + anAnnProp + ">} rdfs:range {Y}";
Set<String> set = new HashSet<String>();
addSerqlQueryResultToCollection(query, set, true);
set = new HashSet<String>(reduceToMostSpecificClasses(set));
byte type = OConstants.OBJECT_PROPERTY;
if (set.isEmpty()) {
if (isSymmetricProperty(anAnnProp.toString().intern())) {
type = OConstants.SYMMETRIC_PROPERTY;
} else if (isTransitiveProperty(anAnnProp.toString().intern())) {
type = OConstants.TRANSITIVE_PROPERTY;
}
list.add(new Property(type, anAnnProp.toString()));
}
set.retainAll(toCheck);
if (!set.isEmpty()) {
if (isSymmetricProperty(anAnnProp.toString().intern())) {
type = OConstants.SYMMETRIC_PROPERTY;
} else if (isTransitiveProperty(anAnnProp.toString().intern())) {
type = OConstants.TRANSITIVE_PROPERTY;
}
list.add(new Property(type, anAnnProp.toString()));
}
}
result.close();
Property[] props1 = listToPropertyArray(list);
Property[] toProps = new Property[props.length + props1.length];
for (int i = 0; i < props.length; i++) {
toProps[i] = props[i];
}
for (int i = 0; i < props1.length; i++) {
toProps[props.length + i] = props1[i];
}
return toProps;
}
/**
* Gets the annotation properties set on the specified resource
*
* @param theResourceURI
* @return
*/
public Property[] getAnnotationProperties(String theResourceURI)
{
List<Property> list = new ArrayList<Property>();
String queryRep = string2Turtle(theResourceURI);
String query =
"Select DISTINCT X FROM {X} rdf:type {<" + OWL.ANNOTATIONPROPERTY + ">} WHERE EXISTS (SELECT * FROM {" + queryRep + "} X {Z})";
UtilTupleQueryIterator result = performSerqlQuery(query);
while (result.hasNext()) {
list.add(new Property(OConstants.ANNOTATION_PROPERTY, result.nextFirstAsString()));
}
result.close();
boolean allowSystemStatements = this.returnSystemStatements;
this.returnSystemStatements = true;
Property[] props = listToPropertyArray(list);
this.returnSystemStatements = allowSystemStatements;
return props;
}
/**
* Gets the RDF properties set on the specified resource
*
* @param theResourceURI
* @return
*/
public Property[] getRDFProperties(String theResourceURI)
{
List<Property> list = new ArrayList<Property>();
String queryRep = string2Turtle(theResourceURI);
String query =
"Select distinct X FROM {X} rdf:type {<" + RDF.PROPERTY.toString() + ">} WHERE EXISTS (SELECT * FROM {" + queryRep + "} X {Z})";
UtilTupleQueryIterator result = performSerqlQuery(query);
while (result.hasNext()) {
String propString = result.nextFirstAsString();
if (isAnnotationProperty(propString) || isDatatypeProperty(propString) || isObjectProperty(propString) || isTransitiveProperty(propString) || isSymmetricProperty(propString)) {
continue;
}
list.add(new Property(OConstants.RDF_PROPERTY, propString));
}
result.close();
return listToPropertyArray(list);
}
/**
* Gets the datatype properties set on the specified resource
*
* @param theResourceURI
* @return
*/
public Property[] getDatatypeProperties(String theResourceURI)
{
List<Property> list = new ArrayList<Property>();
String queryRep = string2Turtle(theResourceURI);
String query =
"Select distinct X FROM {X} rdf:type {<" + OWL.DATATYPEPROPERTY + ">} WHERE EXISTS (SELECT * FROM {" + queryRep + "} X {Z})";
UtilTupleQueryIterator result = performSerqlQuery(query);
while (result.hasNext()) {
String anAnnProp = result.nextFirstAsString();
list.add(new Property(OConstants.DATATYPE_PROPERTY, anAnnProp));
}
result.close();
return listToPropertyArray(list);
}
/**
* Gets the object properties set on the specified resource
*
* @param theResourceURI
* @return
*/
public Property[] getObjectProperties(String theResourceURI) {
List<Property> list = new ArrayList<Property>();
String queryRep = string2Turtle(theResourceURI);
String query =
"Select distinct X FROM {X} rdf:type {<" + OWL.OBJECTPROPERTY + ">} WHERE EXISTS (SELECT * FROM {" + queryRep + "} X {Z})";
UtilTupleQueryIterator result = performSerqlQuery(query);
while (result.hasNext()) {
String anAnnProp = result.nextFirstAsString();
list.add(new Property(OConstants.OBJECT_PROPERTY, anAnnProp));
}
result.close();
return listToPropertyArray(list);
}
/**
* Gets the transitive properties set on the specified resource
*
* @param theResourceURI
* @return
*/
public Property[] getTransitiveProperties(String theResourceURI)
{
List<Property> list = new ArrayList<Property>();
String queryRep = string2Turtle(theResourceURI);
String query =
"Select distinct X FROM {X} rdf:type {<" + OWL.TRANSITIVEPROPERTY + ">} WHERE EXISTS (SELECT * FROM {" + queryRep + "} X {Z})";
UtilTupleQueryIterator result = performSerqlQuery(query);
while (result.hasNext()) {
String anAnnProp = result.nextFirstAsString();
list.add(new Property(OConstants.TRANSITIVE_PROPERTY, anAnnProp));
}
result.close();
return listToPropertyArray(list);
}
/**
* Gets the symmetric properties set on the specified resource
*
* @param theResourceURI
* @return
*/
public Property[] getSymmetricProperties(String theResourceURI)
{
List<Property> list = new ArrayList<Property>();
String queryRep = string2Turtle(theResourceURI);
String query =
"Select distinct X FROM {X} rdf:type {<" + OWL.SYMMETRICPROPERTY + ">} WHERE EXISTS (SELECT * FROM {" + queryRep + "} X {Z})";
UtilTupleQueryIterator result = performSerqlQuery(query);
while (result.hasNext()) {
String anAnnProp = result.nextFirstAsString();
list.add(new Property(OConstants.SYMMETRIC_PROPERTY, anAnnProp));
}
result.close();
return listToPropertyArray(list);
}
/**
* returns if the given property is an Annotation property
*
* @param aPropertyURI
* @return Done
*/
public boolean isAnnotationProperty(String aPropertyURI)
{
String query =
"Select * FROM {X} rdf:type {<" + OWL.ANNOTATIONPROPERTY + ">} WHERE X=<" + aPropertyURI + ">";
return hasSerqlQueryResultRows(query);
}
/**
* Adds a new annotation property value and specifies the language.
*
* @param theAnnotationProperty
* the annotation property
* @param value
* the value containing some value
*/
public void addAnnotationPropertyValue(String theResourceURI, String theAnnotationPropertyURI, String value,
String language)
{
// isAnnotationProperty also checks for the correct repository so no
// need to give a call to it
if (!isAnnotationProperty(theAnnotationPropertyURI)) {
throw new GateOntologyException(
"No annotation property found with the URI :" + theAnnotationPropertyURI);
}
addUULStatement(theResourceURI, theAnnotationPropertyURI, value, language);
}
/**
* Gets the list of annotation property values
*
* @param theResourceURI
* @param theAnnotationPropertyURI
* @return
*/
public PropertyValue[] getAnnotationPropertyValues(String theResourceURI, String theAnnotationPropertyURI)
{
// isAnnotationProperty also checks for the correct repository so no
// need to give a call to it
if (!isAnnotationProperty(theAnnotationPropertyURI)) {
throw new GateOntologyException(
"No annotation property found with the URI :" + theAnnotationPropertyURI);
}
Resource r2 = getResource(theResourceURI);
String queryRep21 = "<" + theResourceURI + ">";
if (r2 instanceof BNode) {
queryRep21 = "_:" + theResourceURI;
}
List<PropertyValue> list = new ArrayList<PropertyValue>();
String query =
"Select DISTINCT Y from {X} <" + theAnnotationPropertyURI + "> {Y} WHERE X=" + queryRep21 + " AND isLiteral(Y)";
UtilTupleQueryIterator result = performSerqlQuery(query);
while (result.hasNext()) {
// TODO: how to process a literal here? Is the string representation
// we get identical with literal.getLabel()?
PropertyValue pv;
Literal literal = (Literal) result.nextFirstAsValue();
//Literal literal = (Literal)iter.getValue(i, 0);
//pv = new PropertyValue(literal.getLanguage(), literal.getLabel());
pv = new PropertyValue(literal.getLanguage(), literal.getLabel());
list.add(pv);
}
return listToPropertyValueArray(list);
}
/**
* Gets the annotation property for the given resource uri.
*
* @param repositoryID
* @param theResourceURI
* @param theAnnotationPropertyURI
* @param language
* @return
*/
public String getAnnotationPropertyValue(String theResourceURI, String theAnnotationPropertyURI, String language)
{
// isAnnotationProperty also checks for the correct repository so no
// need to give a call to it
if (!isAnnotationProperty(theAnnotationPropertyURI)) {
throw new GateOntologyException(
"No annotation property found with the URI :" + theAnnotationPropertyURI);
}
// TODO: !!! use toTurtle
Resource r2 = getResource(theResourceURI);
String queryRep21 = "<" + theResourceURI + ">";
if (r2 instanceof BNode) {
queryRep21 = "_:" + theResourceURI;
}
String query =
"Select Y from {X} <" + theAnnotationPropertyURI + "> {Y} WHERE X=" + queryRep21 + " AND isLiteral(Y) AND lang(Y) LIKE \"" + language + "\"";
UtilTupleQueryIterator result = performSerqlQuery(query);
Literal literal = null;
if (result.hasNext()) {
literal = (Literal) result.nextFirstAsValue();
}
result.close();
if (literal != null) {
return literal.getLabel();
} else {
return null;
}
}
/**
* For the current resource, the method removes the given literal for the
* given property.
*
* @param theAnnotationProperty
* @param literal
*/
public void removeAnnotationPropertyValue(String theResourceURI, String theAnnotationPropertyURI, String value,
String language)
{
// isAnnotationProperty also checks for the correct repository so no
// need to give a call to it
if (!isAnnotationProperty(theAnnotationPropertyURI)) {
throw new GateOntologyException(
"No annotation property found with the URI :" + theAnnotationPropertyURI);
}
startTransaction(null);
removeUULStatement(theResourceURI, theAnnotationPropertyURI, value,
language);
endTransaction(null);
}
/**
* Removes all values for a named property.
*
* @param theProperty
* the property
*/
public void removeAnnotationPropertyValues(String theResourceURI, String theAnnotationPropertyURI)
{
try {
// isAnnotationProperty also checks for the correct repository so
// no
// need to give a call to it
if (!isAnnotationProperty(theAnnotationPropertyURI)) {
throw new GateOntologyException(
"No annotation property found with the URI :" + theAnnotationPropertyURI);
}
startTransaction(null);
repositoryConnection.remove(
getResource(theResourceURI),
makeSesameURI(theAnnotationPropertyURI), null);
endTransaction(null);
} catch (Exception e) {
throw new GateOntologyException(
"Error while removing annotation property values " + e.getMessage(), e);
}
}
// **************
// RDFProperties
// *************
/**
* The method adds a generic property specifiying domain and range for the
* same. All classes specified in domain and range must exist.
*
* @param aPropertyURI
* @param domainClassesURIs
* @param rangeClassesTypes
* Done
*/
public void addRDFProperty(String aPropertyURI,
String[] domainClassesURIs, String[] rangeClassesTypes)
throws GateOntologyException {
addUUUStatement(aPropertyURI, RDF.TYPE.toString(), RDF.PROPERTY.toString());
if (domainClassesURIs != null) {
for (int i = 0; i < domainClassesURIs.length; i++) {
addUUUStatement(aPropertyURI, RDFS.DOMAIN.toString(), domainClassesURIs[i]);
}
}
if (rangeClassesTypes != null) {
for (int i = 0; i < rangeClassesTypes.length; i++) {
addUUUStatement(aPropertyURI, RDFS.RANGE.toString(), rangeClassesTypes[i]);
}
}
}
/**
* returns if the given property is an RDF property
*
* @param aPropertyURI
* @return Done
*/
public boolean isRDFProperty(String aPropertyURI)
{
boolean found =
isAnnotationProperty(aPropertyURI) || isDatatypeProperty(aPropertyURI) || isObjectProperty(aPropertyURI) || isTransitiveProperty(aPropertyURI) || isSymmetricProperty(aPropertyURI);
if (!found) {
String query =
"Select * FROM {X} rdf:type {<" + RDF.PROPERTY.toString() + ">} WHERE X=<" + aPropertyURI + ">";
return hasSerqlQueryResultRows(query);
} else {
return false;
}
}
// **************
// Datatype Properties
// *************
/**
* The method adds a data type property specifiying domain and range for the
* same. All classes specified in domain and range must exist.
*
* @param aPropertyURI
* @param domainClassesURIs
* @param dataTypeURI
* Done
*/
public void addDataTypeProperty(String aPropertyURI,
String[] domainClassesURIs, String dataTypeURI)
{
addUUUStatement(aPropertyURI, RDF.TYPE.toString(), OWL.DATATYPEPROPERTY.toString());
addUUUStatement(aPropertyURI, RDFS.RANGE.toString(), dataTypeURI);
if (domainClassesURIs != null) {
for (int i = 0; i < domainClassesURIs.length; i++) {
addUUUStatement(aPropertyURI, RDFS.DOMAIN.toString(), domainClassesURIs[i]);
}
}
}
/**
* Returns the datatype uri specified for the given datatype property.
*
* @param theDatatypePropertyURI
* @return
* @throws GateOntologyException
*/
public String getDatatype(String theDatatypePropertyURI)
{
// isAnnotationProperty also checks for the correct repository so no
// need to give a call to it
if (!isDatatypeProperty(theDatatypePropertyURI)) {
throw new GateOntologyException(
"Invalid DatatypeProperty :" + theDatatypePropertyURI);
}
String query =
"Select Z from {<" + theDatatypePropertyURI + ">} rdfs:range" + " {Z}";
UtilTupleQueryIterator result = performSerqlQuery(query);
String toReturn = null;
if (result.hasNext()) {
toReturn = result.nextFirstAsString();
}
result.close();
if (OntologyUtilities.getDataType(toReturn) != null) {
return toReturn;
}
return "http://www.w3.org/2001/XMLSchema#string";
}
// **************
// Symmetric Properties
// *************
/**
* The method adds a symmetric property specifying domain and range for the
* same. All classes specified in domain and range must exist.
*
* @param aPropertyURI
* @param domainAndRangeClassesURIs
* Done
*/
public void addSymmetricProperty(String aPropertyURI,
String[] domainAndRangeClassesURIs)
{
if (debug) {
logger.debug("addSymmetricProperty");
}
addUUUStatement(aPropertyURI, RDF.TYPE.toString(), OWL.SYMMETRICPROPERTY.toString());
if (domainAndRangeClassesURIs != null) {
for (int i = 0; i < domainAndRangeClassesURIs.length; i++) {
addUUUStatement(aPropertyURI, RDFS.DOMAIN.toString(), domainAndRangeClassesURIs[i]);
addUUUStatement(aPropertyURI, RDFS.RANGE.toString(), domainAndRangeClassesURIs[i]);
}
}
}
/**
* Checkes whether the two properties are Equivalent.
*
* @param aPropertyURI
* @return
* @throws GateOntologyException
*/
public boolean isEquivalentPropertyAs(String aPropertyURI1, String aPropertyURI2)
{
String query =
"Select * FROM {<" + aPropertyURI1 + ">} " + OWL.EQUIVALENTPROPERTY + " {<" + aPropertyURI2 + ">}";
return hasSerqlQueryResultRows(query);
}
/**
* for the given property, the method returns all its super properties
*
* @param aPropertyURI
* @param direct
* @return
*/
public Property[] getSuperProperties(String aPropertyURI,
Closure direct)
{
String queryRep = string2Turtle(aPropertyURI);
String query = "";
query =
"Select distinct SUPER FROM {" + queryRep + "} rdfs:subPropertyOf {SUPER}" +
" WHERE SUPER!=" + queryRep +
" AND SUPER != ALL ( " +
" select distinct B FROM {B} owl:equivalentProperty {" + queryRep + "} )";
List<String> list = new ArrayList<String>();
addSerqlQueryResultToCollection(query, list);
if (direct == OConstants.Closure.DIRECT_CLOSURE) {
Set<String> toDelete = new HashSet<String>();
for (int i = 0; i < list.size(); i++) {
String string = list.get(i);
if (toDelete.contains(string)) {
continue;
}
queryRep = string2Turtle(string);
query =
"Select distinct SUPER FROM {" + queryRep + "} rdfs:subPropertyOf {SUPER}" +
" WHERE SUPER!=" + queryRep +
" AND SUPER != ALL ( " +
" select distinct B FROM {B} owl:equivalentProperty {" + queryRep + "} )";
addSerqlQueryResultToCollection(query, toDelete);
}
list.removeAll(toDelete);
}
ArrayList<Property> properties = new ArrayList<Property>();
for (int i = 0; i < list.size(); i++) {
byte type = getPropertyType(list.get(i));
properties.add(new Property(type, list.get(i)));
}
return listToPropertyArray(properties);
}
/**
* for the given property, the method returns all its sub properties
*
* @param aPropertyURI
* @param direct
* @return
*/
public Property[] getSubProperties(String aPropertyURI,
Closure direct)
{
String queryRep = string2Turtle(aPropertyURI);
String query = "";
query =
// OLD "Select distinct SUB FROM {SUB} rdfs:subPropertyOf " + queryRep + " WHERE SUB!=" + queryRep1 + " MINUS " + " select distinct B FROM {B} owl:equivalentProperty " + queryRep;
"Select distinct SUB FROM {SUB} rdfs:subPropertyOf {" + queryRep + "} WHERE SUB!=" +
queryRep +
" AND SUB !=ALL( select distinct B FROM {B} owl:equivalentProperty {" + queryRep + "} )";
List<String> list = new ArrayList<String>();
addSerqlQueryResultToCollection(query, list);
if (direct == OConstants.Closure.DIRECT_CLOSURE) {
Set<String> toDelete = new HashSet<String>();
for (int i = 0; i < list.size(); i++) {
String string = list.get(i);
if (toDelete.contains(string)) {
continue;
}
queryRep = string2Turtle(string);
query =
"Select distinct SUB FROM {SUB} rdfs:subPropertyOf {" + queryRep +
"} WHERE SUB!=" + queryRep + " AND SUB != ALL ( " +
" select distinct B FROM {B} owl:equivalentProperty {" + queryRep + "} )";
addSerqlQueryResultToCollection(query, toDelete);
}
list.removeAll(toDelete);
}
ArrayList<Property> properties = new ArrayList<Property>();
for (int i = 0; i < list.size(); i++) {
byte type = getPropertyType(list.get(i));
properties.add(new Property(type, list.get(i)));
}
return listToPropertyArray(properties);
}
/**
* Checkes whether the two properties have a super-sub relation.
*
* @param aSuperPropertyURI
* @param aSubPropertyURI
* @param direct
* @return
*/
public boolean isSuperPropertyOf(String aSuperPropertyURI,
String aSubPropertyURI, Closure direct)
{
String queryRep = string2Turtle(aSuperPropertyURI);
String query = "";
query =
"Select distinct SUPER FROM {" + queryRep +
"} rdfs:subPropertyOf {SUPER}" +
" WHERE SUPER!=" + queryRep +
" AND SUPER != ALL ( " +
" select distinct B FROM {B} owl:equivalentProperty {" + queryRep + "} )";
List<String> list = new ArrayList<String>();
addSerqlQueryResultToCollection(query, list);
if (direct == OConstants.Closure.DIRECT_CLOSURE) {
Set<String> toDelete = new HashSet<String>();
for (int i = 0; i < list.size(); i++) {
String string = list.get(i);
if (toDelete.contains(string)) {
continue;
}
queryRep = string2Turtle(string);
query =
"Select distinct SUPER FROM {" + queryRep +
"} rdfs:subPropertyOf {SUPER}" +
" WHERE SUPER!=" + queryRep + " AND SUPER != ALL ( " +
" select distinct B FROM {B} owl:equivalentProperty {" + queryRep + "} )";
addSerqlQueryResultToCollection(query, toDelete);
}
list.removeAll(toDelete);
}
return list.contains(aSuperPropertyURI);
}
/**
* Checkes whether the two properties have a super-sub relation.
*
* @param aSuperPropertyURI
* @param aSubPropertyURI
* @param direct
* @return
*/
public boolean isSubPropertyOf(String aSuperPropertyURI,
String aSubPropertyURI, Closure direct)
{
return isSuperPropertyOf(aSuperPropertyURI, aSubPropertyURI,
direct);
}
/**
* Returns whether the individual1 is different from the individual2.
*
* @param theInstanceURI1
* @param theInstanceURI2
* @return
*/
public boolean isDifferentIndividualFrom(String theInstanceURI1, String theInstanceURI2)
{
String query =
"Select * from {<" + theInstanceURI1 + ">} owl:differentFrom {<" + theInstanceURI2 + ">}";
return hasSerqlQueryResultRows(query);
}
/**
* Checkes whether the two individuals are same.
*
* @param individualURI1
* @param invidualURI2
* @return
*/
public boolean isSameIndividualAs(String theInstanceURI1, String theInstanceURI2)
{
String query =
"Select * from {<" + theInstanceURI1 + ">} owl:sameAs {<" + theInstanceURI2 + ">}";
return hasSerqlQueryResultRows(query);
}
// *************
// Instances and properties
// **************
/**
* adds the RDF Property value on the specified instance
*
* @param anInstanceURI
* @param anRDFPropertyURI
* @param aResourceURI
*/
public void addRDFPropertyValue(String anInstanceURI,
String anRDFPropertyURI, String aResourceURI)
{
addUUUStatement(anInstanceURI, anRDFPropertyURI, aResourceURI);
}
/**
* Removes the specified RDF Property Value
*
* @param anInstanceURI
* @param anRDFPropertyURI
* @param aResourceURI
*/
public void removeRDFPropertyValue(String anInstanceURI,
String anRDFPropertyURI, String aResourceURI)
{
startTransaction(null);
removeUUUStatement(anInstanceURI, anRDFPropertyURI, aResourceURI);
endTransaction(null);
}
/**
* gets the rdf property values for the specified instance.
*
* @param anInstanceURI
* @param anRDFPropertyURI
* @return resource URIs
*/
public ResourceInfo[] getRDFPropertyValues(String anInstanceURI, String anRDFPropertyURI)
{
Resource r = getResource(anInstanceURI);
// TODO: !!! turtle
String queryRep2 = "<" + anInstanceURI + ">";
if (r instanceof BNode) {
queryRep2 = "_:" + anInstanceURI;
}
List<String> list = new ArrayList<String>();
String query =
"Select DISTINCT Y from {X} <" + anRDFPropertyURI + "> {Y} WHERE X=" + queryRep2;
addSerqlQueryResultToCollection(query, list);
return listToResourceInfoArray(list);
}
/**
* Removes all the RDF Property values from the given instance.
*
* @param anInstanceURI
* @param anRDFPropertyURI
*/
public void removeRDFPropertyValues(String anInstanceURI, String anRDFPropertyURI)
{
try {
repositoryConnection.remove(getResource(anInstanceURI),
makeSesameURI(anRDFPropertyURI), null);
} catch (Exception sue) {
throw new GateOntologyException(
"Error while removing RDF Property Values " + sue.getMessage(), sue);
}
}
// ******************
// DataType Properties
// *****************
/**
* Adds the value for the given Property.
*
* @param anInstanceURI
* @param aDatatypePropertyURI
* @param datatypeURI
* @param value
*/
public void addDatatypePropertyValue(String anInstanceURI, String aDatatypePropertyURI, String datatypeURI,
String value)
{
if (!isDatatypeProperty(aDatatypePropertyURI)) {
throw new GateOntologyException(
"No datatype property exists with URI :" + aDatatypePropertyURI);
}
addUUDStatement(anInstanceURI, aDatatypePropertyURI, value,
datatypeURI);
}
/**
* Removes the provided value for the given instance.
*
* @param anInstanceURI
* @param aDatatypePropertyURI
* @param datatypeURI
* @param value
*/
public void removeDatatypePropertyValue(String anInstanceURI, String aDatatypePropertyURI, String datatypeURI,
String value)
{
if (!isDatatypeProperty(aDatatypePropertyURI)) {
throw new GateOntologyException(
"No datatype property exists with URI :" + aDatatypePropertyURI);
}
startTransaction(null);
removeUUDStatement(anInstanceURI, aDatatypePropertyURI,
value, datatypeURI);
endTransaction(null);
}
/**
* Gets a list of values for the given Property.
*
* @param anInstanceURI
* @param aDatatypePropertyURI
* @return
*/
public PropertyValue[] getDatatypePropertyValues(String anInstanceURI, String aDatatypePropertyURI)
{
if (!isDatatypeProperty(aDatatypePropertyURI)) {
throw new GateOntologyException(
"No datatype property exists with URI :" + aDatatypePropertyURI);
}
Resource r2 = getResource(anInstanceURI);
// TODO: !!!!
String queryRep21 = "<" + anInstanceURI + ">";
if (r2 instanceof BNode) {
queryRep21 = "_:" + anInstanceURI;
}
List<PropertyValue> list = new ArrayList<PropertyValue>();
String query =
"Select DISTINCT Y from {X} <" + aDatatypePropertyURI + "> {Y} WHERE X=" + queryRep21 + " AND isLiteral(Y)";
UtilTupleQueryIterator result = performSerqlQuery(query);
while (result.hasNext()) {
PropertyValue pv;
Literal literal = (Literal) result.nextFirstAsValue();
String datatype = "http://www.w3.org/2001/XMLSchema#string";
if (literal.getDatatype() != null) {
datatype = literal.getDatatype().toString();
}
pv = new PropertyValue(datatype, literal.getLabel());
list.add(pv);
}
return listToPropertyValueArray(list);
}
/**
* Removes all property values set on the provided instance for the current
* property.
*
* @param anInstanceURI
* @param aDatatypePropertyURI
*/
public void removeDatatypePropertyValues(String anInstanceURI, String aDatatypePropertyURI)
{
if (!isDatatypeProperty(aDatatypePropertyURI)) {
throw new GateOntologyException(
"No datatype property exists with URI :" + aDatatypePropertyURI);
}
startTransaction(null);
removeUUUStatement(anInstanceURI, aDatatypePropertyURI, null);
endTransaction(null);
}
// ******************
// Object, Symmetric and Transitive Properties
// *****************
/**
* Adds the value for the given property (Object, Symmetric and Transitive).
*
* @param sourceInstanceURI
* @param anObjectPropertyURI
* @param theValueInstanceURI
*/
public void addObjectPropertyValue(String sourceInstanceURI, String anObjectPropertyURI,
String theValueInstanceURI) {
try {
if (!repositoryConnection.hasStatement(
getResource(anObjectPropertyURI),
makeSesameURI(RDF.TYPE.toString()),
getResource(OWL.OBJECTPROPERTY.toString()),
true)) {
throw new GateOntologyException(
"No object property exists with URI :" + anObjectPropertyURI);
}
} catch (Exception e) {
throw new GateOntologyException("Could not check for statement", e);
}
addUUUStatement(sourceInstanceURI, anObjectPropertyURI, theValueInstanceURI);
}
/**
* Remove the provided value for the given property (Object, Symmetric and
* Transitive).
*
* @param sourceInstanceURI
* @param anObjectPropertyURI
* @param theValueInstanceURI
*/
public void removeObjectPropertyValue(String sourceInstanceURI, String anObjectPropertyURI,
String theValueInstanceURI)
{
if (!isObjectProperty(anObjectPropertyURI)) {
throw new GateOntologyException(
"No object property exists with URI :" + anObjectPropertyURI);
}
startTransaction(null);
removeUUUStatement(sourceInstanceURI, anObjectPropertyURI,
theValueInstanceURI);
endTransaction(null);
}
/**
* Gets a list of values for the given Property (Object, Symmetric and
* Transitive).
*
* @param sourceInstanceURI
* @param anObjectPropertyURI
* @return
*/
public String[] getObjectPropertyValues(String sourceInstanceURI, String anObjectPropertyURI)
{
if (!isObjectProperty(anObjectPropertyURI) && !isTransitiveProperty(anObjectPropertyURI) && !isSymmetricProperty(anObjectPropertyURI)) {
throw new GateOntologyException(
"No object/transitive/symmetric property exists with URI :" + anObjectPropertyURI);
}
Resource r = getResource(sourceInstanceURI);
String queryRep2 = "<" + sourceInstanceURI + ">";
if (r instanceof BNode) {
queryRep2 = "_:" + sourceInstanceURI;
}
List<String> list = new ArrayList<String>();
String query =
"Select DISTINCT Y from {X} <" + anObjectPropertyURI + "> {Y} WHERE X=" + queryRep2;
addSerqlQueryResultToCollection(query, list);
return listToArray(list);
}
/**
* Removes all property values set for the current property (Object, Symmetric
* and Transitive).
*
* @param sourceInstanceURI
* @param anObjectPropertyURI
*/
public void removeObjectPropertyValues(String sourceInstanceURI, String anObjectPropertyURI)
{
if (!isObjectProperty(anObjectPropertyURI)) {
throw new GateOntologyException(
"No object property exists with URI :" + anObjectPropertyURI);
}
startTransaction(null);
removeUUUStatement(sourceInstanceURI, anObjectPropertyURI, null);
endTransaction(null);
}
/**
* Returns if the given property is a topOnly property.
*
* @param classURI
* @return
*/
public boolean isTopProperty(String aPropertyURI)
{
return getSuperProperties(aPropertyURI,
OConstants.Closure.DIRECT_CLOSURE).length == 0;
}
//****************************************************************************
// relations among classes
//****************************************************************************
/**
* The method creates a new class with the URI as specified in className and
* adds it as a subClassOf the parentClass. It also adds the provided comment
* on the subClass.
*
* @param superClassURI
* @param subClassURI
*/
public void addSubClass(String superClassURI,
String subClassURI)
{
addUUUStatement(subClassURI, RDFS.SUBCLASSOF.toString(), superClassURI);
}
/**
* The method creates a new class with the URI as specified in className and
* adds it as a superClassOf the parentClass. It also adds the provided
* comment on the subClass.
*
* @param superClassURI
* @param subClassURI
*/
public void addSuperClass(String superClassURI,
String subClassURI)
{
addUUUStatement(subClassURI, RDFS.SUBCLASSOF.toString(), superClassURI);
}
/**
* Removes the subclass relationship
*
* @param superClassURI
* @param subClassURI
*/
public void removeSubClass(String superClassURI,
String subClassURI) {
removeUUUStatement(subClassURI, RDFS.SUBCLASSOF.toString(), superClassURI);
}
/**
* Removes the superclass relationship
*
* @param superClassURI
* @param subClassURI
*/
public void removeSuperClass(String superClassURI,
String subClassURI) {
removeUUUStatement(subClassURI, RDFS.SUBCLASSOF.toString(), superClassURI);
}
public ClosableIterator<OClass> getSubClassesIterator(
ONodeID forClass, Closure closure) {
if(closure== Closure.DIRECT_CLOSURE) {
// better would be to just do a setbinding for a prepared query,
// but there is a bug in OWLIM that prevents this to work with this query
String query = qs_getSubClassesDirectFor;
query = query.replaceAll("yyy1", forClass.toTurtle());
UtilTupleQueryIterator qp_getSubClassesDirectFor =
new UtilTupleQueryIterator(
repositoryConnection, query, ql_getSubClassesDirectFor);
return new UtilResourceQueryIterator<OClass>(
this, qp_getSubClassesDirectFor, OClass.class);
} else {
String query = qs_getSubClassesAllFor;
query = query.replaceAll("yyy1", forClass.toTurtle());
UtilTupleQueryIterator qp_getSubClassesAllFor =
new UtilTupleQueryIterator(
repositoryConnection, query, ql_getSubClassesAllFor);
return new UtilResourceQueryIterator<OClass>(
this, qp_getSubClassesAllFor, OClass.class);
}
}
public Set<OClass> getSubClasses(ONodeID superClassURI, Closure direct)
{
Set<OClass> ret = new HashSet<OClass>();
ClosableIterator<OClass> it = getSubClassesIterator(superClassURI, direct);
while(it.hasNext()) {
ret.add(it.next());
}
return ret;
}
public OClass getRestrictionForONodeID(ONodeID node) {
OClass theClass = null;
if(node.isAnonymousResource()) {
qp_getRestrictionTypeFor.setBinding("yyy1", new LiteralOrONodeIDImpl(node));
String nodeID = node.toTurtle();
LiteralOrONodeID r = null;
int i = 0;
while(qp_getRestrictionTypeFor.hasNext()) {
i++;
r = qp_getRestrictionTypeFor.nextFirst();
}
if(i==0) {
// no restriction property found, must be some other anonymous class
theClass = Utils.createOClass(ontology, this, node.toString(), OConstants.ANNONYMOUS_CLASS);
} else if(i == 1) {
// make the apropriate restriction
theClass = createRestrictionFromURI(r.toString(), nodeID.toString());
} else {
// oddd
System.out.println("getRestrictionForONodeIDs: Got more than one restriction type for: "+nodeID);
theClass = Utils.createOClass(ontology, this, node.toString(), OConstants.ANNONYMOUS_CLASS);
}
return theClass;
} else {
throw new GateOntologyException("getRestrictionForONodeIDs: called for non-anonymous class: "+node.toTurtle());
}
}
/**
* This method returns all super classes of the given class
*
* @param subClassURI
* @param direct
* @return
*/
public ResourceInfo[] getSuperClasses(String subClassURI, Closure direct) throws GateOntologyException {
String queryRep1 = string2Turtle(subClassURI);
String queryRep = "{" + queryRep1 + "}";
String query = "";
query =
"Select distinct SUPER FROM " + queryRep + " rdfs:subClassOf {SUPER}" + " WHERE SUPER!=" + queryRep1 + " AND SUPER != ALL ( " + " select distinct B FROM {B} owl:equivalentClass " + queryRep + ")";
List<String> list = new ArrayList<String>();
addSerqlQueryResultToCollection(query, list);
if (direct == OConstants.Closure.DIRECT_CLOSURE) {
Set<String> toDelete = new HashSet<String>();
for (int i = 0; i < list.size(); i++) {
String string = list.get(i);
if (toDelete.contains(string)) {
continue;
}
queryRep1 = string2Turtle(string);
queryRep = "{"+queryRep1+"}";
query =
"Select distinct SUPER FROM " + queryRep + " rdfs:subClassOf {SUPER}" + " WHERE SUPER!=" + queryRep1 + " AND SUPER != ALL ( " + " select distinct B FROM {B} owl:equivalentClass " + queryRep + ")";
addSerqlQueryResultToCollection(query, toDelete);
}
list.removeAll(toDelete);
}
return listToResourceInfoArray(list);
}
/**
* Sets the classes as disjoint
*
* @param class1URI
* @param class2URI
*/
public void setDisjointClassWith(String class1URI,
String class2URI)
{
addUUUStatement(class1URI, OWL.DISJOINTWITH.toString(), class2URI);
}
/**
* Sets the classes as same classes
*
* @param class1URI
* @param class2URI
*/
public void setEquivalentClassAs(String class1URI,
String class2URI) {
addUUUStatement(class1URI, OWL.EQUIVALENTCLASS.toString(), class2URI);
}
/**
* returns an array of classes which are marked as disjoint for the given
* class
*
* @param classURI
* @return
*/
public String[] getDisjointClasses(String aClassURI)
{
Resource r1 = getResource(aClassURI);
// TODO: !!!! turtle
String queryRep1 = "<" + aClassURI + ">";
if (r1 instanceof BNode) {
queryRep1 = "_:" + aClassURI;
}
String query =
"Select distinct B FROM {A}" + " owl:disjointWith {B} WHERE A!=B AND A=" + queryRep1;
List<String> list = new ArrayList<String>();
addSerqlQueryResultToCollection(query, list);
return listToArray(list);
}
/**
* returns an array of classes which are equivalent as the given class
*
* @param aClassURI
* @return
*/
public ResourceInfo[] getEquivalentClasses(String aClassURI)
{
String queryRep1 = string2Turtle(aClassURI);
String query =
"Select distinct B FROM {A}" + " owl:equivalentClass {B} WHERE A!=B AND A=" + queryRep1;
List<String> list = new ArrayList<String>();
addSerqlQueryResultToCollection(query, list);
return listToResourceInfoArray(list);
}
/**
* Removes the given property
*
* @param aPropertyURI
* @param removeSubTree
* - if set to true, removes all its subproperties, otherwise shifts
* subproperties to its parent property
* @return a list of URIs of resources deleted as a result of deleting this
* property.
*/
public String[] removePropertyFromOntology(String aPropertyURI, boolean removeSubTree)
{
List<String> deletedResources = new ArrayList<String>();
// TODO: have to check for explicit property in some other way, this
// does not work anymore!
//if(removeUUUStatement(aPropertyURI, RDF.TYPE.toString(), null) == 0) {
// throw new GateOntologyException(aPropertyURI
// + " is not an explicit Property");
// }
// else {
// currentEventsLog
// .addEvent(new OEvent(aPropertyURI, RDF.TYPE.toString(), null, false));
// deletedResources.add(aPropertyURI);
// }
removeUUUStatement(aPropertyURI, RDF.TYPE.toString(), null);
deletedResources.add(aPropertyURI);
try {
startTransaction(null);
// removing all values set for the current property
repositoryConnection.remove((Resource) null, makeSesameURI(aPropertyURI), null);
repositoryConnection.remove(getResource(aPropertyURI),
makeSesameURI(RDFS.SUBPROPERTYOF.toString()), null);
endTransaction(null);
} catch (Exception sue) {
throw new GateOntologyException("error while removing a property:" + aPropertyURI, sue);
}
// this should happen only if removeSubTree is set to true
if (removeSubTree) {
Property[] subProps =
getSubProperties(aPropertyURI, OConstants.Closure.DIRECT_CLOSURE);
for (int i = 0; i < subProps.length; i++) {
try {
if (repositoryConnection.hasStatement(getResource(subProps[i].getUri()),
makeSesameURI(RDF.TYPE.toString()), null, false)) {
continue;
}
String[] removedResources =
removePropertyFromOntology(subProps[i].getUri(), true);
deletedResources.addAll(Arrays.asList(removedResources));
} catch (RepositoryException e) {
throw new GateOntologyException("Error finding statement ", e);
}
}
}
removeUUUStatement(aPropertyURI, null, null);
removeUUUStatement(null, aPropertyURI, null);
removeUUUStatement(null, null, aPropertyURI);
return listToArray(deletedResources);
}
/**
* The method adds an object property specifiying domain and range for the
* same. All classes specified in domain and range must exist.
*
* @param aPropertyURI
* @param domainClassesURIs
* @param rangeClassesTypes
*/
public void addObjectProperty(String aPropertyURI,
String[] domainClassesURIs, String[] rangeClassesTypes)
{
addUUUStatement(aPropertyURI, RDF.TYPE.toString(), OWL.OBJECTPROPERTY.toString());
if (domainClassesURIs != null) {
for (int i = 0; i < domainClassesURIs.length; i++) {
addUUUStatement(aPropertyURI, RDFS.DOMAIN.toString(), domainClassesURIs[i]);
}
}
if (rangeClassesTypes != null) {
for (int i = 0; i < rangeClassesTypes.length; i++) {
addUUUStatement(aPropertyURI, RDFS.RANGE.toString(), rangeClassesTypes[i]);
}
}
}
/**
* The method adds a transitive property specifiying domain and range for the
* same. All classes specified in domain and range must exist.
*
* @param aPropertyURI
* @param domainClassesURIs
* @param rangeClassesTypes
*/
public void addTransitiveProperty(String aPropertyURI,
String[] domainClassesURIs, String[] rangeClassesTypes)
{
addUUUStatement(aPropertyURI, RDF.TYPE.toString(), OWL.TRANSITIVEPROPERTY.toString());
if (domainClassesURIs != null) {
for (int i = 0; i < domainClassesURIs.length; i++) {
addUUUStatement(aPropertyURI, RDFS.DOMAIN.toString(), domainClassesURIs[i]);
}
}
if (rangeClassesTypes != null) {
for (int i = 0; i < rangeClassesTypes.length; i++) {
addUUUStatement(aPropertyURI, RDFS.RANGE.toString(), rangeClassesTypes[i]);
}
}
}
/**
* The method returns an array of properties. Property is a complex structure,
* which contains name, comment, information about its domain and range.
*
* @return
*/
public Property[] getRDFProperties()
{
List<Property> list = new ArrayList<Property>();
String query =
"Select distinct X FROM {X} rdf:type {<" + RDF.PROPERTY + ">}";
UtilTupleQueryIterator result = performSerqlQuery(query);
while (result.hasNext()) {
String propString = result.nextFirstAsString();
if (isAnnotationProperty(propString) || isDatatypeProperty(propString) || isObjectProperty(propString) || isTransitiveProperty(propString) || isSymmetricProperty(propString)) {
continue;
}
list.add(new Property(OConstants.RDF_PROPERTY, propString));
}
result.close();
return listToPropertyArray(list);
}
/**
* The method returns an array of properties. Property is a complex structure,
* which contains name, comment, information about its domain and range.
*
* @return
*/
public Property[] getObjectProperties()
{
List<Property> list = new ArrayList<Property>();
String query =
"Select distinct X FROM {X} rdf:type {<" + OWL.OBJECTPROPERTY + ">}";
logger.debug("=== searching for object properties");
UtilTupleQueryIterator result = performSerqlQuery(query);
while (result.hasNext()) {
Value anAnnProp = result.nextFirstAsValue();
logger.debug("Got an object property: "+anAnnProp);
list.add(new Property(OConstants.OBJECT_PROPERTY, anAnnProp.toString()));
}
result.close();
query =
"Select distinct X FROM {X} rdf:type {<" + OWL.SYMMETRICPROPERTY + ">}";
logger.debug("=== searching for symmetric properties");
result = performSerqlQuery(query);
while (result.hasNext()) {
Value anAnnProp = result.nextFirstAsValue();
logger.debug("Got a symmetric property: "+anAnnProp);
list.add(new Property(OConstants.SYMMETRIC_PROPERTY, anAnnProp.toString()));
}
query =
"Select distinct X FROM {X} rdf:type {<" + OWL.TRANSITIVEPROPERTY + ">}";
result = performSerqlQuery(query);
while (result.hasNext()) {
Value anAnnProp = result.nextFirstAsValue();
logger.debug("Got a transitive property: "+anAnnProp);
list.add(new Property(OConstants.TRANSITIVE_PROPERTY, anAnnProp.toString()));
}
logger.debug("Returning from OSI getObjectProperties");
return listToPropertyArray(list);
}
/**
* The method returns an array of properties. Property is a complex structure,
* which contains name, comment, information about its domain and range.
*
* @return
*/
public Property[] getSymmetricProperties()
{
List<Property> list = new ArrayList<Property>();
String query =
"Select distinct X FROM {X} rdf:type {<" + OWL.SYMMETRICPROPERTY + ">}";
UtilTupleQueryIterator result = performSerqlQuery(query);
while (result.hasNext()) {
Value anAnnProp = result.nextFirstAsValue();
list.add(new Property(OConstants.SYMMETRIC_PROPERTY, anAnnProp.toString()));
}
return listToPropertyArray(list);
}
/**
* The method returns an array of properties. Property is a complex structure,
* which contains name, comment, information about its domain and range.
*
* @return
*/
public Property[] getTransitiveProperties()
{
List<Property> list = new ArrayList<Property>();
String query =
"Select distinct X FROM {X} rdf:type {<" + OWL.TRANSITIVEPROPERTY + ">}";
UtilTupleQueryIterator result = performSerqlQuery(query);
while (result.hasNext()) {
Value anAnnProp = result.nextFirstAsValue();
list.add(new Property(OConstants.TRANSITIVE_PROPERTY, anAnnProp.toString()));
}
return listToPropertyArray(list);
}
/**
* The method returns an array of properties. Property is a complex structure,
* which contains name, comment, information about its domain and range.
*
* @return
*/
public Property[] getDatatypeProperties()
{
List<Property> list = new ArrayList<Property>();
String query =
"Select distinct X FROM {X} rdf:type {<" + OWL.DATATYPEPROPERTY + ">}";
UtilTupleQueryIterator result = performSerqlQuery(query);
while (result.hasNext()) {
Value anAnnProp = result.nextFirstAsValue();
list.add(new Property(OConstants.DATATYPE_PROPERTY, anAnnProp.toString()));
}
return listToPropertyArray(list);
}
/**
* The method returns an array of properties. Property is a complex structure,
* which contains name, comment, information about its domain and range.
*
* @return
*/
public Property[] getAnnotationProperties()
{
List<Property> list = new ArrayList<Property>();
String query =
"Select distinct X FROM {X} rdf:type {<" + OWL.ANNOTATIONPROPERTY + ">}";
UtilTupleQueryIterator result = performSerqlQuery(query);
while (result.hasNext()) {
Value anAnnProp = result.nextFirstAsValue();
list.add(new Property(OConstants.ANNOTATION_PROPERTY, anAnnProp.toString()));
}
boolean allowSystemStatements = this.returnSystemStatements;
this.returnSystemStatements = true;
Property[] props = listToPropertyArray(list);
this.returnSystemStatements = allowSystemStatements;
return props;
}
public Set<RDFProperty> getPropertiesByName(String name) {
Set<RDFProperty> properties = new HashSet<RDFProperty>();
// TODOD: !!!!!!
// TODO: get all rdf properties, object properties, symmetric properties
// etc where the URI fragment identifier matches the name
return properties;
}
/**
* Given a property, this method returns its domain
*
* @param aPropertyURI
* @return
*/
// TODO: return ONodeIDs or Classes, make reducing to most
// specific classes optional
public ResourceInfo[] getDomain(String aPropertyURI)
{
if (isAnnotationProperty(aPropertyURI)) {
throw new GateOntologyException(
"AnnotationProperties do no specify any domain or range");
}
String query =
"select distinct Y from {<" + aPropertyURI + ">} rdfs:domain {Y}";
UtilTupleQueryIterator result = performSerqlQuery(query);
List<ResourceInfo> list = new ArrayList<ResourceInfo>();
while (result.hasNext()) {
String classString = result.nextFirstAsString();
byte classType = getClassType(classString);
if (classType == OConstants.ANNONYMOUS_CLASS) {
continue;
}
list.add(new ResourceInfo(classString, classType));
}
result.close();
return reduceToMostSpecificClasses(list);
}
/**
* Given a property, this method returns its range
*
* @param aPropertyURI
* @return
*/
public ResourceInfo[] getRange(String aPropertyURI)
{
if (isAnnotationProperty(aPropertyURI)) {
throw new GateOntologyException(
"AnnotationProperties do no specify any domain or range");
}
if (isDatatypeProperty(aPropertyURI)) {
throw new GateOntologyException(
"Please use getDatatype(String theDatatypeProerptyURI) method instead");
}
String query =
"Select distinct Y from {<" + aPropertyURI + ">} rdfs:range {Y}";
UtilTupleQueryIterator result = performSerqlQuery(query);
List<ResourceInfo> list = new ArrayList<ResourceInfo>();
while (result.hasNext()) {
String classString = result.nextFirstAsString();
byte classType = getClassType(classString);
if (classType == OConstants.ANNONYMOUS_CLASS) {
continue;
}
list.add(new ResourceInfo(classString, classType));
}
result.close();
return reduceToMostSpecificClasses(list);
}
/**
* Returns if the provided property is functional
*
* @param aPropertyURI
* @return
*/
public boolean isFunctional(String aPropertyURI)
{
String query =
"Select * FROM {X} rdf:type {<" + OWL.FUNCTIONALPROPERTY + ">} WHERE X=<" + aPropertyURI + ">";
return hasSerqlQueryResultRows(query);
}
/**
* sets the current property as functional
*
* @param aPropertyURI
* @param isFunctional
*/
public void setFunctional(String aPropertyURI,
boolean isFunctional)
{
if (isFunctional) {
addUUUStatement(aPropertyURI, RDF.TYPE.toString(), OWL.FUNCTIONALPROPERTY.toString());
} else {
removeUUUStatement(aPropertyURI, RDF.TYPE.toString(), OWL.FUNCTIONALPROPERTY.toString());
}
}
/**
* returns if the given property is inverse functional property
*
* @param aPropertyURI
* @return
*/
public boolean isInverseFunctional(String aPropertyURI)
{
String query =
"Select * FROM {X} rdf:type {<" + OWL.INVERSEFUNCTIONALPROPERTY + ">} WHERE X=<" + aPropertyURI + ">";
return hasSerqlQueryResultRows(query);
}
/**
* Sets the current property as inverse functional property
*
* @param aPropertyURI
* @param isInverseFunctional
*/
public void setInverseFunctional(String aPropertyURI,
boolean isInverseFunctional)
{
if (isInverseFunctional) {
addUUUStatement(aPropertyURI, RDF.TYPE.toString(), OWL.INVERSEFUNCTIONALPROPERTY.toString());
} else {
removeUUUStatement(aPropertyURI, RDF.TYPE.toString(), OWL.INVERSEFUNCTIONALPROPERTY.toString());
}
}
/**
* returns if the given property is a symmetric property
*
* @param aPropertyURI
* @return
*/
public boolean isSymmetricProperty(String aPropertyURI)
{
String query =
"Select * FROM {X} rdf:type {<" + OWL.SYMMETRICPROPERTY + ">} WHERE X=<" + aPropertyURI + ">";
return hasSerqlQueryResultRows(query);
}
/**
* returns if the given property is a transitive property
*
* @param aPropertyURI
* @return
*/
public boolean isTransitiveProperty(String aPropertyURI)
{
String query =
"Select * FROM {X} rdf:type {<" + OWL.TRANSITIVEPROPERTY + ">} WHERE X=<" + aPropertyURI + ">";
return hasSerqlQueryResultRows(query);
}
/**
* returns if the given property is a datatype property
*
* @param aPropertyURI
* @return
*/
public boolean isDatatypeProperty(String aPropertyURI)
{
String query =
"Select * FROM {X} rdf:type {<" + OWL.DATATYPEPROPERTY + ">} WHERE X=<" + aPropertyURI + ">";
return hasSerqlQueryResultRows(query);
}
/**
* returns if the given property is an object property
*
* @param aPropertyURI
* @return
*/
public boolean isObjectProperty(String aPropertyURI)
{
String query =
"Select * FROM {X} rdf:type {<" + OWL.OBJECTPROPERTY + ">} WHERE X=<" + aPropertyURI + ">";
return hasSerqlQueryResultRows(query);
}
// *************************************
// Relations among properties
// *************************************
/**
* Sets two properties as same
*
* @param property1URI
* @param property2URI
*/
public void setEquivalentPropertyAs(String property1URI,
String property2URI)
{
addUUUStatement(property1URI, OWL.EQUIVALENTPROPERTY.toString(), property2URI);
}
/**
* For the given property, this method returns all properties marked as
* Equivalent as it
*
* @param aPropertyURI
* @return
*/
public Property[] getEquivalentPropertyAs(String aPropertyURI)
{
String query =
"Select DISTINCT Y FROM {X} owl:equivalentProperty {Y} WHERE X=<" + aPropertyURI + ">";
UtilTupleQueryIterator result = performSerqlQuery(query);
List<Property> list = new ArrayList<Property>();
while (result.hasNext()) {
list.add(createPropertyObject(result.nextFirstAsString()));
}
return listToPropertyArray(list);
}
/**
* For the given properties, this method registers the super, sub relation
*
* @param superPropertyURI
* @param subPropertyURI
*/
public void addSuperProperty(String superPropertyURI,
String subPropertyURI)
{
addUUUStatement(subPropertyURI, RDFS.SUBPROPERTYOF.toString(), superPropertyURI);
}
/**
* For the given properties, this method removes the super, sub relation
*
* @param superPropertyURI
* @param subPropertyURI
*/
public void removeSuperProperty(String superPropertyURI,
String subPropertyURI)
{
removeUUUStatement(subPropertyURI, RDFS.SUBPROPERTYOF.toString(), superPropertyURI);
}
/**
* For the given properties, this method registers the super, sub relation
*
* @param superPropertyURI
* @param subPropertyURI
*/
public void addSubProperty(String superPropertyURI,
String subPropertyURI)
{
addUUUStatement(subPropertyURI, RDFS.SUBPROPERTYOF.toString(), superPropertyURI);
}
/**
* For the given properties, this method removes the super, sub relation
*
* @param superPropertyURI
* @param subPropertyURI
*/
public void removeSubProperty(String superPropertyURI,
String subPropertyURI)
{
removeUUUStatement(subPropertyURI, RDFS.SUBPROPERTYOF.toString(), superPropertyURI);
}
/**
* for the given property, the method returns all its super properties
*
* @param aPropertyURI
* @param direct
* @return
*/
public Property[] getSuperProperties(String aPropertyURI, boolean direct)
{
return this.getSuperProperties(aPropertyURI, direct
? OConstants.Closure.DIRECT_CLOSURE
: OConstants.Closure.TRANSITIVE_CLOSURE);
}
/**
* for the given property, the method returns all its sub properties
*
* @param aPropertyURI
* @param direct
* @return
*/
public Property[] getSubProperties(String aPropertyURI,
boolean direct)
{
return this.getSubProperties(aPropertyURI, direct
? OConstants.Closure.DIRECT_CLOSURE
: OConstants.Closure.TRANSITIVE_CLOSURE);
}
/**
* for the given property, the method returns all its inverse properties
*
* @param aPropertyURI
* @return
*/
public Property[] getInverseProperties(String aPropertyURI)
{
String query =
"Select DISTINCT Y FROM {X} owl:inverseOf {Y} WHERE X=<" + aPropertyURI + ">";
UtilTupleQueryIterator result = performSerqlQuery(query);
List<Property> list = new ArrayList<Property>();
while (result.hasNext()) {
list.add(createPropertyObject(result.nextFirstAsString()));
}
result.close();
return listToPropertyArray(list);
}
/**
* property1 is set as inverse of property 2
*
* @param propertyURI1
* @param propertyURI2
*/
public void setInverseOf(String propertyURI1, String propertyURI2)
{
addUUUStatement(propertyURI1, OWL.INVERSEOF.toString(), propertyURI2);
}
// *******************************************************************
// *************************** Instance Methods **********************
// *******************************************************************
/**
* The method adds a new instance (literal) into the repository. It then
* creates a statement indicating membership relation with the provided class.
*
* @param superClassURI
* @param individualURI
*/
public void addIndividual(String superClassURI,
String individualURI)
{
addUUUStatement(individualURI, RDF.TYPE.toString(), superClassURI);
}
/**
* The method removes the provided instance from the repository.
*
* @param individual
* @return
*/
public String[] removeIndividual(String individualURI)
{
// TODO: JP we have to check for explicit individual in some other way
// here since removeUUUStatement cannot return the number of removed
// eny more
// Do a query to assert this?
//int no = removeUUUStatement(individualURI, RDF.TYPE.toString(), null);
//if(no == 0)
// throw new GateOntologyException(individualURI
// + " is not an explicit Individual");
removeUUUStatement(individualURI, RDF.TYPE.toString(), null);
// we need to go though all ontology resources of the ontology
// check if they have property with value the current resource
// we need to delete it
// TODO: !!!! is this not redundand with respect to what we do below?
// (which is remove any triples that contain this URI anywhere?)
// NOTE that removing all triples with this URI will fail for OWL-DL
// if we just want to remove the occurrences of this individual as
// individual but it is also a class!
List<Property> properties = new ArrayList<Property>();
properties.addAll(Arrays.asList(getObjectProperties()));
try {
startTransaction(null);
for (int i = 0; i < properties.size(); i++) {
repositoryConnection.remove((Resource) null, makeSesameURI(properties.get(i).getUri()),
getResource(individualURI));
}
endTransaction(null);
} catch (Exception sue) {
throw new GateOntologyException("error while removing individual:" + individualURI, sue);
}
removeUUUStatement(individualURI, null, null);
removeUUUStatement(null, null, individualURI);
removeUUUStatement(null, individualURI, null);
return new String[]{individualURI};
}
/**
* The method returns all member instances of the provided class. It returns
* only the direct instances if the boolean parameter direct is set to true.
*
* @param superClassURI
* @param direct
*/
public String[] getIndividuals(String superClassURI,
Closure direct) {
String queryRep = string2Turtle(superClassURI);
// A -> B -> I1
String query = "";
if (direct == OConstants.Closure.DIRECT_CLOSURE) {
query = "Select distinct X from {X} serql:directType {" + queryRep +"}";
} else {
query = "Select distinct X from {X} rdf:type {" + queryRep +"}";
}
//System.out.println("getIndividuals query: "+query);
List<String> list = new ArrayList<String>();
addSerqlQueryResultToCollection(query, list);
return listToArray(list);
}
public ClosableIterator<OInstance> getInstancesIterator(
ONodeID aClass, OConstants.Closure closure) {
// if aClass is null: all instances
// if aClass is not null: instances of that class either
// direct or transitive
// once we have that, remove unneeded classes and re-implement
// getOInstance and has OInstance in abstractOntologyimpl
UtilResourceQueryIterator ret = null;
if(aClass == null) {
ret = new UtilResourceQueryIterator<OInstance>(
this, qp_getInstancesAll, OInstance.class);
} else if(closure == OConstants.Closure.DIRECT_CLOSURE) {
ret = new UtilResourceQueryIterator<OInstance>(
this, qp_getInstancesDirectFor, OInstance.class);
ret.setBinding("yyy1", new LiteralOrONodeIDImpl(aClass));
} else {
ret = new UtilResourceQueryIterator<OInstance>(
this, qp_getInstancesAllFor, OInstance.class);
ret.setBinding("yyy1", new LiteralOrONodeIDImpl(aClass));
}
return ret;
}
public Set<OInstance> getInstances(ONodeID aClass, OConstants.Closure closure) {
//System.out.println("Running service.getInstances()");
Set<OInstance> theInstances = new HashSet<OInstance>();
ClosableIterator<OInstance> ii = getInstancesIterator(aClass, closure);
while(ii.hasNext()) {
OInstance i = ii.next();
//System.out.println("Adding to result: "+i);
theInstances.add(i);
}
return theInstances;
}
// public ClosableIterator<OInstance> getInstancesIterator() {
// //System.out.print("Creating ResourceQueryIt fir "+qp_getInstancesAll);
// return new UtilResourceQueryIterator<OInstance>(
// this, qp_getInstancesAll, OInstance.class);
// }
public Set<OInstance> getInstancesByName(String name) {
Set<OInstance> instances = new HashSet<OInstance>();
String query =
"Select distinct X from {X} rdf:type {Y} rdf:type {<http://www.w3.org/2002/07/owl#Class>} WHERE Y != <http://www.w3.org/2002/07/owl#Thing> AND X LIKE yyy1 ";
query = query.replaceAll("yyy1", "\"*"+name+"\"");
//System.out.println("Query for instances: "+query);
UtilTupleQueryIterator q = new UtilTupleQueryIterator(repositoryConnection,
query,OConstants.QueryLanguage.SERQL);
while(q.hasNext()) {
Value v = q.nextFirstAsValue();
OInstance i = Utils.createOInstance(ontology, this, v.toString());
instances.add(i);
}
return instances;
}
// OURI must be not null, ONodeID can be null in that cas closure can be null too
public boolean hasInstance(OURI theURI, ONodeID theClass, OConstants.Closure closure) {
boolean ret = false;
if(theClass == null) {
qp_hasInstance.setBinding("yyy1", new LiteralOrONodeIDImpl(theURI));
if(qp_hasInstance.hasNext()) {
ret = true;
qp_hasInstance.close();
}
} else if(closure == OConstants.Closure.DIRECT_CLOSURE) {
// qp_hasInstanceDirectFor.setBinding("yyy1", new LiteralOrONodeIDImpl(theURI));
// qp_hasInstanceDirectFor.setBinding("yyy2", new LiteralOrONodeIDImpl(theClass));
String query = qs_hasInstanceDirectFor;
query = query.replaceAll("yyy1", theURI.toTurtle());
query = query.replaceAll("yyy2", theClass.toTurtle());
UtilTupleQueryIterator qp_hasInstanceDirectFor =
new UtilTupleQueryIterator(repositoryConnection, query, ql_hasInstanceDirectFor);
if(qp_hasInstanceDirectFor.hasNext()) {
ret = true;
qp_hasInstanceDirectFor.close();
}
} else {
// qp_hasInstanceAllFor.setBinding("yyy1", new LiteralOrONodeIDImpl(theURI));
// qp_hasInstanceAllFor.setBinding("yyy2", new LiteralOrONodeIDImpl(theClass));
String query = qs_hasInstanceAllFor;
query = query.replaceAll("yyy1", theURI.toTurtle());
query = query.replaceAll("yyy2", theClass.toTurtle());
UtilTupleQueryIterator qp_hasInstanceAllFor =
new UtilTupleQueryIterator(repositoryConnection, query, ql_hasInstanceAllFor);
if(qp_hasInstanceAllFor.hasNext()) {
ret = true;
qp_hasInstanceAllFor.close();
}
}
return ret;
}
/**
* For the given individual, the method returns a set of classes for which the
* individual is registered as instance of
*
* @param individualURI
*/
public ResourceInfo[] getClassesOfIndividual(String individualURI, Closure direct) throws GateOntologyException {
if (debug) {
logger.debug("getClassesOfIndividual");
}
String query = "";
if (direct == OConstants.Closure.DIRECT_CLOSURE) {
query =
"Select DISTINCT B from {X} serql:directType {B} WHERE X=<" + individualURI + ">";
} else {
query =
"Select DISTINCT B from {X} rdf:type {B} WHERE X=<" + individualURI + ">";
}
List<String> list = new ArrayList<String>();
addSerqlQueryResultToCollection(query, list);
return listToResourceInfoArray(list);
}
// *******************************************************************
// relations among individuals
// *******************************************************************
/**
* individual1 is sets as different individual from individual2
*
* @param individual1URI
* @param individual2URI
*/
public void setDifferentIndividualFrom(String individual1URI, String individual2URI) throws GateOntologyException {
if (debug) {
logger.debug("setDifferentIndividualFrom");
}
addUUUStatement(individual1URI, OWL.DIFFERENTFROM.toString(), individual2URI);
}
/**
* for the given individual, the method returns all individuals registered as
* different from the given individual
*
* @param individualURI
* @return
*/
public String[] getDifferentIndividualFrom(String individualURI) throws GateOntologyException {
String query =
"Select distinct B from {X} owl:differentFrom {B} WHERE X=<" + individualURI + ">";
List<String> list = new ArrayList<String>();
addSerqlQueryResultToCollection(query, list);
return listToArray(list);
}
/**
* individual1 is set as same as the individual2
*
* @param individual1URI
* @param individual2URI
*/
public void setSameIndividualAs(String individual1URI,
String individual2URI) throws GateOntologyException {
if (debug) {
logger.debug("setSameIndividualAs");
}
addUUUStatement(individual1URI, OWL.SAMEAS.toString(), individual2URI);
}
/**
* for the given individual, the method returns all individuals which are
* registered as same as the provided individual
*
* @param inidividualURI
* @return
*/
public String[] getSameIndividualAs(String individualURI)
{
String query =
"select distinct B from {X} owl:sameAs {B} WHERE X=<" + individualURI + "> AND X!=B";
List<String> list = new ArrayList<String>();
addSerqlQueryResultToCollection(query, list);
return listToArray(list);
}
// ***********************************************
// ********* Restrictions ***********************
// ***********************************************
/**
* This method given a restriction uri returns the value for the onProperty
* element.
*
* @param restrictionURI
* @return
* @throws GateOntologyException
*/
public Property getOnPropertyValue(String restrictionURI)
{
String queryRep = string2Turtle(restrictionURI);
String query =
"Select distinct B from {X} owl:onProperty {B} WHERE X=" + queryRep;
//System.out.println("Query="+query);
UtilTupleQueryIterator result = performSerqlQuery(query);
String val = null;
if (result.hasNext()) {
// here we need to check which type of property it is
val = result.nextFirstAsString();
}
result.close();
if (val != null) {
return createPropertyObject(val);
} else {
return null;
}
}
/**
* This method sets the value for onProperty element on the given restriction.
*
* @param repositoryId
* @param restrictionURI
* @param propertyURI
* @throws GateOntologyException
*/
public void setOnPropertyValue(String restrictionURI,
String propertyURI)
{
addUUUStatement(restrictionURI, OWL.ONPROPERTY.toString(), propertyURI);
}
/**
* Gets the datatype uri specified on the given restriction uri.
*
* @param repositoryID
* @param restrictionURI
* @return
* @throws GateOntologyException
*/
public PropertyValue getPropertyValue(
String restrictionURI, byte restrictionType)
{
org.openrdf.model.URI whatValueURI = null;
switch (restrictionType) {
case OConstants.CARDINALITY_RESTRICTION:
whatValueURI = OWL.CARDINALITY;
break;
case OConstants.MAX_CARDINALITY_RESTRICTION:
whatValueURI = OWL.MAXCARDINALITY;
break;
case OConstants.MIN_CARDINALITY_RESTRICTION:
whatValueURI = OWL.MINCARDINALITY;
break;
default:
throw new GateOntologyException("Invalid restriction type :" + restrictionType + " for the " + restrictionURI);
}
try {
RepositoryResult<Statement> iter =
repositoryConnection.getStatements(getResource(restrictionURI), whatValueURI,
null, true);
if (iter.hasNext()) {
Value v = iter.next().getObject();
if (v instanceof Literal) {
return new PropertyValue(((Literal) v).getDatatype().toString(), ((Literal) v).getLabel());
}
} else {
throw new GateOntologyException("Could not find restriction value for "+restrictionURI+"/"+whatValueURI);
}
} catch (Exception e) {
throw new GateOntologyException(e);
}
return null;
}
/**
* Sets the datatype uri for the given restriction uri.
*
* @param restrictionURI
* @param datatypeURI
*/
public void setPropertyValue(String restrictionURI,
byte restrictionType, String value, String datatypeURI)
{
String whatValueURI = null;
switch (restrictionType) {
case OConstants.CARDINALITY_RESTRICTION:
whatValueURI = OWL.CARDINALITY.toString();
break;
case OConstants.MAX_CARDINALITY_RESTRICTION:
whatValueURI = OWL.MAXCARDINALITY.toString();
break;
case OConstants.MIN_CARDINALITY_RESTRICTION:
whatValueURI = OWL.MINCARDINALITY.toString();
break;
default:
throw new GateOntologyException("Invalid restriction type :" + restrictionType + " for the restriction " + restrictionURI);
}
Statement toDelete = null;
try {
RepositoryResult<Statement> iter =
repositoryConnection.getStatements(getResource(restrictionURI), makeSesameURI(whatValueURI),
null, true);
if (iter.hasNext()) {
Statement stmt = iter.next();
Value v = stmt.getObject();
if (v instanceof Literal) {
if (((Literal) v).getDatatype().toString().intern() == datatypeURI.intern()) {
toDelete = stmt;
}
}
}
} catch (Exception e) {
throw new GateOntologyException(e);
}
if (toDelete != null) {
Literal l = (Literal) toDelete.getObject();
removeUUUStatement(whatValueURI, l.getLabel(), l.getDatatype().toString());
}
addUUDStatement(restrictionURI, whatValueURI, value,
datatypeURI);
}
/**
* Gets the cardinality value specified on the given restriction uri.
*
* @param restrictionURI
* @param restrictionType
* - either of the following constants from the OConstants -
* ALL_VALUES_FROM_RESTRICTION, SOME_VALUES_FROM_RESTRICTION, and
* HAS_VALUE_RESTRICTION
* @return
*/
public ResourceInfo getRestrictionValue(
String restrictionURI, byte restrictionType)
{
System.out.println("getRestrictionValue for "+restrictionURI);
URI whatValueURI = null;
switch (restrictionType) {
case OConstants.ALL_VALUES_FROM_RESTRICTION:
whatValueURI = OWL.ALLVALUESFROM;
break;
case OConstants.HAS_VALUE_RESTRICTION:
whatValueURI = OWL.HASVALUE;
break;
case OConstants.SOME_VALUES_FROM_RESTRICTION:
whatValueURI = OWL.SOMEVALUESFROM;
break;
default:
throw new GateOntologyException("Invalid restriction type:" + restrictionType + " for the restriction " + restrictionURI);
}
String resourceURI;
try {
RepositoryResult<Statement> iter =
repositoryConnection.getStatements(string2SesameResource(restrictionURI), whatValueURI,
null, true);
if (iter.hasNext()) {
resourceURI = iter.next().getObject().toString();
Resource res = getResource(resourceURI);
boolean isRestriction =
repositoryConnection.hasStatement(
res,
RDF.TYPE,
OWL.RESTRICTION,
true);
byte classType = OConstants.OWL_CLASS;
if (isRestriction) {
if (repositoryConnection.hasStatement(res, OWL.HASVALUE, null, true)) {
classType = OConstants.HAS_VALUE_RESTRICTION;
} else if (repositoryConnection.hasStatement(res, OWL.SOMEVALUESFROM, null, true)) {
classType = OConstants.SOME_VALUES_FROM_RESTRICTION;
} else if (repositoryConnection.hasStatement(res, OWL.ALLVALUESFROM, null, true)) {
classType = OConstants.ALL_VALUES_FROM_RESTRICTION;
} else if (repositoryConnection.hasStatement(res, OWL.CARDINALITY, null, true)) {
classType = OConstants.CARDINALITY_RESTRICTION;
} else if (repositoryConnection.hasStatement(res, OWL.MINCARDINALITY, null, true)) {
classType = OConstants.MIN_CARDINALITY_RESTRICTION;
} else if (repositoryConnection.hasStatement(res, OWL.MAXCARDINALITY, null, true)) {
classType = OConstants.MAX_CARDINALITY_RESTRICTION;
}
}
if (classType == OConstants.OWL_CLASS) {
if (res instanceof BNode) {
classType = OConstants.ANNONYMOUS_CLASS;
} else {
// check if it is an instance
if (isIndividual(resourceURI)) {
classType = OConstants.INSTANCE;
}
}
}
return new ResourceInfo(resourceURI, classType);
}
} catch (Exception e) {
throw new GateOntologyException("Problem getting restriction value for "+restrictionURI,e);
}
return null;
}
/**
* tells if the given URI is registered as an individual
* @param individualURI
* @return
*/
public boolean isIndividual(String individualURI)
{
String query = "Select X from {<" + individualURI + ">} rdf:type {X} rdf:type {<http://www.w3.org/2002/07/owl#Class>}";
return hasSerqlQueryResultRows(query);
}
/**
* Sets the cardinality value for the given restriction uri.
*
* @param restrictionURI
* @param restrictionType
* - either of the following constants from the OConstants -
* ALL_VALUES_FROM_RESTRICTION, SOME_VALUES_FROM_RESTRICTION, and
* HAS_VALUE_RESTRICTION
* @param value
* @return
*/
public void setRestrictionValue(String restrictionURI,
byte restrictionType, String value)
{
String whatValueURI = null;
switch (restrictionType) {
case OConstants.ALL_VALUES_FROM_RESTRICTION:
whatValueURI = OWL.ALLVALUESFROM.toString();
break;
case OConstants.HAS_VALUE_RESTRICTION:
whatValueURI = OWL.HASVALUE.toString();
break;
case OConstants.SOME_VALUES_FROM_RESTRICTION:
whatValueURI = OWL.SOMEVALUESFROM.toString();
break;
default:
throw new GateOntologyException("Invalid restriction type:" + restrictionType + " for the restriction " + restrictionURI);
}
Statement toDelete = null;
try {
RepositoryResult<Statement> iter =
repositoryConnection.getStatements(getResource(restrictionURI), makeSesameURI(whatValueURI),
null, true);
if (iter.hasNext()) {
Statement stmt = iter.next();
Value v = stmt.getObject();
toDelete = stmt;
}
} catch (Exception e) {
throw new GateOntologyException(e);
}
if (toDelete != null) {
String objectString = toDelete.getObject().toString();
removeUUUStatement(restrictionURI, whatValueURI, objectString);
}
addUUUStatement(restrictionURI, whatValueURI, value);
}
/**
* This method tells what type of restriction the given uri refers to. If the
* given URI is not a restriction, the method returns -1. Otherwise one of the
* following values from the OConstants class. OWL_CLASS,
* CARDINALITY_RESTRICTION, MIN_CARDINALITY_RESTRICTION,
* MAX_CARDINALITY_RESTRICTION, HAS_VALUE_RESTRICTION,
* ALL_VALUES_FROM_RESTRICTION.
*
* @param restrictionURI
* @return
*/
// TODO: !!! how does this relate to getRestrictionForONodeID
public byte getClassType(String restrictionURI)
{
Resource res = getResource(restrictionURI);
logger.debug("Converted to resource: " + res);
String rep1 = "<" + restrictionURI + ">";
if (res instanceof BNode) {
logger.debug("is an instance of Bnode: " + res);
rep1 = restrictionURI;
}
if (res instanceof BNode) {
logger.debug("is an instance of Bnode: " + res);
String query = "select * from {" + rep1 + "} owl:hasValue {B}";
if (hasSerqlQueryResultRows(query)) {
return OConstants.HAS_VALUE_RESTRICTION;
}
query = "select * from {" + rep1 + "} owl:someValuesFrom {B}";
if (hasSerqlQueryResultRows(query)) {
return OConstants.SOME_VALUES_FROM_RESTRICTION;
}
query = "select * from {" + rep1 + "} owl:allValuesFrom {B}";
if (hasSerqlQueryResultRows(query)) {
return OConstants.ALL_VALUES_FROM_RESTRICTION;
}
query = "select * from {" + rep1 + "} owl:cardinality {B}";
if (hasSerqlQueryResultRows(query)) {
return OConstants.CARDINALITY_RESTRICTION;
}
query = "select * from {" + rep1 + "} owl:minCardinality {B}";
if (hasSerqlQueryResultRows(query)) {
return OConstants.MIN_CARDINALITY_RESTRICTION;
}
query = "select * from {" + rep1 + "} owl:maxCardinality {B}";
if (hasSerqlQueryResultRows(query)) {
return OConstants.MAX_CARDINALITY_RESTRICTION;
}
}
if (res instanceof BNode) {
logger.debug("is an instance of Bnode: " + res);
return OConstants.ANNONYMOUS_CLASS;
} else {
logger.debug("is an ordinary class: " + res);
return OConstants.OWL_CLASS;
}
}
/**
* The method is useful for adding statements into the graph. All three values
* must exist in repository. These values are cast in Resources and then added
* into the graph of repository.
*
* @param subjectURI
* @param predicateURI
* @param objectURI
*/
public void addStatement(String subjectURI,
String predicateURI, String objectURI)
{
try {
startTransaction(null);
Resource s = subjectURI != null ? getResource(subjectURI) : null;
URI p =
predicateURI != null
? repositoryConnection.getValueFactory().createURI(predicateURI)
: null;
Resource o = objectURI != null ? getResource(objectURI) : null;
repositoryConnection.add(s, p, o);
endTransaction(null);
} catch (Exception e) {
throw new GateOntologyException(
"error while adding statement into the repository where subject:" + subjectURI + " predicate:" + predicateURI + " objectURI:" + objectURI, e);
}
}
/**
* The method is useful for removing statements from the graph of repository.
* All three values must exist in repository. these values are cast in
* Resources and then removed from teh graph of repository.
*
* @param subjectURI
* @param predicateURI
* @param objectURI
*/
public void removeStatement(String subjectURI,
String predicateURI, String objectURI)
{
try {
startTransaction(null);
Resource s = subjectURI != null ? getResource(subjectURI) : null;
URI p =
predicateURI != null
? repositoryConnection.getValueFactory().createURI(predicateURI)
: null;
Resource o = objectURI != null ? getResource(objectURI) : null;
repositoryConnection.remove(s, p, o);
endTransaction(null);
} catch (Exception e) {
throw new GateOntologyException(
"error while removing statement from the repository where subject:" + subjectURI + " predicate:" + predicateURI + " objectURI:" + objectURI, e);
}
}
// ***************************************************************************
// *********************** Other Utility Methods
// **************************************************************************
private void addUUUStatement(String subject, String predicate, String object)
{
try {
startTransaction(null);
Resource s = subject != null ? getResource(subject) : null;
URI p =
predicate != null ? repositoryConnection.getValueFactory().createURI(predicate) : null;
Resource o = object != null ? getResource(object) : null;
repositoryConnection.add(s, p, o, DATA_CONTEXT_URI);
endTransaction(null);
} catch (Exception e) {
throw new GateOntologyException(
"error while adding statement into the repository where subject:" + subject + " predicate:" + predicate + " objectURI:" + object, e);
}
}
private void addUULStatement(String subject, String predicate, String object,
String language) throws GateOntologyException {
if (debug) {
logger.debug("addUULStatement for " + subject + " / " + predicate + " / " + object);
}
try {
startTransaction(null);
Resource s = subject != null ? getResource(subject) : null;
URI p =
predicate != null ? repositoryConnection.getValueFactory().createURI(predicate) : null;
Literal o = null;
if (language == null) {
o =
object != null ? repositoryConnection.getValueFactory().createLiteral(object) : null;
} else {
o =
object != null
? repositoryConnection.getValueFactory().createLiteral(object, language)
: null;
}
repositoryConnection.add(s, p, o, DATA_CONTEXT_URI);
endTransaction(null);
} catch (Exception e) {
throw new GateOntologyException(
"error while adding statement into the repository where subject:" + subject + " predicate:" + predicate + " objectURI:" + object, e);
}
}
public void addStatement(String subject,
String predicate, String object, String datatype)
{
try {
startTransaction(null);
Resource s = subject != null ? getResource(subject) : null;
URI p =
predicate != null ? repositoryConnection.getValueFactory().createURI(predicate) : null;
URI d = repositoryConnection.getValueFactory().createURI(datatype);
Literal l =
object != null ? repositoryConnection.getValueFactory().createLiteral(object, d) : null;
repositoryConnection.add(s, p, l, DATA_CONTEXT_URI);
endTransaction(null);
} catch (Exception e) {
throw new GateOntologyException(
"error while adding statement into the repository where subject:" + subject + " predicate:" + predicate + " objectURI:" + object, e);
}
}
public void addUUDStatement(String subject,
String predicate, String object, String datatype)
{
try {
startTransaction(null);
Resource s = subject != null ? getResource(subject) : null;
URI p =
predicate != null ? repositoryConnection.getValueFactory().createURI(predicate) : null;
URI d = repositoryConnection.getValueFactory().createURI(datatype);
Literal l =
object != null ? repositoryConnection.getValueFactory().createLiteral(object, d) : null;
repositoryConnection.add(s, p, l, DATA_CONTEXT_URI);
endTransaction(null);
} catch (Exception e) {
throw new GateOntologyException(
"error while adding statement into the repository where subject:" + subject + " predicate:" + predicate + " objectURI:" + object, e);
}
}
// NOTE: this originally returned the number of removed statements, but
// this does not work any more with Sesame2
private void removeUUUStatement(String subject, String predicate, String object)
{
try {
startTransaction(null);
Resource s = subject != null ? getResource(subject) : null;
URI p =
predicate != null ? repositoryConnection.getValueFactory().createURI(predicate) : null;
Resource o = object != null ? getResource(object) : null;
//int no = repositoryConnection.remove(s, p, o);
// TODO: should we restrict removal to the DATA context?
repositoryConnection.remove(s, p, o);
endTransaction(null);
//return no;
} catch (Exception e) {
throw new GateOntologyException(
"error while removing statement from the repository where subject:" + subject + " predicate:" + predicate + " objectURI:" + object, e);
}
}
private void removeUULStatement(String subject, String predicate,
String object, String language)
{
try {
startTransaction(null);
Resource s = subject != null ? getResource(subject) : null;
URI p =
predicate != null ? repositoryConnection.getValueFactory().createURI(predicate) : null;
Literal l = null;
if (language == null) {
l =
object != null ? repositoryConnection.getValueFactory().createLiteral(object) : null;
} else {
l =
object != null ? repositoryConnection.getValueFactory().createLiteral(object,
language) : null;
}
repositoryConnection.remove(s, p, l);
endTransaction(null);
} catch (Exception e) {
throw new GateOntologyException(
"error while removing statement from the repository where subject:" + subject + " predicate:" + predicate + " objectURI:" + object, e);
}
}
public void removeUUDStatement(String subject,
String predicate, String object, String datatype)
{
try {
startTransaction(null);
Resource s = subject != null ? getResource(subject) : null;
URI p =
predicate != null ? repositoryConnection.getValueFactory().createURI(predicate) : null;
URI d = repositoryConnection.getValueFactory().createURI(datatype);
Literal l =
object != null ? repositoryConnection.getValueFactory().createLiteral(object) : null;
repositoryConnection.remove(s, p, l);
l =
object != null ? repositoryConnection.getValueFactory().createLiteral(object, d) : null;
repositoryConnection.remove(s, p, l);
endTransaction(null);
} catch (Exception e) {
throw new GateOntologyException(
"error while removing statement from the repository where subject:" + subject + " predicate:" + predicate + " objectURI:" + object, e);
}
}
public void removeStatement(String subject,
String predicate, String object, String datatype)
{
try {
startTransaction(null);
Resource s = subject != null ? getResource(subject) : null;
URI p =
predicate != null ? repositoryConnection.getValueFactory().createURI(predicate) : null;
URI d = repositoryConnection.getValueFactory().createURI(datatype);
Literal l =
object != null ? repositoryConnection.getValueFactory().createLiteral(object) : null;
repositoryConnection.remove(s, p, l);
l =
object != null ? repositoryConnection.getValueFactory().createLiteral(object, d) : null;
repositoryConnection.remove(s, p, l);
endTransaction(null);
} catch (Exception e) {
throw new GateOntologyException(
"error while removing statement from the repository where subject:" + subject + " predicate:" + predicate + " objectURI:" + object, e);
}
}
public void startTransaction(String repositoryID)
{
}
public void endTransaction(String repositoryID) throws GateOntologyException {
}
private Property[] listToPropertyArray(List<Property> list) {
if (list == null) {
return null;
}
ArrayList<Property> subList = new ArrayList<Property>();
for (int i = 0; i < list.size(); i++) {
if (hasSystemNameSpace(list.get(i).getUri())) {
continue;
}
subList.add(list.get(i));
}
Property[] props = new Property[subList.size()];
for (int i = 0; i < subList.size(); i++) {
props[i] = subList.get(i);
}
return props;
}
private PropertyValue[] listToPropertyValueArray(List<PropertyValue> subList) {
if (subList == null) {
return null;
}
PropertyValue[] props = new PropertyValue[subList.size()];
for (int i = 0; i < subList.size(); i++) {
props[i] = subList.get(i);
}
return props;
}
private ResourceInfo[] listToResourceInfoArray(List<String> list) {
if (list == null) {
return null;
}
ArrayList<ResourceInfo> subList = new ArrayList<ResourceInfo>();
for (int i = 0; i < list.size(); i++) {
String resourceURI = list.get(i);
if (hasSystemNameSpace(resourceURI)) {
continue;
}
byte classType = getClassType(resourceURI);
if (classType == OConstants.ANNONYMOUS_CLASS) {
continue;
}
subList.add(new ResourceInfo(list.get(i).toString(), classType));
}
ResourceInfo[] strings = new ResourceInfo[subList.size()];
for (int i = 0; i < subList.size(); i++) {
strings[i] = subList.get(i);
}
return strings;
}
/**
* This method tells whether the resource is imported or added as an explicit
* statement.
*
* @param resourceURI
* @return
*/
// JP: seems what is meant here is "implicit" not "imported"
public boolean isImplicitResource(String resourceURI)
{
try {
return !repositoryConnection.hasStatement(getResource(resourceURI),
makeSesameURI(RDF.TYPE.toString()), null, false);
} catch (Exception e) {
throw new GateOntologyException(e);
}
}
private String[] listToArray(List<String> list) {
if (list == null) {
return null;
}
ArrayList<String> subList = new ArrayList<String>();
for (int i = 0; i < list.size(); i++) {
if (hasSystemNameSpace(list.get(i))) {
continue;
}
subList.add(list.get(i));
}
String[] strings = new String[subList.size()];
for (int i = 0; i < subList.size(); i++) {
strings[i] = subList.get(i);
}
return strings;
}
private org.openrdf.model.URI makeSesameURI(String string) {
Resource rs = repositoryConnection.getValueFactory().createURI(string);
return (URI) rs;
}
private Resource getResource(String string) {
Resource rs = null; // resourcesMap.get(string);
// TODO: !!!!!
if(string.startsWith("_:") ||
(!string.startsWith("_:") && !string.contains(":"))) {
if(string.startsWith("_:")) {
string = string.substring(2);
}
rs = repositoryConnection.getValueFactory().createBNode(string);
logger.debug("Created BNode resource for " + rs);
//resourcesMap.put(string, rs);
} else {
logger.debug("Creating resource for " + string);
rs = repositoryConnection.getValueFactory().createURI(string);
logger.debug("Created URI resource for " + string);
//resourcesMap.put(string, rs);
}
logger.debug("Created resource " + rs);
return rs;
}
// TODO: get rid of this and use ontology objects directly!
private Property createPropertyObject(String uri)
throws GateOntologyException {
byte type = OConstants.ANNOTATION_PROPERTY;
if (isAnnotationProperty(uri)) {
type = OConstants.ANNOTATION_PROPERTY;
} else if (isObjectProperty(uri)) {
type = OConstants.OBJECT_PROPERTY;
} else if (isDatatypeProperty(uri)) {
type = OConstants.DATATYPE_PROPERTY;
} else if (isTransitiveProperty(uri)) {
type = OConstants.TRANSITIVE_PROPERTY;
} else if (isSymmetricProperty(uri)) {
type = OConstants.SYMMETRIC_PROPERTY;
} else if (isRDFProperty(uri)) {
type = OConstants.RDF_PROPERTY;
} else {
return null;
}
return new Property(type, uri);
}
/**
* This method is used to obtain the most specific classes
*
* @param values
* @return
*/
private ResourceInfo[] reduceToMostSpecificClasses(List<ResourceInfo> values)
{
if (values == null || values.isEmpty()) {
return new ResourceInfo[0];
}
List<String> classes = new ArrayList<String>();
for (int i = 0; i < values.size(); i++) {
classes.add(values.get(i).getUri());
}
outer:
for (int i = 0; i < classes.size(); i++) {
String c = classes.get(i);
// if the class's children appear in list, it is not the most
// specific class
String queryRep = string2Turtle(c);
String query =
"select distinct A FROM {A} rdfs:subClassOf {" + queryRep +
"} WHERE A!=" + queryRep +
" AND A != ALL ( " +
" select distinct B FROM {B} owl:equivalentClass {" + queryRep + "} )";
List<String> list = new ArrayList<String>();
addSerqlQueryResultToCollection(query, list);
for (int j = 0; j < list.size(); j++) {
if (classes.contains(list.get(j))) {
classes.remove(i);
values.remove(i);
i--;
continue outer;
}
}
}
return values.toArray(new ResourceInfo[0]);
}
/**
* This method is used to obtain the most specific classes
*
* @param values
* @return
*/
private List<String> reduceToMostSpecificClasses(Set<String> values)
{
if (values == null || values.isEmpty()) {
return new ArrayList<String>();
}
List<String> classes = new ArrayList<String>(values);
outer:
for (int i = 0; i < classes.size(); i++) {
String c = classes.get(i);
// if the class's children appear in list, it is not the most
// specific class
String queryRep = string2Turtle(c);
String query =
"select distinct A FROM {A} rdfs:subClassOf {" + queryRep +
"} WHERE A!=" + queryRep + " AND A!= ALL ( " +
" select distinct B FROM {B} owl:equivalentClass {" + queryRep + "} )";
List<String> list = new ArrayList<String>();
addSerqlQueryResultToCollection(query, list);
for (int j = 0; j < list.size(); j++) {
if (classes.contains(list.get(j))) {
classes.remove(i);
i--;
continue outer;
}
}
}
return classes;
}
private byte getPropertyType(String aPropertyURI)
throws GateOntologyException {
if (isDatatypeProperty(aPropertyURI)) {
return OConstants.DATATYPE_PROPERTY;
} else if (isTransitiveProperty(aPropertyURI)) {
return OConstants.TRANSITIVE_PROPERTY;
} else if (isSymmetricProperty(aPropertyURI)) {
return OConstants.SYMMETRIC_PROPERTY;
} else if (isObjectProperty(aPropertyURI)) {
return OConstants.OBJECT_PROPERTY;
} else if (isAnnotationProperty(aPropertyURI)) {
return OConstants.ANNOTATION_PROPERTY;
} else {
return OConstants.RDF_PROPERTY;
}
}
private PropertyValue[] getPropertyValues(String aResourceURI, String aPropertyURI) throws GateOntologyException {
Resource r = getResource(aResourceURI);
String rep1 = "<" + aResourceURI + ">";
String rep2 = "{" + rep1 + "}";
if (r instanceof BNode) {
rep1 = "_:" + aResourceURI;
rep2 = "{" + rep1 + "}";
}
String query =
"Select DISTINCT Y from " + rep2 + " <" + aPropertyURI + "> {Y}";
UtilTupleQueryIterator result = performSerqlQuery(query);
List<PropertyValue> list = new ArrayList<PropertyValue>();
while (result.hasNext()) {
list.add(new PropertyValue(String.class.getName(), result.nextFirstAsString()));
}
result.close();
return listToPropertyValueArray(list);
}
String executeQuery(String serqlQuery) {
//logger.info("executeQuery: "+serqlQuery);
TupleQueryResult res = null;
String ret = "";
String msg = "Error executing query: "+serqlQuery;
try {
res = repositoryConnection.prepareTupleQuery(org.openrdf.query.QueryLanguage.SERQL, serqlQuery).evaluate();
// TODO: convert to string that is compatible what the old Sesame1 to string
// method did!
// code taken from Sesame1 org.openrdf.sesame.query.QueryResultsTable.toString()
StringBuffer buf = new StringBuffer();
List<String> bindings = res.getBindingNames();
//System.out.println("Found bindings: "+bindings);
String[] _columnNames = bindings.toArray(new String[0]);
//System.out.println("Found columns names: "+_columnNames);
if (_columnNames != null) {
for (int i = 0; i < _columnNames.length; i++) {
if (i > 0) {
buf.append("\t| ");
}
buf.append(_columnNames[i]);
}
buf.append('\n');
int dashCount = buf.length() + 7*(_columnNames.length-1);
for (int i = 0; i < dashCount; i++) {
buf.append('-');
}
buf.append('\n');
}
Vector<Value> columns = new Vector<Value>(bindings.size());
for(int j = 0; j < bindings.size(); j++) {
columns.add(null);
}
//for (int i = 0; i < _rowList.size(); i++) {
while(res.hasNext()) {
BindingSet bs = res.next();
int i = 0;
for(String name : bindings) {
columns.set(i++, bs.getValue(name));
//System.out.println("Found columns: "+columns);
}
//List columns = (List)_rowList.get(i);
for (int j = 0; j < columns.size(); j++) {
if (j > 0) {
buf.append("\t| ");
}
buf.append( columns.get(j).stringValue() );
}
buf.append('\n');
}
ret = buf.toString();
} catch (QueryEvaluationException ex) {
throw new GateOntologyException(msg,ex);
} catch (RepositoryException ex) {
throw new GateOntologyException(msg,ex);
} catch (MalformedQueryException ex) {
throw new GateOntologyException(msg,ex);
} finally {
if(res != null) {
try {
res.close();
} catch (QueryEvaluationException ex) {
throw new GateOntologyException(msg,ex);
}
}
}
//logger.info("executeQuery returns:\n"+ret+"\n");
return ret;
}
// ***************************************************************************
// *** UTILITY FUNCTIONS
// ***************************************************************************
public RepositoryConnection getRepositoryConnection() {
return repositoryConnection;
}
// TODO: is returnSystemStatements still relevant?
// if yes, check how often and where actually used
// This should probably become part of the query anyways.
// Try to get rid and move entirely to UtilConvert
private boolean hasSystemNameSpace(String uri) {
if (returnSystemStatements) {
return false;
}
Boolean val = new Boolean(Utils.hasSystemNameSpace(uri));
return val.booleanValue();
}
private RDFWriter getRDFWriter4Format(
OutputStream out, OntologyFormat ontologyFormat) {
RDFWriter writer = null;
switch (ontologyFormat) {
case N3:
writer = new N3Writer(out);
break;
case NTRIPLES:
writer = new NTriplesWriter(out);
break;
case TURTLE:
writer = new TurtleWriter(out);
break;
case RDFXML:
writer = new RDFXMLWriter(out);
break;
default:
throw new GateOntologyException("Unsupported ontology format: " + ontologyFormat);
}
return writer;
}
private RDFWriter getRDFWriter4Format(
Writer out, OntologyFormat ontologyFormat) {
RDFWriter writer = null;
switch (ontologyFormat) {
case N3:
writer = new N3Writer(out);
break;
case NTRIPLES:
writer = new NTriplesWriter(out);
break;
case TURTLE:
writer = new TurtleWriter(out);
break;
case RDFXML:
writer = new RDFXMLWriter(out);
break;
default:
throw new GateOntologyException("Unsupported ontology format: " + ontologyFormat);
}
return writer;
}
private RDFFormat ontologyFormat2RDFFormat(OntologyFormat format) {
switch(format) {
case RDFXML:
return RDFFormat.RDFXML;
case N3:
return RDFFormat.N3;
case NTRIPLES:
return RDFFormat.NTRIPLES;
case TURTLE:
return RDFFormat.TURTLE;
default:
throw new GateOntologyException("Unsupported ontology format: "+format);
}
}
private String string2Turtle(String queryRep1) {
if(!queryRep1.startsWith("_:") && !queryRep1.startsWith("<")) {
if(queryRep1.contains(":")) {
queryRep1 = "<"+queryRep1+">";
} else {
queryRep1 = "_:"+queryRep1;
}
}
return queryRep1;
}
private Resource string2SesameResource(String uriString) {
if(uriString.startsWith("_:")) {
return new BNodeImpl(uriString.substring(2));
} else {
// we can still get bnodeids from old methods where the initial _: is missing
// we assume that if the string contains a colon it must be a proper
// URI, otherwise it must be a Bnodeid
if(uriString.contains(":")) {
return new URIImpl(uriString);
} else {
return new BNodeImpl(uriString);
}
}
}
private Resource oNodeID2SesameResource(ONodeID id) {
if(id.isAnonymousResource()) {
// TODO: does this and should this include the _: part?
return new BNodeImpl(id.getResourceName());
} else {
return new URIImpl(id.toString());
}
}
private ONodeID string2ONodeID(String uri) {
if(uri.startsWith("_:")) {
return new OBNodeIDImpl(uri);
} else if(uri.contains(":")) {
return new OURIImpl(uri);
} else {
return new OBNodeIDImpl(uri);
}
}
// The query language of the query is determined automatically: if the
// query string contains "USING NAMESPACE" it is SERQL, if it contains
// "PREFIX" at the beginning of a line it is SPARQL. If neither applies,
// an exception is thrown.
UtilTupleQueryIterator qp_getClassesTopAll;
UtilTupleQueryIterator qp_getClassesAllAll;
UtilTupleQueryIterator qp_getOntologyURIs;
UtilTupleQueryIterator qp_getInstancesAll;
UtilTupleQueryIterator qp_getInstancesAllFor;
UtilTupleQueryIterator qp_getInstancesDirectFor;
UtilTupleQueryIterator qp_hasInstance;
// Unfortunately, the prepared queries do not work properly with
// setBinding, we need to do String substitution!
//UtilTupleQueryIterator qp_hasInstanceAllFor;
//UtilTupleQueryIterator qp_hasInstanceDirectFor;
String qs_hasInstanceAllFor;
QueryLanguage ql_hasInstanceAllFor;
String qs_hasInstanceDirectFor;
QueryLanguage ql_hasInstanceDirectFor;
UtilTupleQueryIterator qp_getRestrictionTypeFor;
// Unfortunately, the prepared queries do not work properly with
// setBinding, we need to do String substitution!
//UtilTupleQueryIterator qp_getSubClassesAllFor;
//UtilTupleQueryIterator qp_getSubClassesDirectFor;
String qs_getSubClassesAllFor;
QueryLanguage ql_getSubClassesAllFor;
String qs_getSubClassesDirectFor;
QueryLanguage ql_getSubClassesDirectFor;
String qs_getClassesByNameNoW3;
QueryLanguage ql_getClassesByNameNoW3;
//UtilTupleQueryIterator qp_getClassesByNameNoW3;
File queriesDir;
private void initQueries(String querySet) {
queriesDir =
new File(((AbstractOntologyImpl)ontology).getPluginDir(),"queries");
queriesDir = new File(queriesDir,querySet);
if(!queriesDir.exists()) {
throw new GateOntologyException("Queries directory not found: "+queriesDir.getAbsolutePath());
}
qp_getClassesTopAll = getPreparedTupleQueryFromFile("getClassesTopAll");
qp_getClassesAllAll = getPreparedTupleQueryFromFile("getClassesAllAll");
qp_getOntologyURIs = getPreparedTupleQueryFromFile("getOntologyURIs");
qp_getInstancesAll = getPreparedTupleQueryFromFile("getInstancesAll");
qp_getInstancesDirectFor = getPreparedTupleQueryFromFile("getInstancesDirectFor");
qp_getInstancesAllFor = getPreparedTupleQueryFromFile("getInstancesAllFor");
qp_hasInstance = getPreparedTupleQueryFromFile("hasInstance");
//qp_hasInstanceAllFor = getPreparedTupleQueryFromFile("hasInstanceAllFor");
//qp_hasInstanceDirectFor = getPreparedTupleQueryFromFile("hasInstanceDirectFor");
qs_hasInstanceAllFor = getQueryStringFromFile("hasInstanceAllFor");
ql_hasInstanceAllFor = determineQueryLanguage(qs_hasInstanceAllFor);
qs_hasInstanceDirectFor = getQueryStringFromFile("hasInstanceDirectFor");
ql_hasInstanceDirectFor = determineQueryLanguage(qs_hasInstanceDirectFor);
qp_getRestrictionTypeFor = getPreparedTupleQueryFromFile("getRestrictionTypeFor");
qs_getSubClassesAllFor = getQueryStringFromFile("getSubClassesAllFor");
ql_getSubClassesAllFor = determineQueryLanguage(qs_getSubClassesAllFor);
qs_getSubClassesDirectFor = getQueryStringFromFile("getSubClassesDirectFor");
ql_getSubClassesDirectFor = determineQueryLanguage(qs_getSubClassesDirectFor);
qs_getClassesByNameNoW3 = getQueryStringFromFile("getClassesByNameNoW3");
ql_getClassesByNameNoW3 = determineQueryLanguage(qs_getClassesByNameNoW3);
}
private UtilTupleQueryIterator getPreparedTupleQueryFromFile(String filename) {
String queryString = null;
try {
queryString =
FileUtils.readFileToString(new File(queriesDir, filename));
} catch (IOException ex) {
throw new GateOntologyException("Could not read query file: "+filename,ex);
}
QueryLanguage queryLanguage = determineQueryLanguage(queryString);
return new UtilTupleQueryIterator(repositoryConnection,
queryString,queryLanguage);
}
private String getQueryStringFromFile(String filename) {
String queryString = null;
try {
queryString =
FileUtils.readFileToString(new File(queriesDir, filename));
} catch (IOException ex) {
throw new GateOntologyException("Could not read query file: "+filename,ex);
}
return queryString;
}
private UtilBooleanQuery getPreparedBooleanQueryFromFile(String filename) {
String queryString = null;
try {
queryString =
FileUtils.readFileToString(new File(queriesDir, filename));
} catch (IOException ex) {
throw new GateOntologyException("Could not read query file: "+filename,ex);
}
QueryLanguage queryLanguage = determineQueryLanguage(queryString);
return new UtilBooleanQuery(repositoryConnection,
queryString,queryLanguage);
}
private QueryLanguage determineQueryLanguage(String query) {
if(query.contains("USING NAMESPACE")) {
return QueryLanguage.SERQL;
} else if(query.contains("PREFIX ")) {
return QueryLanguage.SPARQL;
} else {
throw new GateOntologyException("Could not determine query language for: "+query);
}
}
// ***************************************************************************
// **** STUFF TO GET RID OF EVENTUALLY
// ***************************************************************************
/**
* Debug parameter, if set to true, shows various messages when different
* methods are invoked
*/
private boolean debug = true;
public void setDebug(boolean debug) {
this.debug = debug;
}
public boolean getDebug() {
return debug;
}
// TODO: STUFF TO GET RID OF
// TODO: get rid of this or make semantics available to API?
// If it is just internal, make this local to whatever method and
// context where it is relevant
private boolean returnSystemStatements = false;
}