From 415da2eb8b34e82b2f4716325beb007fe32f4a03 Mon Sep 17 00:00:00 2001 From: Jim Balhoff Date: Fri, 8 Sep 2023 17:14:16 -0400 Subject: [PATCH] Add direct predicate options. Remove SPARQL federated query and SPARQL composer API. Remove OWL/XML syntax. (#123) --- build.sbt | 24 +- project/build.properties | 2 +- ...anchesterSyntaxClassExpressionParser.scala | 21 +- .../owlet/OWLXMLClassExpressionParser.scala | 176 -------- .../scala/org/phenoscape/owlet/Owlet.scala | 134 ++---- .../owlet/OwletManchesterSyntaxDataType.scala | 2 +- .../org/phenoscape/owlet/SPARQLComposer.scala | 202 --------- .../owlet/StandaloneEntityChecker.scala | 2 +- .../owlet/TestManchesterParserJava.java | 20 - .../phenoscape/owlet/TestSPARQLQueryJava.java | 51 --- .../owlet/TestManchesterParser.scala | 206 +++++---- .../phenoscape/owlet/TestQueryExpander.scala | 406 +++++++++--------- .../phenoscape/owlet/TestSPARQLComposer.scala | 74 ---- .../phenoscape/owlet/TestSPARQLQuery.scala | 245 +++-------- 14 files changed, 436 insertions(+), 1129 deletions(-) delete mode 100644 src/main/scala/org/phenoscape/owlet/OWLXMLClassExpressionParser.scala delete mode 100644 src/main/scala/org/phenoscape/owlet/SPARQLComposer.scala delete mode 100644 src/test/java/org/phenoscape/owlet/TestManchesterParserJava.java delete mode 100644 src/test/java/org/phenoscape/owlet/TestSPARQLQueryJava.java delete mode 100644 src/test/scala/org/phenoscape/owlet/TestSPARQLComposer.scala diff --git a/build.sbt b/build.sbt index 4358667..8a4fa6a 100644 --- a/build.sbt +++ b/build.sbt @@ -3,7 +3,7 @@ organization := "org.phenoscape" name := "owlet" -version := "1.9" +version := "2.0-SNAPSHOT" publishMavenStyle := true @@ -15,38 +15,39 @@ publishTo := { Some("releases" at nexus + "service/local/staging/deploy/maven2") } -publishArtifact in Test := false +Test / publishArtifact := false licenses := Seq("MIT" -> url("https://opensource.org/licenses/MIT")) homepage := Some(url("https://github.com/phenoscape/owlet")) -scalaVersion := "2.12.18" +scalaVersion := "2.13.11" -crossScalaVersions := Seq("2.12.18", "2.13.11") +//crossScalaVersions := Seq("2.13.11", "3") scalacOptions := Seq("-unchecked", "-deprecation", "-encoding", "utf8") -scalacOptions in Test ++= Seq("-Yrangepos") +Test / scalacOptions ++= Seq("-Yrangepos") + +testFrameworks += new TestFramework("utest.runner.Framework") + +Test / parallelExecution := false lazy val jenaVersion = "4.9.0" libraryDependencies ++= { Seq( - "org.scalaz" %% "scalaz-core" % "7.3.7", "net.sourceforge.owlapi" % "owlapi-distribution" % "4.5.26", "org.apache.jena" % "jena-core" % jenaVersion, "org.apache.jena" % "jena-arq" % jenaVersion, "com.typesafe.scala-logging" %% "scala-logging" % "3.9.5", - "org.scala-lang.modules" %% "scala-xml" % "2.2.0", - "org.slf4j" % "slf4j-log4j12" % "1.7.36" % Test, + "org.slf4j" % "slf4j-log4j12" % "2.0.9" % Test, "org.semanticweb.elk" % "elk-owlapi" % "0.4.3" % Test, - "junit" % "junit" % "4.13.2" % Test, - "com.github.sbt" % "junit-interface" % "0.13.3" % Test + "com.lihaoyi" %% "utest" % "0.8.1" % Test ) } -pomExtra := ( +pomExtra := git@github.com:phenoscape/owlet.git scm:git:git@github.com:phenoscape/owlet.git @@ -58,4 +59,3 @@ pomExtra := ( jim@balhoff.org -) \ No newline at end of file diff --git a/project/build.properties b/project/build.properties index 52413ab..3040987 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.9.3 +sbt.version=1.9.4 diff --git a/src/main/scala/org/phenoscape/owlet/ManchesterSyntaxClassExpressionParser.scala b/src/main/scala/org/phenoscape/owlet/ManchesterSyntaxClassExpressionParser.scala index 491e747..29c0f17 100644 --- a/src/main/scala/org/phenoscape/owlet/ManchesterSyntaxClassExpressionParser.scala +++ b/src/main/scala/org/phenoscape/owlet/ManchesterSyntaxClassExpressionParser.scala @@ -3,32 +3,31 @@ package org.phenoscape.owlet import org.semanticweb.owlapi.apibinding.OWLManager import org.semanticweb.owlapi.manchestersyntax.parser.ManchesterOWLSyntaxClassExpressionParser import org.semanticweb.owlapi.model._ -import scalaz._ -import scala.collection.JavaConverters._ import scala.collection.Map +import scala.jdk.CollectionConverters._ +import scala.util.Try object ManchesterSyntaxClassExpressionParser { - def parse(expression: String): Validation[String, OWLClassExpression] = parse(expression, Map[String, String]()) + def parse(expression: String): Either[String, OWLClassExpression] = parse(expression, Map[String, String]()) - def parse(expression: String, prefixes: Map[String, String]): Validation[String, OWLClassExpression] = { + def parse(expression: String, prefixes: Map[String, String]): Either[String, OWLClassExpression] = { val checker = new StandaloneEntityChecker(prefixes) val parser = new ManchesterOWLSyntaxClassExpressionParser(OWLManager.getOWLDataFactory, checker) - Validation.fromTryCatchNonFatal(parser.parse(expression)).leftMap(_.getMessage) + Try(parser.parse(expression)).toEither.left.map(_.getMessage) } - def parse(expression: String, prefixes: java.util.Map[String, String]): Validation[String, OWLClassExpression] = + def parse(expression: String, prefixes: java.util.Map[String, String]): Either[String, OWLClassExpression] = parse(expression, prefixes.asScala) - def parseIRI(input: String, prefixes: Map[String, String] = Map.empty): Validation[String, IRI] = { + def parseIRI(input: String, prefixes: Map[String, String] = Map.empty): Either[String, IRI] = StandaloneEntityChecker.nameToIRI(input, prefixes) match { - case Some(iri) => Validation.success(iri) - case None => Validation.failure("Invalid IRI") + case Some(iri) => Right(iri) + case None => Left("Invalid IRI") } - } - def parseIRI(input: String, prefixes: java.util.Map[String, String]): Validation[String, IRI] = + def parseIRI(input: String, prefixes: java.util.Map[String, String]): Either[String, IRI] = parseIRI(input, prefixes.asScala) } diff --git a/src/main/scala/org/phenoscape/owlet/OWLXMLClassExpressionParser.scala b/src/main/scala/org/phenoscape/owlet/OWLXMLClassExpressionParser.scala deleted file mode 100644 index 619b467..0000000 --- a/src/main/scala/org/phenoscape/owlet/OWLXMLClassExpressionParser.scala +++ /dev/null @@ -1,176 +0,0 @@ -package org.phenoscape.owlet - -import org.semanticweb.owlapi.apibinding.OWLManager -import org.semanticweb.owlapi.model._ - -import scala.collection.JavaConverters._ -import scala.collection.Map -import scala.xml.{Elem, XML} - -object OWLXMLClassExpressionParser { - - val factory = OWLManager.getOWLDataFactory - - case class ObjectRestriction(property: OWLObjectPropertyExpression, filler: Option[OWLClassExpression]) - - def parse(expression: String): Option[OWLClassExpression] = { - parse(expression, Map()) - } - - def parse(expression: String, prefixes: Map[String, String]): Option[OWLClassExpression] = { - val expressionXML = XML.loadString(expression) - Option(parseClassExpression(expressionXML, prefixes)) - } - - def parseClassExpression(element: Elem, prefixes: Map[String, String]): OWLClassExpression = { - element match { - case => parseClass(element, prefixes) - case {_*} => parseObjectIntersectionOf(element, prefixes) - case {_*} => parseObjectUnionOf(element, prefixes) - case {_*} => parseObjectComplementOf(element, prefixes) - case {_*} => parseObjectOneOf(element, prefixes) - case {_*} => parseObjectSomeValuesFrom(element, prefixes) - case {_*} => parseObjectAllValuesFrom(element, prefixes) - case {_*} => parseObjectHasValue(element, prefixes) - case {_*} => parseObjectHasSelf(element, prefixes) - case {_*} => parseObjectMinCardinality(element, prefixes) - case {_*} => parseObjectMaxCardinality(element, prefixes) - case {_*} => parseObjectExactCardinality(element, prefixes) - case {_*} => ??? - case {_*} => ??? - case {_*} => ??? - case {_*} => ??? - case {_*} => ??? - case {_*} => ??? - case _ => null - } - } - - def parseClass(element: Elem, prefixes: Map[String, String]): OWLClass = { - factory.getOWLClass(parseIRI(element, prefixes)) - } - - def parseObjectIntersectionOf(element: Elem, prefixes: Map[String, String]): OWLObjectIntersectionOf = { - val classes = children(element) map (parseClassExpression(_, prefixes)) - factory.getOWLObjectIntersectionOf(classes.toSet.asJava) - } - - def parseObjectUnionOf(element: Elem, prefixes: Map[String, String]): OWLObjectUnionOf = { - val classes = children(element) map (parseClassExpression(_, prefixes)) - factory.getOWLObjectUnionOf(classes.toSet.asJava) - } - - def parseObjectSomeValuesFrom(element: Elem, prefixes: Map[String, String]): OWLObjectSomeValuesFrom = { - def struct = parseObjectRestriction(element, prefixes) - factory.getOWLObjectSomeValuesFrom(struct.property, struct.filler.get) - } - - def parseObjectAllValuesFrom(element: Elem, prefixes: Map[String, String]): OWLObjectAllValuesFrom = { - def struct = parseObjectRestriction(element, prefixes) - factory.getOWLObjectAllValuesFrom(struct.property, struct.filler.get) - } - - def parseObjectRestriction(element: Elem, prefixes: Map[String, String]): ObjectRestriction = { - val childElements = children(element) - val property = parsePropertyExpression(childElements.head, prefixes) - val filler = if (childElements.size > 1) - Option(parseClassExpression(childElements(1), prefixes)) - else - None - ObjectRestriction(property, filler) - } - - def parseObjectComplementOf(element: Elem, prefixes: Map[String, String]): OWLObjectComplementOf = { - factory.getOWLObjectComplementOf(parseClassExpression(children(element).head, prefixes)) - } - - def parseObjectOneOf(element: Elem, prefixes: Map[String, String]): OWLObjectOneOf = { - val individuals = children(element) map (parseIndividual(_, prefixes)) - factory.getOWLObjectOneOf(individuals.toSet.asJava) - } - - def parseObjectHasValue(element: Elem, prefixes: Map[String, String]): OWLObjectHasValue = { - val childElements = children(element) - val property = parsePropertyExpression(childElements.head, prefixes) - val filler = parseIndividual(childElements(1), prefixes) - factory.getOWLObjectHasValue(property, filler) - } - - def parseObjectHasSelf(element: Elem, prefixes: Map[String, String]): OWLObjectHasSelf = { - val property = parsePropertyExpression(children(element).head, prefixes) - factory.getOWLObjectHasSelf(property) - } - - def parseObjectMinCardinality(element: Elem, prefixes: Map[String, String]): OWLObjectMinCardinality = { - val restriction = parseObjectRestriction(element, prefixes) - val cardinality = (element \ "@cardinality").head.text.toInt - restriction match { - case ObjectRestriction(property, Some(filler)) => factory.getOWLObjectMinCardinality(cardinality, property, filler) - case ObjectRestriction(property, None) => factory.getOWLObjectMinCardinality(cardinality, property) - } - } - - def parseObjectMaxCardinality(element: Elem, prefixes: Map[String, String]): OWLObjectMaxCardinality = { - val restriction = parseObjectRestriction(element, prefixes) - val cardinality = (element \ "@cardinality").head.text.toInt - restriction match { - case ObjectRestriction(property, Some(filler)) => factory.getOWLObjectMaxCardinality(cardinality, property, filler) - case ObjectRestriction(property, None) => factory.getOWLObjectMaxCardinality(cardinality, property) - } - } - - def parseObjectExactCardinality(element: Elem, prefixes: Map[String, String]): OWLObjectExactCardinality = { - val restriction = parseObjectRestriction(element, prefixes) - val cardinality = (element \ "@cardinality").head.text.toInt - restriction match { - case ObjectRestriction(property, Some(filler)) => factory.getOWLObjectExactCardinality(cardinality, property, filler) - case ObjectRestriction(property, None) => factory.getOWLObjectExactCardinality(cardinality, property) - } - } - - def parseIndividual(element: Elem, prefixes: Map[String, String]): OWLIndividual = { - element match { - case => parseNamedIndividual(element, prefixes) - case => parseAnonymousIndividual(element, prefixes) - } - } - - def parseNamedIndividual(element: Elem, prefixes: Map[String, String]): OWLNamedIndividual = { - factory.getOWLNamedIndividual(parseIRI(element, prefixes)) - } - - def parseAnonymousIndividual(element: Elem, prefixes: Map[String, String]): OWLAnonymousIndividual = { - val nodeID = (element \ "@nodeID").head.text - factory.getOWLAnonymousIndividual(nodeID) - } - - def parsePropertyExpression(element: Elem, prefixes: Map[String, String]): OWLObjectPropertyExpression = { - element match { - case => parseObjectProperty(element, prefixes) - case {_*} => parseInverseProperty(element, prefixes) - } - } - - def parseObjectProperty(element: Elem, prefixes: Map[String, String]): OWLObjectProperty = { - factory.getOWLObjectProperty(parseIRI(element, prefixes)) - } - - def parseInverseProperty(element: Elem, prefixes: Map[String, String]): OWLObjectInverseOf = { - val property = parseObjectProperty(children(element).head, prefixes) - factory.getOWLObjectInverseOf(property) - } - - def parseIRI(element: Elem, prefixes: Map[String, String]): IRI = { - val iriString = (element \ "@IRI").headOption.map(_.text).getOrElse(expandAbbreviatedIRI((element \ "@abbreviatedIRI").head.text, prefixes)) - IRI.create(iriString) - } - - def expandAbbreviatedIRI(value: String, prefixes: Map[String, String]): String = { - val segments = value.split(":", 2) - val localName = if (segments.size > 1) segments(1) else "" - prefixes(segments(0)) + localName - } - - def children(element: Elem): Seq[Elem] = (element.child collect { case e: Elem => e }) - -} \ No newline at end of file diff --git a/src/main/scala/org/phenoscape/owlet/Owlet.scala b/src/main/scala/org/phenoscape/owlet/Owlet.scala index e76c07e..95cafcb 100644 --- a/src/main/scala/org/phenoscape/owlet/Owlet.scala +++ b/src/main/scala/org/phenoscape/owlet/Owlet.scala @@ -1,23 +1,19 @@ package org.phenoscape.owlet import org.apache.jena.graph._ -import org.apache.jena.graph.impl.GraphBase import org.apache.jena.query._ -import org.apache.jena.rdf.model.ModelFactory import org.apache.jena.sparql.core.{TriplePath, Var} import org.apache.jena.sparql.engine.binding.BindingFactory import org.apache.jena.sparql.expr._ import org.apache.jena.sparql.expr.nodevalue.NodeValueNode import org.apache.jena.sparql.syntax._ -import org.apache.jena.util.iterator.{ExtendedIterator, WrappedIterator} import org.apache.jena.vocabulary.{OWL2, RDF, RDFS} -import org.semanticweb.owlapi.apibinding.OWLManager +import org.eclipse.rdf4j.model.vocabulary.SESAME import org.semanticweb.owlapi.model._ import org.semanticweb.owlapi.reasoner.OWLReasoner -import java.util.UUID -import scala.collection.JavaConverters._ import scala.collection.Map +import scala.jdk.CollectionConverters._ /** * Processes SPARQL queries containing triple patterns with embedded OWL class expressions. @@ -26,8 +22,6 @@ import scala.collection.Map */ class Owlet(reasoner: OWLReasoner) { - private val factory = OWLManager.getOWLDataFactory - def expandQueryString(query: String, asValues: Boolean = false): String = { val parsedQuery = QueryFactory.create(query) expandQuery(parsedQuery, asValues).toString @@ -67,90 +61,52 @@ class Owlet(reasoner: OWLReasoner) { } - private def querySubClasses(expression: OWLClassExpression): Set[OWLClass] = { - val subclasses = reasoner.getSubClasses(expression, false).getFlattened.asScala.toSet - if (!expression.isAnonymous) - subclasses + expression.asOWLClass - else - subclasses - } - - private def queryEquivalentClasses(expression: OWLClassExpression): Set[OWLClass] = { - val equivalents = reasoner.getEquivalentClasses(expression).getEntities.asScala.toSet - if (!expression.isAnonymous) - equivalents + expression.asOWLClass - else - equivalents - } - - private def querySuperClasses(expression: OWLClassExpression): Set[OWLClass] = { - val superclasses = reasoner.getSuperClasses(expression, false).getFlattened.asScala.toSet - if (!expression.isAnonymous) - superclasses + expression.asOWLClass - else - superclasses - } - - private def queryIndividuals(expression: OWLClassExpression): Set[OWLNamedIndividual] = reasoner.getInstances(expression, false).getFlattened.asScala.toSet - - private def matchTriple(triple: TriplePath, prefixes: Map[String, String]): Option[OwletResult] = for { - (expression, queryFunction) <- (triple.getSubject, triple.getPredicate, triple.getObject) match { - case (_: Node_Variable | Node.ANY, Owlet.SubClassOf, expression: Node_Literal) if Owlet.SYNTAXES(expression.getLiteralDatatypeURI) => - Option(expression, querySubClasses _) - case (expression: Node_Literal, Owlet.SubClassOf, _: Node_Variable | Node.ANY) if Owlet.SYNTAXES(expression.getLiteralDatatypeURI) => - Option(expression, querySuperClasses _) - case (_: Node_Variable | Node.ANY, Owlet.EquivalentClass, expression: Node_Literal) if Owlet.SYNTAXES(expression.getLiteralDatatypeURI) => - Option(expression, queryEquivalentClasses _) - case (expression: Node_Literal, Owlet.EquivalentClass, _: Node_Variable | Node.ANY) if Owlet.SYNTAXES(expression.getLiteralDatatypeURI) => - Option(expression, queryEquivalentClasses _) - case (_: Node_Variable | Node.ANY, Owlet.Type, expression: Node_Literal) if Owlet.SYNTAXES(expression.getLiteralDatatypeURI) => - Option(expression, queryIndividuals _) - case _ => None - } - classExpression <- Owlet.parseExpression(expression, prefixes) - } yield { - val namedQuery = addQueryAsClass(classExpression) - OwletResult(triple.asTriple, queryFunction(namedQuery)) - } - - def addQueryAsClass(expression: OWLClassExpression): OWLClass = expression match { - case named: OWLClass => named - case anonymous => - val ontology = reasoner.getRootOntology - val manager = ontology.getOWLOntologyManager - val namedQuery = factory.getOWLClass(IRI.create(s"http://example.org/${UUID.randomUUID.toString}")) - manager.addAxiom(ontology, factory.getOWLEquivalentClassesAxiom(namedQuery, expression)) - reasoner.flush() - namedQuery - } - - def performSPARQLQuery(query: Query): ResultSet = { - val prefixMap = query.getPrefixMapping.getNsPrefixMap.asScala.toMap - val model = ModelFactory.createModelForGraph(new OwletGraph(prefixMap)) - val queryExecution = QueryExecutionFactory.create(query, model) - // The query optimizer must be turned off so that the OWL reasoner - // can be queried once rather than for every VALUES binding. - // This also makes property paths work correctly with our fake RDF graph. - ARQ.enableOptimizer(queryExecution.getContext, false) - queryExecution.execSelect - } - - private class OwletGraph(prefixes: Map[String, String]) extends GraphBase { - - override def graphBaseFind(pattern: Triple): ExtendedIterator[Triple] = { - val results = matchTriple(new TriplePath(pattern), prefixes).map(_.toTriples).getOrElse(Set()) - WrappedIterator.create(results.iterator.asJava) - } - - } + private def querySubClasses(expression: OWLClassExpression, direct: Boolean): Set[OWLClass] = + reasoner.getSubClasses(expression, direct).getFlattened.asScala.toSet.filterNot(_.isOWLNothing) + + private def queryEquivalentClasses(expression: OWLClassExpression): Set[OWLClass] = + reasoner.getEquivalentClasses(expression).getEntities.asScala.toSet + + private def querySuperClasses(expression: OWLClassExpression, direct: Boolean): Set[OWLClass] = + reasoner.getSuperClasses(expression, direct).getFlattened.asScala.toSet.filterNot(_.isOWLThing) + + private def queryIndividuals(expression: OWLClassExpression, direct: Boolean): Set[OWLNamedIndividual] = + reasoner.getInstances(expression, direct).getFlattened.asScala.toSet + + private def matchTriple(triple: TriplePath, prefixes: Map[String, String]): Option[OwletResult] = + for { + (expression, queryFunction) <- (triple.getSubject, triple.getPredicate, triple.getObject) match { + case (_: Node_Variable | Node.ANY, Owlet.SubClassOf, expression: Node_Literal) if Owlet.SYNTAXES(expression.getLiteralDatatypeURI) => + Option(expression, querySubClasses(_, false)) + case (_: Node_Variable | Node.ANY, Owlet.DirectSubClassOf, expression: Node_Literal) if Owlet.SYNTAXES(expression.getLiteralDatatypeURI) => + Option(expression, querySubClasses(_, true)) + case (expression: Node_Literal, Owlet.SubClassOf, _: Node_Variable | Node.ANY) if Owlet.SYNTAXES(expression.getLiteralDatatypeURI) => + Option(expression, querySuperClasses(_, false)) + case (expression: Node_Literal, Owlet.DirectSubClassOf, _: Node_Variable | Node.ANY) if Owlet.SYNTAXES(expression.getLiteralDatatypeURI) => + Option(expression, querySuperClasses(_, true)) + case (_: Node_Variable | Node.ANY, Owlet.EquivalentClass, expression: Node_Literal) if Owlet.SYNTAXES(expression.getLiteralDatatypeURI) => + Option(expression, queryEquivalentClasses _) + case (expression: Node_Literal, Owlet.EquivalentClass, _: Node_Variable | Node.ANY) if Owlet.SYNTAXES(expression.getLiteralDatatypeURI) => + Option(expression, queryEquivalentClasses _) + case (_: Node_Variable | Node.ANY, Owlet.Type, expression: Node_Literal) if Owlet.SYNTAXES(expression.getLiteralDatatypeURI) => + Option(expression, queryIndividuals(_, false)) + case (_: Node_Variable | Node.ANY, Owlet.DirectType, expression: Node_Literal) if Owlet.SYNTAXES(expression.getLiteralDatatypeURI) => + Option(expression, queryIndividuals(_, true)) + case _ => None + } + classExpression <- Owlet.parseExpression(expression, prefixes) + } yield OwletResult(triple.asTriple, queryFunction(classExpression)) } object Owlet { - val SubClassOf: Node = RDFS.Nodes.subClassOf - val EquivalentClass: Node = OWL2.equivalentClass.asNode - val Type: Node = RDF.Nodes.`type` + private val SubClassOf: Node = RDFS.Nodes.subClassOf + private val DirectSubClassOf: Node = NodeFactory.createURI(SESAME.DIRECTSUBCLASSOF.stringValue()) + private val EquivalentClass: Node = OWL2.equivalentClass.asNode + private val Type: Node = RDF.Nodes.`type` + private val DirectType: Node = NodeFactory.createURI(SESAME.DIRECTTYPE.stringValue()) + val OWLET_NS: String = "http://purl.org/phenoscape/owlet/syntax#" val MANCHESTER: String = s"${OWLET_NS}omn" val OWLXML: String = s"${OWLET_NS}owx" @@ -166,12 +122,10 @@ object Owlet { val expression = literal.getLiteralLexicalForm literal.getLiteralDatatypeURI match { case MANCHESTER => ManchesterSyntaxClassExpressionParser.parse(expression, prefixes).toOption - case OWLXML => OWLXMLClassExpressionParser.parse(expression, prefixes) - case FUNCTIONAL => parseFunctional(expression, prefixes) + case _ => None } } - private def parseFunctional(expression: String, prefixes: Map[String, String]): Option[OWLClassExpression] = ??? def makeFilter(variable: Node_Variable, classes: Iterable[OWLEntity]): ElementFilter = { val nodes = classes.map(term => new NodeValueNode(NodeFactory.createURI(term.getIRI.toString))) diff --git a/src/main/scala/org/phenoscape/owlet/OwletManchesterSyntaxDataType.scala b/src/main/scala/org/phenoscape/owlet/OwletManchesterSyntaxDataType.scala index d2a09a9..ae26a70 100644 --- a/src/main/scala/org/phenoscape/owlet/OwletManchesterSyntaxDataType.scala +++ b/src/main/scala/org/phenoscape/owlet/OwletManchesterSyntaxDataType.scala @@ -32,4 +32,4 @@ object OwletManchesterSyntaxDataType { } -} \ No newline at end of file +} diff --git a/src/main/scala/org/phenoscape/owlet/SPARQLComposer.scala b/src/main/scala/org/phenoscape/owlet/SPARQLComposer.scala deleted file mode 100644 index 5499166..0000000 --- a/src/main/scala/org/phenoscape/owlet/SPARQLComposer.scala +++ /dev/null @@ -1,202 +0,0 @@ -package org.phenoscape.owlet - -import org.apache.jena.datatypes.{RDFDatatype, TypeMapper} -import org.apache.jena.graph.{Node, NodeFactory, Triple} -import org.apache.jena.query.{Query, QueryFactory, QuerySolution, SortCondition} -import org.apache.jena.sparql.core.{BasicPattern, TriplePath, Var} -import org.apache.jena.sparql.expr._ -import org.apache.jena.sparql.path._ -import org.apache.jena.sparql.syntax._ -import org.semanticweb.owlapi.model.{IRI, OWLClassExpression, OWLEntity, OWLProperty} -import org.semanticweb.owlapi.reasoner.OWLReasoner - -import scala.collection.JavaConverters._ - -object SPARQLComposer { - - def construct(triples: BasicTriple*): Query = { - val query = QueryFactory.make() - query.setQueryConstructType() - val bgp = BasicPattern.wrap(triples.map(triple => new Triple(triple.s, triple.p, triple.o)).asJava) - query.setConstructTemplate(new Template(bgp)) - query - } - - def select(resultVars: Var*): Query = { - val query = QueryFactory.make() - query.setQuerySelectType() - resultVars foreach { - query.addResultVar(_) - } - query - } - - def select_distinct(resultVars: Var*): Query = { - val query = select(resultVars: _*) - query.setDistinct(true) - query - } - - // def WITH(uri: String): UpdateDeleteInsert = { - // val update = new UpdateDeleteInsert() - // update.setWithIRI(NodeFactory.createURI(uri)) - // update - // } - - // def INSERT: UpdateDeleteInsert = { - // val update = new UpdateDeleteInsert() - // update. - // update - // } - - def bgp(triples: TripleOrPath*): ElementPathBlock = { - val block = new ElementPathBlock() - triples.foreach { - case triple: BasicTriple => block.addTriple(new Triple(triple.s, triple.p, triple.o)) - case path: PathTriple => block.addTriplePath(new TriplePath(path.s, path.p, path.o)) - } - block - } - - def optional(elements: Element*): ElementOptional = { - val body = new ElementGroup() - elements.foreach(body.addElement) - new ElementOptional(body) - } - - def service(uri: String, elements: Element*): ElementService = { - val body = new ElementGroup() - elements.foreach(body.addElement) - new ElementService(uri, body) - } - - def subClassOf(variable: Symbol, expression: OWLClassExpression)(implicit reasoner: OWLReasoner): ElementFilter = { - val subclasses = reasoner.getSubClasses(expression, false).getFlattened.asScala - val filterClasses = if (!expression.isAnonymous) - subclasses + expression.asOWLClass - else - subclasses - Owlet.makeFilter(variable, filterClasses) - } - - def str(variable: Var): E_Str = new E_Str(new ExprVar(variable)) - - def asc(variable: Var): SortCondition = new SortCondition(variable, Query.ORDER_ASCENDING) - - def desc(variable: Var): SortCondition = new SortCondition(variable, Query.ORDER_DESCENDING) - - implicit def symbolToVar(value: Symbol): Var = Var.alloc(value.name) - - implicit def symbolToSortCondition(value: Symbol): SortCondition = new SortCondition(symbolToVar(value), Query.ORDER_DEFAULT) - - implicit def iriToNode(iri: IRI): Node = NodeFactory.createURI(iri.toString) - - //implicit def iriToPath(iri: IRI): P_Link = new P_Link(iriToNode(iri)) - - implicit def owlEntityToNode(entity: OWLEntity): Node = iriToNode(entity.getIRI) - - //implicit def owlEntityToPath(entity: OWLEntity): P_Link = new P_Link(owlEntityToNode(entity)) - - def t(s: Node, p: Path, o: Node): PathTriple = PathTriple(s, p, o) - - def t(s: Node, p: Node, o: Node): BasicTriple = BasicTriple(s, p, o) - - sealed trait TripleOrPath - - case class BasicTriple(s: Node, p: Node, o: Node) extends TripleOrPath - - case class PathTriple(s: Node, p: Path, o: Node) extends TripleOrPath - - implicit def triplePathToTriple(tp: TriplePath): Triple = tp.asTriple - - //new ElementFilter(new E_OneOf(new ExprVar('matrix), new ExprList(publications.map(new NodeValueNode(_)).toList))) - - def filter(in: E_OneOf): ElementFilter = new ElementFilter(in) - - implicit class ComposerSymbol(val self: Symbol) extends AnyVal { - - def in(list: ExprList): E_OneOf = new E_OneOf(new ExprVar(self.toString), list) - } - - implicit def listToExprList(list: List[Node]): ExprList = { - val exprs: List[Expr] = list.map(NodeValue.makeNode(_)) - new ExprList(exprs.asJava) - } - - implicit class StringToLiteral(val self: String) extends AnyVal { - - def ^^(datatypeURI: String): Node = { - ^^(TypeMapper.getInstance.getSafeTypeByName(datatypeURI)) - } - - def ^^(datatype: RDFDatatype): Node = { - NodeFactory.createLiteral(self, datatype) - } - - } - - implicit class ComposerQuery(val self: Query) extends AnyVal { - - def from(uri: String): Query = { - self.addGraphURI(uri) - self - } - - def where(elements: Element*): Query = { - val body = new ElementGroup() - elements foreach { - body.addElement(_) - } - self.setQueryPattern(body) - self - } - - def order_by(sortConditions: SortCondition*): Query = { - sortConditions.foreach(self.addOrderBy(_)) - self - } - - def limit(count: Int): Query = { - self.setLimit(count) - self - } - - def into[T](func: QuerySolution => T): Query = { - ??? - } - - } - - implicit class ComposerProperty(val self: OWLProperty) extends AnyVal { - - def /(rightSide: Path): P_Seq = new P_Seq(new P_Link(owlEntityToNode(self)), rightSide) - - def /(rightSide: Node): P_Seq = new P_Seq(new P_Link(owlEntityToNode(self)), new P_Link(rightSide)) - - def |(rightSide: Path): P_Alt = new P_Alt(new P_Link(owlEntityToNode(self)), rightSide) - - def |(rightSide: Node): P_Alt = new P_Alt(new P_Link(owlEntityToNode(self)), new P_Link(rightSide)) - - def * : P_ZeroOrMore1 = new P_ZeroOrMore1(new P_Link(owlEntityToNode(self))) - - def + : P_OneOrMore1 = new P_OneOrMore1(new P_Link(owlEntityToNode(self))) - - def ? : P_ZeroOrMore1 = new P_ZeroOrMore1(new P_Link(owlEntityToNode(self))) - - } - - implicit class ComposerPath(val self: Path) extends AnyVal { - - def /(rightSide: Path): P_Seq = new P_Seq(self, rightSide) - - def /(rightSide: Node): P_Seq = new P_Seq(self, new P_Link(rightSide)) - - } - - // implicit class ComposerExprFunction(val self: ExprFunction) extends AnyVal { - // - // def as(variable: Var): - // - // } - -} \ No newline at end of file diff --git a/src/main/scala/org/phenoscape/owlet/StandaloneEntityChecker.scala b/src/main/scala/org/phenoscape/owlet/StandaloneEntityChecker.scala index 4105d3b..485c5ee 100644 --- a/src/main/scala/org/phenoscape/owlet/StandaloneEntityChecker.scala +++ b/src/main/scala/org/phenoscape/owlet/StandaloneEntityChecker.scala @@ -6,7 +6,7 @@ import org.semanticweb.owlapi.model._ import org.semanticweb.owlapi.model.parameters.Imports import org.semanticweb.owlapi.vocab.{OWL2Datatype, OWLRDFVocabulary, XSDVocabulary} -import scala.collection.JavaConverters._ +import scala.jdk.CollectionConverters._ class StandaloneEntityChecker(prefixes: PartialFunction[String, String], ontologyOpt: Option[OWLOntology] = None) extends OWLEntityChecker { diff --git a/src/test/java/org/phenoscape/owlet/TestManchesterParserJava.java b/src/test/java/org/phenoscape/owlet/TestManchesterParserJava.java deleted file mode 100644 index 5dfbc14..0000000 --- a/src/test/java/org/phenoscape/owlet/TestManchesterParserJava.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.phenoscape.owlet; - -import java.util.HashMap; -import java.util.Map; - -import org.junit.Test; - -public class TestManchesterParserJava { - - /** - * Demonstrate that we can use the parser from Java. - */ - @Test - public void testExpressions() { - final Map prefixes = new HashMap(); - prefixes.put("ex", "http://example.org/"); - ManchesterSyntaxClassExpressionParser.parse("ex:head and not (ex:part_of some ex:eye)", prefixes); - } - -} diff --git a/src/test/java/org/phenoscape/owlet/TestSPARQLQueryJava.java b/src/test/java/org/phenoscape/owlet/TestSPARQLQueryJava.java deleted file mode 100644 index 4625117..0000000 --- a/src/test/java/org/phenoscape/owlet/TestSPARQLQueryJava.java +++ /dev/null @@ -1,51 +0,0 @@ -package org.phenoscape.owlet; - -import java.io.IOException; -import java.io.InputStream; - -import org.apache.jena.query.Query; -import org.apache.jena.query.QueryExecutionFactory; -import org.apache.jena.query.QueryFactory; -import org.apache.jena.query.ResultSet; -import org.apache.jena.rdf.model.Model; -import org.apache.jena.rdf.model.ModelFactory; -import org.junit.Test; -import org.semanticweb.elk.owlapi.ElkReasonerFactory; -import org.semanticweb.owlapi.apibinding.OWLManager; -import org.semanticweb.owlapi.model.OWLOntology; -import org.semanticweb.owlapi.model.OWLOntologyCreationException; -import org.semanticweb.owlapi.model.OWLOntologyManager; -import org.semanticweb.owlapi.reasoner.InferenceType; -import org.semanticweb.owlapi.reasoner.OWLReasoner; - -public class TestSPARQLQueryJava { - - @Test - public void testSPARQLQuery() throws OWLOntologyCreationException, IOException { - final OWLOntologyManager manager = OWLManager.createOWLOntologyManager(); - final InputStream owlStream = this.getClass().getClassLoader().getResourceAsStream("vsao.owl"); - final OWLOntology ontology = manager.loadOntologyFromOntologyDocument(owlStream); - owlStream.close(); - final OWLReasoner reasoner = new ElkReasonerFactory().createReasoner(ontology); - reasoner.precomputeInferences(InferenceType.CLASS_HIERARCHY); - final InputStream rdfStream = this.getClass().getClassLoader().getResourceAsStream("vsao.owl"); - final Model rdfModel = ModelFactory.createDefaultModel(); - rdfModel.read(rdfStream, null); - rdfStream.close(); - final String queryText = "PREFIX rdfs: \n" - + "PREFIX ow: \n" - + "PREFIX axial_skeleton: \n" - + "PREFIX definition: \n" - + "PREFIX part_of: \n" - + "SELECT DISTINCT ?structure ?label ?definition\n" + "WHERE\n" + "{\n" - + "?structure rdfs:label ?label .\n" + "?structure definition: ?definition .\n" - + "?structure rdfs:subClassOf \"part_of: some axial_skeleton:\"^^ow:omn .\n" + "}"; - - final Owlet owlet = new Owlet(reasoner); - final Query query = QueryFactory.create(queryText); - final Query expandedQuery = owlet.expandQuery(query, true); - @SuppressWarnings("unused") - final ResultSet results = QueryExecutionFactory.create(expandedQuery, rdfModel).execSelect(); - } - -} diff --git a/src/test/scala/org/phenoscape/owlet/TestManchesterParser.scala b/src/test/scala/org/phenoscape/owlet/TestManchesterParser.scala index c86c969..9dc3a34 100644 --- a/src/test/scala/org/phenoscape/owlet/TestManchesterParser.scala +++ b/src/test/scala/org/phenoscape/owlet/TestManchesterParser.scala @@ -1,113 +1,107 @@ package org.phenoscape.owlet -import org.junit.Assert -import org.junit.Test import org.semanticweb.owlapi.apibinding.OWLManager -import org.semanticweb.owlapi.model.IRI -import org.semanticweb.owlapi.model.OWLClass -import org.semanticweb.owlapi.model.OWLClassExpression -import scalaz.Validation +import org.semanticweb.owlapi.model.{IRI, OWLClass, OWLClassExpression} +import utest._ + +object TestManchesterParser extends TestSuite { + + private val factory = OWLManager.getOWLDataFactory + + val tests: Tests = Tests { + test("Test expressions") - { + val head = factory.getOWLClass(IRI.create("http://example.org/head")) + val cell = factory.getOWLClass(IRI.create("http://example.org/cell")) + val nucleus = factory.getOWLClass(IRI.create("http://example.org/nucleus")) + val muscle = factory.getOWLClass(IRI.create("http://example.org/muscle")) + val eye = factory.getOWLClass(IRI.create("http://example.org/eye")) + val part_of = factory.getOWLObjectProperty(IRI.create("http://example.org/part_of")) + val has_part = factory.getOWLObjectProperty(IRI.create("http://example.org/has_part")) + + val parsed1 = ManchesterSyntaxClassExpressionParser.parse("ex:head", Map("ex" -> "http://example.org/")).toOption.get + assert(parsed1.isInstanceOf[OWLClass]) + assert(head == parsed1) + + val parsed2 = ManchesterSyntaxClassExpressionParser.parse("head").toOption + assert(parsed2.isEmpty) + + val parsed3 = ManchesterSyntaxClassExpressionParser.parse("head:", Map("head" -> "http://example.org/head")).toOption.get + assert(head == parsed3) + + val parsed4 = ManchesterSyntaxClassExpressionParser.parse(":head", Map("" -> "http://example.org/")).toOption.get + assert(head == parsed4) + + val parsed5 = ManchesterSyntaxClassExpressionParser.parse(" or ").toOption.get + assert(factory.getOWLObjectUnionOf(head, muscle) == parsed5) + + val parsed6 = ManchesterSyntaxClassExpressionParser.parse(" and some ").toOption.get + assert(factory.getOWLObjectIntersectionOf(muscle, factory.getOWLObjectSomeValuesFrom(part_of, head)) == parsed6) + + val parsed6a = ManchesterSyntaxClassExpressionParser.parse(" that some ").toOption.get + + assert(factory.getOWLObjectIntersectionOf(muscle, factory.getOWLObjectSomeValuesFrom(part_of, head)) == parsed6a) + + val parsed6b = ManchesterSyntaxClassExpressionParser.parse(" that not ( some )").toOption.get + assert(factory.getOWLObjectIntersectionOf(muscle, factory.getOWLObjectComplementOf(factory.getOWLObjectSomeValuesFrom(part_of, head))) == parsed6b) + + val parsed6c = ManchesterSyntaxClassExpressionParser.parse(" that not ( some ) and some ").toOption.get + assert(factory.getOWLObjectIntersectionOf(muscle, factory.getOWLObjectComplementOf(factory.getOWLObjectSomeValuesFrom(part_of, head)), factory.getOWLObjectSomeValuesFrom(part_of, eye)) == parsed6c) + + val parsed7 = ManchesterSyntaxClassExpressionParser.parse("not and some ").toOption.get + assert(factory.getOWLObjectIntersectionOf(factory.getOWLObjectComplementOf(muscle), factory.getOWLObjectSomeValuesFrom(part_of, head)) == parsed7) + + val parsed8 = ManchesterSyntaxClassExpressionParser.parse("ex:head and not (ex:part_of some ex:eye)", Map("ex" -> "http://example.org/")).toOption.get + assert(factory.getOWLObjectIntersectionOf(head, factory.getOWLObjectComplementOf(factory.getOWLObjectSomeValuesFrom(part_of, eye))) == parsed8) + + val parsed9 = ManchesterSyntaxClassExpressionParser.parse("not(ex:head)", Map("ex" -> "http://example.org/")).toOption.get + assert(factory.getOWLObjectComplementOf(head) == parsed9) + + val parsed10 = ManchesterSyntaxClassExpressionParser.parse("(ex:head or ex:cell) and not(ex:nucleus) and ex:part_of some (ex:eye or ex:muscle)", Map("ex" -> "http://example.org/")).toOption.get + val built10 = factory.getOWLObjectIntersectionOf( + factory.getOWLObjectUnionOf(head, cell), + factory.getOWLObjectComplementOf(nucleus), + factory.getOWLObjectSomeValuesFrom(part_of, factory.getOWLObjectUnionOf(eye, muscle))) + assert(built10 == parsed10) + + val parsed11 = ManchesterSyntaxClassExpressionParser.parse("ex:cell and ex:has_part max 1 ex:nucleus or ex:eye", Map("ex" -> "http://example.org/")).toOption.get + val built11 = factory.getOWLObjectUnionOf( + factory.getOWLObjectIntersectionOf(cell, factory.getOWLObjectMaxCardinality(1, has_part, nucleus)), + eye) + assert(built11 == parsed11) + + val parsed12 = ManchesterSyntaxClassExpressionParser.parse("", Map("ex" -> "http://example.org/")) + assert(parsed12.isLeft) + } + + test("Test UUID expressions") - { + // the prefix regex performed worse and worse as the local name got longer + val prefixes = Map("" -> "http://purl.obolibrary.org/obo/") + val parsed = ManchesterSyntaxClassExpressionParser.parse(":UBERONTEMP_18a5dd1b-1213-471f-9a0b-06190b1ecf2c", prefixes) + assert(parsed.toOption.get.isInstanceOf[OWLClass]) // problem is that parsing never returns + } + + test("Test prefix error") - { + val prefixes = Map("" -> "http://purl.obolibrary.org/obo/") + val expression = " some " + val parsed = ManchesterSyntaxClassExpressionParser.parse(expression, prefixes) + assert(parsed.toOption.get.isInstanceOf[OWLClassExpression]) + } + + test("Test fail on missing prefix") - { + val expression = "ex:head and not (ex:part_of some ex:eye)" + val parsed = ManchesterSyntaxClassExpressionParser.parse(expression).toOption + assert(parsed.isEmpty) + val parsedWithPrefixes = ManchesterSyntaxClassExpressionParser.parse(expression, Map("ex" -> "http://example.org/")) + assert(parsedWithPrefixes.toOption.get.isInstanceOf[OWLClassExpression]) + } + + test("Test IRI parsing") - { + val parsed1 = ManchesterSyntaxClassExpressionParser.parseIRI("ex:head", Map("ex" -> "http://example.org/")).toOption.get + assert(IRI.create("http://example.org/head") == parsed1) + val parsed2 = ManchesterSyntaxClassExpressionParser.parseIRI("").toOption.get + assert(IRI.create("http://example.org/head") == parsed2) + } -class TestManchesterParser { - - val factory = OWLManager.getOWLDataFactory - - @Test - def testExpressions(): Unit = { - val head = factory.getOWLClass(IRI.create("http://example.org/head")) - val cell = factory.getOWLClass(IRI.create("http://example.org/cell")) - val nucleus = factory.getOWLClass(IRI.create("http://example.org/nucleus")) - val muscle = factory.getOWLClass(IRI.create("http://example.org/muscle")) - val eye = factory.getOWLClass(IRI.create("http://example.org/eye")) - val part_of = factory.getOWLObjectProperty(IRI.create("http://example.org/part_of")) - val has_part = factory.getOWLObjectProperty(IRI.create("http://example.org/has_part")) - - val parsed1 = ManchesterSyntaxClassExpressionParser.parse("ex:head", Map("ex" -> "http://example.org/")).toOption.get - Assert.assertTrue(parsed1.isInstanceOf[OWLClass]) - Assert.assertEquals(head, parsed1) - - val parsed2 = ManchesterSyntaxClassExpressionParser.parse("head").toOption - Assert.assertEquals(None, parsed2) - - val parsed3 = ManchesterSyntaxClassExpressionParser.parse("head:", Map("head" -> "http://example.org/head")).toOption.get - Assert.assertEquals(head, parsed3) - - val parsed4 = ManchesterSyntaxClassExpressionParser.parse(":head", Map("" -> "http://example.org/")).toOption.get - Assert.assertEquals(head, parsed4) - - val parsed5 = ManchesterSyntaxClassExpressionParser.parse(" or ").toOption.get - Assert.assertEquals(factory.getOWLObjectUnionOf(head, muscle), parsed5) - - val parsed6 = ManchesterSyntaxClassExpressionParser.parse(" and some ").toOption.get - Assert.assertEquals(factory.getOWLObjectIntersectionOf(muscle, factory.getOWLObjectSomeValuesFrom(part_of, head)), parsed6) - - val parsed6a = ManchesterSyntaxClassExpressionParser.parse(" that some ").toOption.get - - Assert.assertEquals(factory.getOWLObjectIntersectionOf(muscle, factory.getOWLObjectSomeValuesFrom(part_of, head)), parsed6a) - - val parsed6b = ManchesterSyntaxClassExpressionParser.parse(" that not ( some )").toOption.get - Assert.assertEquals(factory.getOWLObjectIntersectionOf(muscle, factory.getOWLObjectComplementOf(factory.getOWLObjectSomeValuesFrom(part_of, head))), parsed6b) - - val parsed6c = ManchesterSyntaxClassExpressionParser.parse(" that not ( some ) and some ").toOption.get - Assert.assertEquals(factory.getOWLObjectIntersectionOf(muscle, factory.getOWLObjectComplementOf(factory.getOWLObjectSomeValuesFrom(part_of, head)), factory.getOWLObjectSomeValuesFrom(part_of, eye)), parsed6c) - - val parsed7 = ManchesterSyntaxClassExpressionParser.parse("not and some ").toOption.get - Assert.assertEquals(factory.getOWLObjectIntersectionOf(factory.getOWLObjectComplementOf(muscle), factory.getOWLObjectSomeValuesFrom(part_of, head)), parsed7) - - val parsed8 = ManchesterSyntaxClassExpressionParser.parse("ex:head and not (ex:part_of some ex:eye)", Map("ex" -> "http://example.org/")).toOption.get - Assert.assertEquals(factory.getOWLObjectIntersectionOf(head, factory.getOWLObjectComplementOf(factory.getOWLObjectSomeValuesFrom(part_of, eye))), parsed8) - - val parsed9 = ManchesterSyntaxClassExpressionParser.parse("not(ex:head)", Map("ex" -> "http://example.org/")).toOption.get - Assert.assertEquals(factory.getOWLObjectComplementOf(head), parsed9) - - val parsed10 = ManchesterSyntaxClassExpressionParser.parse("(ex:head or ex:cell) and not(ex:nucleus) and ex:part_of some (ex:eye or ex:muscle)", Map("ex" -> "http://example.org/")).toOption.get - val built10 = factory.getOWLObjectIntersectionOf( - factory.getOWLObjectUnionOf(head, cell), - factory.getOWLObjectComplementOf(nucleus), - factory.getOWLObjectSomeValuesFrom(part_of, factory.getOWLObjectUnionOf(eye, muscle))) - Assert.assertEquals(built10, parsed10) - - val parsed11 = ManchesterSyntaxClassExpressionParser.parse("ex:cell and ex:has_part max 1 ex:nucleus or ex:eye", Map("ex" -> "http://example.org/")).toOption.get - val built11 = factory.getOWLObjectUnionOf( - factory.getOWLObjectIntersectionOf(cell, factory.getOWLObjectMaxCardinality(1, has_part, nucleus)), - eye) - Assert.assertEquals(built11, parsed11) - - val parsed12 = ManchesterSyntaxClassExpressionParser.parse("", Map("ex" -> "http://example.org/")) - Assert.assertTrue(parsed12.isFailure) - } - - @Test - def testUUIDExpression(): Unit = { - // the prefix regex performed worse and worse as the local name got longer - val prefixes = Map("" -> "http://purl.obolibrary.org/obo/") - val parsed = ManchesterSyntaxClassExpressionParser.parse(":UBERONTEMP_18a5dd1b-1213-471f-9a0b-06190b1ecf2c", prefixes) - Assert.assertTrue(parsed.toOption.get.isInstanceOf[OWLClass]) // problem is that parsing never returns - } - - @Test - def testPrefixError(): Unit = { - val prefixes = Map("" -> "http://purl.obolibrary.org/obo/") - val expression = " some " - val parsed = ManchesterSyntaxClassExpressionParser.parse(expression, prefixes) - Assert.assertTrue(parsed.toOption.get.isInstanceOf[OWLClassExpression]) - } - - @Test - def testFailOnMissingPrefix(): Unit = { - val expression = "ex:head and not (ex:part_of some ex:eye)" - val parsed = ManchesterSyntaxClassExpressionParser.parse(expression).toOption - Assert.assertEquals(None, parsed) - val parsedWithPrefixes = ManchesterSyntaxClassExpressionParser.parse(expression, Map("ex" -> "http://example.org/")) - Assert.assertTrue(parsedWithPrefixes.toOption.get.isInstanceOf[OWLClassExpression]) - } - - @Test - def testIRIParsing(): Unit = { - val parsed1 = ManchesterSyntaxClassExpressionParser.parseIRI("ex:head", Map("ex" -> "http://example.org/")).toOption.get - Assert.assertEquals(IRI.create("http://example.org/head"), parsed1) - val parsed2 = ManchesterSyntaxClassExpressionParser.parseIRI("").toOption.get - Assert.assertEquals(IRI.create("http://example.org/head"), parsed2) } } \ No newline at end of file diff --git a/src/test/scala/org/phenoscape/owlet/TestQueryExpander.scala b/src/test/scala/org/phenoscape/owlet/TestQueryExpander.scala index 022c5ed..c301be2 100644 --- a/src/test/scala/org/phenoscape/owlet/TestQueryExpander.scala +++ b/src/test/scala/org/phenoscape/owlet/TestQueryExpander.scala @@ -1,219 +1,207 @@ package org.phenoscape.owlet import org.apache.jena.atlas.lib.EscapeStr -import org.junit.AfterClass -import org.junit.Assert -import org.junit.BeforeClass -import org.junit.Test import org.semanticweb.elk.owlapi.ElkReasonerFactory import org.semanticweb.owlapi.apibinding.OWLManager import org.semanticweb.owlapi.reasoner.InferenceType -import org.semanticweb.owlapi.reasoner.OWLReasoner - -object TestQueryExpander { - - var reasoner: OWLReasoner = null - - @BeforeClass - def setupReasoner(): Unit = { - val manager = OWLManager.createOWLOntologyManager() - val vsaoStream = this.getClass.getClassLoader.getResourceAsStream("vsao.owl") - val vsao = manager.loadOntologyFromOntologyDocument(vsaoStream) - reasoner = new ElkReasonerFactory().createReasoner(vsao) - reasoner.precomputeInferences(InferenceType.CLASS_HIERARCHY) - } +import utest._ + +object TestQueryExpander extends TestSuite { + + private val manager = OWLManager.createOWLOntologyManager() + private val vsaoStream = this.getClass.getClassLoader.getResourceAsStream("vsao.owl") + private val vsao = manager.loadOntologyFromOntologyDocument(vsaoStream) + private val reasoner = new ElkReasonerFactory().createReasoner(vsao) + reasoner.precomputeInferences(InferenceType.CLASS_HIERARCHY) + + override def utestAfterAll(): Unit = reasoner.dispose() + + val tests: Tests = Tests { + test("Test query expander") - { + val expander = new Owlet(reasoner) + + val manchesterQuery = + """ + PREFIX rdf: + PREFIX rdfs: + PREFIX xsd: + PREFIX owl: + PREFIX sesame: + PREFIX ow: + PREFIX vsao: + PREFIX axial_skeleton: + PREFIX part_of: + PREFIX has_part: + SELECT * + WHERE + { + ?organism has_part: ?part . + ?part rdf:type ?structure . + ?structure sesame:directSubClassOf "part_of: some axial_skeleton:"^^ow:omn . + } + """ + val expandedQuery = expander.expandQueryString(manchesterQuery) + assert(expandedQuery.contains("0000093")) + assert(expandedQuery.contains("0000049")) + assert(expandedQuery.contains("0000183")) + assert(expandedQuery.contains("0000185")) + assert(expandedQuery.contains("0000149")) + assert(expandedQuery.contains("0000184")) + assert(!expandedQuery.contains("0000082")) + + val manchesterQueryDirect = + """ + PREFIX rdf: + PREFIX rdfs: + PREFIX xsd: + PREFIX owl: + PREFIX ow: + PREFIX vsao: + PREFIX axial_skeleton: + PREFIX part_of: + PREFIX has_part: + SELECT * + WHERE + { + ?organism has_part: ?part . + ?part rdf:type ?structure . + ?structure rdfs:subClassOf "part_of: some axial_skeleton:"^^ow:omn . + } + """ + val expandedQueryDirect = expander.expandQueryString(manchesterQueryDirect) + assert(expandedQueryDirect.contains("0000093")) + assert(expandedQueryDirect.contains("0000049")) + assert(expandedQueryDirect.contains("0000183")) + assert(expandedQueryDirect.contains("0000185")) + assert(expandedQueryDirect.contains("0000149")) + assert(expandedQueryDirect.contains("0000082")) + assert(expandedQueryDirect.contains("0000184")) + } + + test("Test for null pointer exception with property paths") - { + val query = + """ + PREFIX rdf: + PREFIX rdfs: + PREFIX dc: + PREFIX obo: + PREFIX ps: + PREFIX ow: + PREFIX StandardState: + PREFIX has_character: + PREFIX has_state: + PREFIX belongs_to_tu: + PREFIX has_external_reference: + PREFIX HasNumberOf: + PREFIX Count: + PREFIX part_of: + PREFIX LimbFin: + PREFIX Sarcopterygii: + + SELECT DISTINCT ?character ?entity ?entity_label ?state ?state_label ?matrix_label ?taxon ?taxon_label + FROM + WHERE + { + ?character ?entity . + ?character ?quality . + FILTER(?quality IN (Count:, HasNumberOf:)) + ?entity rdfs:subClassOf "part_of: some LimbFin:"^^ow:omn . + ?eq rdfs:subClassOf ?character . + ?pheno_instance rdf:type ?eq . + ?state ps:denotes_exhibiting ?pheno_instance . + ?state rdf:type StandardState: . + ?state dc:description ?state_label . + ?entity rdfs:label ?entity_label . + ?quality rdfs:label ?quality_label . + ?matrix has_character: ?matrix_char . + ?matrix rdfs:label ?matrix_label . + ?matrix_char ps:may_have_state_value ?state . + ?cell has_state: ?state . + ?cell belongs_to_tu: ?otu . + ?otu has_external_reference: ?taxon . + ?taxon rdfs:label ?taxon_label . + ?taxon rdfs:subClassOf* Sarcopterygii: . + }""" + val expander = new Owlet(reasoner) + expander.expandQueryString(query) + } + + test("Test for P not a URI node") - { + val query = + """ + PREFIX rdf: + PREFIX rdfs: + PREFIX xsd: + PREFIX owl: + PREFIX skos: + PREFIX foaf: + PREFIX dc: + SELECT ?s ?p ?o + WHERE { + ?s ?p ?o + } + LIMIT 10 + """ + val expander = new Owlet(reasoner) + expander.expandQueryString(query) + } + + test("Test nested filter") - { + val manchesterQuery = + """ + PREFIX rdf: + PREFIX rdfs: + PREFIX xsd: + PREFIX owl: + PREFIX ow: + PREFIX vsao: + PREFIX axial_skeleton: + PREFIX part_of: + PREFIX has_part: + SELECT * + WHERE + { + ?organism has_part: ?part . + FILTER EXISTS { + ?part rdf:type ?structure . + ?structure rdfs:subClassOf "part_of: some axial_skeleton:"^^ow:omn . + } + } + """ + val expander = new Owlet(TestQueryExpander.reasoner) + val expandedQuery = expander.expandQueryString(manchesterQuery) + assert(expandedQuery.contains("FILTER ( ?structure IN")) + } + + test("Test subquery") - { + val manchesterQuery = + """ + PREFIX rdf: + PREFIX rdfs: + PREFIX xsd: + PREFIX owl: + PREFIX ow: + PREFIX vsao: + PREFIX axial_skeleton: + PREFIX part_of: + PREFIX has_part: + SELECT * + WHERE + { + ?organism has_part: ?part . + { + SELECT ?part WHERE { + ?part rdf:type ?structure . + ?structure rdfs:subClassOf "part_of: some axial_skeleton:"^^ow:omn . + } + } + } + """ + val expander = new Owlet(TestQueryExpander.reasoner) + val expandedQuery = expander.expandQueryString(manchesterQuery, true) + assert(expandedQuery.contains("VALUES ?structure {")) + } - @AfterClass - def disposeReasoner(): Unit = { - reasoner.dispose() } } - -class TestQueryExpander { - - @Test - def testQueryExpander(): Unit = { - val expander = new Owlet(TestQueryExpander.reasoner) - - val xmlExpression = - val xmlExpressionText = EscapeStr.stringEsc(xmlExpression.toString()) - val xmlQuery = """ - PREFIX rdf: - PREFIX rdfs: - PREFIX xsd: - PREFIX owl: - PREFIX ow: - PREFIX vsao: - PREFIX axial_skeleton: - PREFIX part_of: - PREFIX has_part: - SELECT * - WHERE - { - ?organism has_part: ?part . - ?part rdf:type ?structure . - ?structure rdfs:subClassOf "%s"^^ow:owx . - } - """.format(xmlExpressionText) - - println(xmlQuery) - expander.expandQueryString(xmlQuery) - - val manchesterQuery = """ - PREFIX rdf: - PREFIX rdfs: - PREFIX xsd: - PREFIX owl: - PREFIX ow: - PREFIX vsao: - PREFIX axial_skeleton: - PREFIX part_of: - PREFIX has_part: - SELECT * - WHERE - { - ?organism has_part: ?part . - ?part rdf:type ?structure . - ?structure rdfs:subClassOf "part_of: some axial_skeleton:"^^ow:omn . - } - """ - val expandedQuery = expander.expandQueryString(manchesterQuery) - Assert.assertTrue("Filter should contain term with identifier", expandedQuery.contains("0000093")) - Assert.assertTrue("Filter should contain term with identifier", expandedQuery.contains("0000049")) - Assert.assertTrue("Filter should contain term with identifier", expandedQuery.contains("0000183")) - Assert.assertTrue("Filter should contain term with identifier", expandedQuery.contains("0000185")) - Assert.assertTrue("Filter should contain term with identifier", expandedQuery.contains("0000149")) - Assert.assertTrue("Filter should contain term with identifier", expandedQuery.contains("0000082")) - Assert.assertTrue("Filter should contain term with identifier", expandedQuery.contains("0000184")) - } - - @Test - def testForNullPointerExceptionWithPropertyPaths(): Unit = { - val query = """ - PREFIX rdf: - PREFIX rdfs: - PREFIX dc: - PREFIX obo: - PREFIX ps: - PREFIX ow: - PREFIX StandardState: - PREFIX has_character: - PREFIX has_state: - PREFIX belongs_to_tu: - PREFIX has_external_reference: - PREFIX HasNumberOf: - PREFIX Count: - PREFIX part_of: - PREFIX LimbFin: - PREFIX Sarcopterygii: - - SELECT DISTINCT ?character ?entity ?entity_label ?state ?state_label ?matrix_label ?taxon ?taxon_label - FROM - WHERE - { - ?character ?entity . - ?character ?quality . - FILTER(?quality IN (Count:, HasNumberOf:)) - ?entity rdfs:subClassOf "part_of: some LimbFin:"^^ow:omn . - ?eq rdfs:subClassOf ?character . - ?pheno_instance rdf:type ?eq . - ?state ps:denotes_exhibiting ?pheno_instance . - ?state rdf:type StandardState: . - ?state dc:description ?state_label . - ?entity rdfs:label ?entity_label . - ?quality rdfs:label ?quality_label . - ?matrix has_character: ?matrix_char . - ?matrix rdfs:label ?matrix_label . - ?matrix_char ps:may_have_state_value ?state . - ?cell has_state: ?state . - ?cell belongs_to_tu: ?otu . - ?otu has_external_reference: ?taxon . - ?taxon rdfs:label ?taxon_label . - ?taxon rdfs:subClassOf* Sarcopterygii: . - }""" - val expander = new Owlet(TestQueryExpander.reasoner) - val expandedQuery = expander.expandQueryString(query) - println(expandedQuery) - } - - @Test - def testForPNotAURINode(): Unit = { - val query = """ - PREFIX rdf: - PREFIX rdfs: - PREFIX xsd: - PREFIX owl: - PREFIX skos: - PREFIX foaf: - PREFIX dc: - SELECT ?s ?p ?o - WHERE { - ?s ?p ?o - } - LIMIT 10 - """ - val expander = new Owlet(TestQueryExpander.reasoner) - val expandedQuery = expander.expandQueryString(query) - println(expandedQuery) - } - - @Test - def testNestedFilter(): Unit = { - val manchesterQuery = """ - PREFIX rdf: - PREFIX rdfs: - PREFIX xsd: - PREFIX owl: - PREFIX ow: - PREFIX vsao: - PREFIX axial_skeleton: - PREFIX part_of: - PREFIX has_part: - SELECT * - WHERE - { - ?organism has_part: ?part . - FILTER EXISTS { - ?part rdf:type ?structure . - ?structure rdfs:subClassOf "part_of: some axial_skeleton:"^^ow:omn . - } - } - """ - val expander = new Owlet(TestQueryExpander.reasoner) - val expandedQuery = expander.expandQueryString(manchesterQuery) - println(expandedQuery) - Assert.assertTrue(expandedQuery.contains("FILTER ( ?structure IN")) - } - - @Test - def testSubQuery(): Unit = { - val manchesterQuery = """ - PREFIX rdf: - PREFIX rdfs: - PREFIX xsd: - PREFIX owl: - PREFIX ow: - PREFIX vsao: - PREFIX axial_skeleton: - PREFIX part_of: - PREFIX has_part: - SELECT * - WHERE - { - ?organism has_part: ?part . - { - SELECT ?part WHERE { - ?part rdf:type ?structure . - ?structure rdfs:subClassOf "part_of: some axial_skeleton:"^^ow:omn . - } - } - } - """ - val expander = new Owlet(TestQueryExpander.reasoner) - val expandedQuery = expander.expandQueryString(manchesterQuery, true) - println(expandedQuery) - Assert.assertTrue(expandedQuery.contains("VALUES ?structure {")) - } - -} \ No newline at end of file diff --git a/src/test/scala/org/phenoscape/owlet/TestSPARQLComposer.scala b/src/test/scala/org/phenoscape/owlet/TestSPARQLComposer.scala deleted file mode 100644 index d28a524..0000000 --- a/src/test/scala/org/phenoscape/owlet/TestSPARQLComposer.scala +++ /dev/null @@ -1,74 +0,0 @@ -package org.phenoscape.owlet - -import org.junit.{Assert, Test} -import org.phenoscape.owlet.OwletManchesterSyntaxDataType._ -import org.phenoscape.owlet.SPARQLComposer._ -import org.semanticweb.owlapi.apibinding.OWLManager -import org.semanticweb.owlapi.model.IRI -import org.semanticweb.owlapi.vocab.OWLRDFVocabulary - -import scala.language.postfixOps - -class TestSPARQLComposer { - - val omn = Owlet.MANCHESTER - val factory = OWLManager.getOWLDataFactory - - @Test - def testZeroOrMorePropertyPath(): Unit = { - val head = factory.getOWLClass(IRI.create("http://example.org/head")) - val muscle = factory.getOWLClass(IRI.create("http://example.org/muscle")) - val part_of = factory.getOWLObjectProperty(IRI.create("http://example.org/part_of")) - val expression = factory.getOWLObjectIntersectionOf(muscle, factory.getOWLObjectSomeValuesFrom(part_of, head)) - val rdfsSubClassOf = factory.getOWLObjectProperty(OWLRDFVocabulary.RDFS_SUBCLASS_OF.getIRI) - val rdfType = factory.getOWLObjectProperty(OWLRDFVocabulary.RDF_TYPE.getIRI) - val query = select_distinct('phenotype) from "http://kb.phenoscape.org/" where ( - bgp( - t('eq, rdfsSubClassOf*, 'absence), - t('phenotype, rdfType, 'eq)), - service("http://owlery.phenoscape.org/sparql", - bgp( - t('eq, rdfsSubClassOf, "part_of some blah" ^^ omn), - t('eq, rdfsSubClassOf, expression.asOMN)))) order_by 'phenotype - println(query) - } - - @Test - def constructQuery(): Unit = { - val head = factory.getOWLClass(IRI.create("http://example.org/head")) - val muscle = factory.getOWLClass(IRI.create("http://example.org/muscle")) - val part_of = factory.getOWLObjectProperty(IRI.create("http://example.org/part_of")) - val expression = factory.getOWLObjectIntersectionOf(muscle, factory.getOWLObjectSomeValuesFrom(part_of, head)) - val rdfsSubClassOf = factory.getOWLObjectProperty(OWLRDFVocabulary.RDFS_SUBCLASS_OF.getIRI) - val rdfType = factory.getOWLObjectProperty(OWLRDFVocabulary.RDF_TYPE.getIRI) - val query = construct(t('phenotype, rdfType, 'eq)) from "http://kb.phenoscape.org/" where ( - bgp( - t('eq, rdfsSubClassOf*, 'absence), - t('phenotype, rdfType, 'eq), - t('foo, 'pred, 'bar)), - service("http://owlery.phenoscape.org/sparql", - bgp( - t('eq, rdfsSubClassOf, "part_of some blah" ^^ omn), - t('blah, rdfsSubClassOf / rdfType, 'blah), - t('blah, rdfsSubClassOf / (rdfType *), 'blah), - t('blah, rdfsSubClassOf | (rdfType*) / part_of, 'blah), - t('blah, rdfsSubClassOf ?, 'blah), - t('blah, rdfsSubClassOf +, 'blah), - t('foo, 'pred, 'bar), - t('eq, rdfsSubClassOf, expression.asOMN)), - filter('eq in (owlEntityToNode(rdfType) :: owlEntityToNode(rdfsSubClassOf) :: Nil)))) order_by 'phenotype - println(query) - } - - @Test - def testManchesterSyntaxRenderer(): Unit = { - - val head = factory.getOWLClass(IRI.create("http://example.org/head")) - val muscle = factory.getOWLClass(IRI.create("http://example.org/muscle")) - val part_of = factory.getOWLObjectProperty(IRI.create("http://example.org/part_of")) - val expression = factory.getOWLObjectIntersectionOf(muscle, factory.getOWLObjectSomeValuesFrom(part_of, head)) - Assert.assertEquals("\" and ( some )\"^^http://purl.org/phenoscape/owlet/syntax#omn", - expression.asOMN.toString) - } - -} diff --git a/src/test/scala/org/phenoscape/owlet/TestSPARQLQuery.scala b/src/test/scala/org/phenoscape/owlet/TestSPARQLQuery.scala index 79aa74f..664fa72 100644 --- a/src/test/scala/org/phenoscape/owlet/TestSPARQLQuery.scala +++ b/src/test/scala/org/phenoscape/owlet/TestSPARQLQuery.scala @@ -1,188 +1,83 @@ package org.phenoscape.owlet -import scala.collection.JavaConverters._ - -import org.apache.jena.query.QueryExecutionFactory -import org.apache.jena.query.QueryFactory +import org.apache.jena.query.{QueryExecutionFactory, QueryFactory} import org.apache.jena.rdf.model.ModelFactory -import org.junit.AfterClass -import org.junit.Assert -import org.junit.BeforeClass -import org.junit.Test import org.semanticweb.elk.owlapi.ElkReasonerFactory import org.semanticweb.owlapi.apibinding.OWLManager import org.semanticweb.owlapi.reasoner.InferenceType -import org.semanticweb.owlapi.reasoner.OWLReasoner - -object TestSPARQLQuery { - - var reasoner: OWLReasoner = null - - @BeforeClass - def setupReasoner(): Unit = { - val manager = OWLManager.createOWLOntologyManager() - val vsaoStream = this.getClass.getClassLoader.getResourceAsStream("vsao.owl") - val vsao = manager.loadOntologyFromOntologyDocument(vsaoStream) - vsaoStream.close() - reasoner = new ElkReasonerFactory().createReasoner(vsao) - reasoner.precomputeInferences(InferenceType.CLASS_HIERARCHY) - } - - @AfterClass - def disposeReasoner(): Unit = { - reasoner.dispose() - } - -} +import utest._ -class TestSPARQLQuery { +import scala.jdk.CollectionConverters._ +import scala.util.Using - @Test - def testSPARQLQueryUsingFilter(): Unit = { - val rdfStream = this.getClass.getClassLoader.getResourceAsStream("vsao.owl") - val vsaoRDF = ModelFactory.createDefaultModel() - vsaoRDF.read(rdfStream, null) - rdfStream.close() - val queryText = """ - PREFIX rdfs: - PREFIX ow: - PREFIX axial_skeleton: - PREFIX definition: - PREFIX part_of: - SELECT DISTINCT ?structure ?label ?definition - WHERE - { - ?structure rdfs:label ?label . - ?structure definition: ?definition . - ?structure rdfs:subClassOf "part_of: some axial_skeleton:"^^ow:omn . - } - """ - val owlet = new Owlet(TestSPARQLQuery.reasoner) - val query = QueryFactory.create(queryText) - val unexpandedResults = QueryExecutionFactory.create(query, vsaoRDF).execSelect() - Assert.assertFalse("Shouldn't get any results before expansion", unexpandedResults.hasNext) - val expandedQuery = owlet.expandQuery(query, false) - val results = QueryExecutionFactory.create(expandedQuery, vsaoRDF).execSelect() - Assert.assertEquals("Should get seven results", 7, results.asScala.length) - } +object TestSPARQLQuery extends TestSuite { - @Test - def testSPARQLQueryUsingValues(): Unit = { - val rdfStream = this.getClass.getClassLoader.getResourceAsStream("vsao.owl") - val vsaoRDF = ModelFactory.createDefaultModel() - vsaoRDF.read(rdfStream, null) - rdfStream.close() - val queryText = """ - PREFIX rdfs: - PREFIX ow: - PREFIX axial_skeleton: - PREFIX definition: - PREFIX part_of: - SELECT DISTINCT ?structure ?label ?definition - WHERE - { - ?structure rdfs:label ?label . - ?structure definition: ?definition . - ?structure rdfs:subClassOf "part_of: some axial_skeleton:"^^ow:omn . - } - """ - val owlet = new Owlet(TestSPARQLQuery.reasoner) - val query = QueryFactory.create(queryText) - val unexpandedResults = QueryExecutionFactory.create(query, vsaoRDF).execSelect() - Assert.assertFalse("Shouldn't get any results before expansion", unexpandedResults.hasNext) - val expandedQuery = owlet.expandQuery(query, true) - val results = QueryExecutionFactory.create(expandedQuery, vsaoRDF).execSelect() - Assert.assertEquals("Should get seven results", 7, results.asScala.length) + private val manager = OWLManager.createOWLOntologyManager() + private val vsao = Using.resource(this.getClass.getClassLoader.getResourceAsStream("vsao.owl")) { vsaoStream => + manager.loadOntologyFromOntologyDocument(vsaoStream) } - - //@Test - def testSPARQLQueryUsingOwletGraph(): Unit = { - val owlet = new Owlet(TestSPARQLQuery.reasoner) - val basicQuery = """ - PREFIX rdfs: - PREFIX ow: - PREFIX axial_skeleton: - PREFIX definition: - PREFIX part_of: - SELECT DISTINCT ?structure - WHERE - { - ?structure rdfs:subClassOf "part_of: some axial_skeleton:"^^ow:omn . - } - """ - Assert.assertEquals("Should get nine results", 9, owlet.performSPARQLQuery(QueryFactory.create(basicQuery)).asScala.length) - - val queryWithValues = """ - PREFIX rdfs: - PREFIX ow: - PREFIX axial_skeleton: - PREFIX definition: - PREFIX part_of: - SELECT DISTINCT ?structure - WHERE - { - VALUES ?structure { } - ?structure rdfs:subClassOf "part_of: some axial_skeleton:"^^ow:omn . - } - """ - Assert.assertEquals("Should get one result", 1, owlet.performSPARQLQuery(QueryFactory.create(queryWithValues)).asScala.length) - - val queryWithStar = """ - PREFIX rdfs: - PREFIX ow: - PREFIX axial_skeleton: - PREFIX definition: - PREFIX part_of: - SELECT DISTINCT ?structure - WHERE - { - ?structure rdfs:subClassOf* "part_of: some axial_skeleton:"^^ow:omn . - } - """ - Assert.assertEquals("Should get ten results (query engine includes expression as a result)", 10, owlet.performSPARQLQuery(QueryFactory.create(queryWithStar)).asScala.length) - - val queryWithPlus = """ - PREFIX rdfs: - PREFIX ow: - PREFIX axial_skeleton: - PREFIX definition: - PREFIX part_of: - SELECT DISTINCT ?structure - WHERE - { - ?structure rdfs:subClassOf+ "part_of: some axial_skeleton:"^^ow:omn . - } - """ - Assert.assertEquals("Should get nine results", 9, owlet.performSPARQLQuery(QueryFactory.create(queryWithPlus)).asScala.length) - - val queryWithQuestionMark = """ - PREFIX rdfs: - PREFIX ow: - PREFIX axial_skeleton: - PREFIX definition: - PREFIX part_of: - SELECT DISTINCT ?structure - WHERE - { - ?structure rdfs:subClassOf? "part_of: some axial_skeleton:"^^ow:omn . - } - """ - Assert.assertEquals("Should get ten results (query engine includes expression as a result)", 10, owlet.performSPARQLQuery(QueryFactory.create(queryWithQuestionMark)).asScala.length) - - val queryWithAlternative = """ - PREFIX rdfs: - PREFIX owl: - PREFIX ow: - PREFIX skeletal_element: - PREFIX bone_tissue: - PREFIX has_part: - SELECT DISTINCT ?structure - WHERE - { - ?structure rdfs:subClassOf|owl:equivalentClass "skeletal_element: and (has_part: some bone_tissue:)"^^ow:omn . - } - """ - Assert.assertEquals("Should get nineteen results", 19, owlet.performSPARQLQuery(QueryFactory.create(queryWithAlternative)).asScala.length) + private val reasoner = new ElkReasonerFactory().createReasoner(vsao) + reasoner.precomputeInferences(InferenceType.CLASS_HIERARCHY) + + override def utestAfterAll(): Unit = reasoner.dispose() + + val tests: Tests = Tests { + test("Test SPARQL query using filter") - { + val vsaoRDF = Using.resource(this.getClass.getClassLoader.getResourceAsStream("vsao.owl")) { stream => + ModelFactory.createDefaultModel().read(stream, null) + } + val queryText = + """ + PREFIX rdfs: + PREFIX ow: + PREFIX axial_skeleton: + PREFIX definition: + PREFIX part_of: + SELECT DISTINCT ?structure ?label ?definition + WHERE + { + ?structure rdfs:label ?label . + ?structure definition: ?definition . + ?structure rdfs:subClassOf "part_of: some axial_skeleton:"^^ow:omn . + } + """ + val owlet = new Owlet(TestSPARQLQuery.reasoner) + val query = QueryFactory.create(queryText) + val unexpandedResults = QueryExecutionFactory.create(query, vsaoRDF).execSelect() + //Shouldn't get any results before expansion + assert(!unexpandedResults.hasNext) + val expandedQuery = owlet.expandQuery(query, false) + val results = QueryExecutionFactory.create(expandedQuery, vsaoRDF).execSelect() + assert(7 == results.asScala.length) + } + test("Test SPARQL query using values") - { + val vsaoRDF = Using.resource(this.getClass.getClassLoader.getResourceAsStream("vsao.owl")) { stream => + ModelFactory.createDefaultModel().read(stream, null) + } + val queryText = + """ + PREFIX rdfs: + PREFIX ow: + PREFIX axial_skeleton: + PREFIX definition: + PREFIX part_of: + SELECT DISTINCT ?structure ?label ?definition + WHERE + { + ?structure rdfs:label ?label . + ?structure definition: ?definition . + ?structure rdfs:subClassOf "part_of: some axial_skeleton:"^^ow:omn . + } + """ + val owlet = new Owlet(TestSPARQLQuery.reasoner) + val query = QueryFactory.create(queryText) + val unexpandedResults = QueryExecutionFactory.create(query, vsaoRDF).execSelect() + // Shouldn't get any results before expansion + assert(!unexpandedResults.hasNext) + val expandedQuery = owlet.expandQuery(query, true) + val results = QueryExecutionFactory.create(expandedQuery, vsaoRDF).execSelect() + assert(7 == results.asScala.length) + } } }