Skip to content

Commit

Permalink
hierarchically ordered Sequence of base classes (#1700)
Browse files Browse the repository at this point in the history
* feature (orderedBaseClasses) all base classes of a resource class should be stored as a hierarchically ordered Seq

* feature (orderedBaseClasses) prepend the class Iri of the resource to the sequence of base classes

* refactor (orderedBaseClasses) comments updated.

* refactor (orderedBaseClasses) more comments.

* fix (orderedBaseClasses) failing test fixed

* fix (orderedBaseClasses) the failing test

* style(OntologyResponderV2): Remove redundant conversion, add missing type annotation.

* style(gravsearch): Clarify comment.

Co-authored-by: Benjamin Geer <benjaminlewis.geer@unibas.ch>
  • Loading branch information
SepidehAlassi and Benjamin Geer committed Sep 8, 2020
1 parent a3b1665 commit a9e72d8
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 60 deletions.
Expand Up @@ -27,17 +27,19 @@ import org.knora.webapi.messages.SmartIri
*/
object OntologyUtil {
/**
* Recursively walks up an entity hierarchy read from the triplestore, collecting the IRIs of all base entities.
* Recursively walks up an entity hierarchy read from the triplestore, collecting the IRIs of all base entities in
* an ordered sequence.
*
* @param iri the IRI of an entity.
* @param directRelations a map of entities to their direct base entities.
* @return all the base entities of the specified entity.
* @return all the base entities of the specified entity hierarchically ordered.
*/
def getAllBaseDefs(iri: SmartIri, directRelations: Map[SmartIri, Set[SmartIri]]): Set[SmartIri] = {
def getAllBaseDefsRec(initialIri: SmartIri, currentIri: SmartIri): Set[SmartIri] = {
def getAllBaseDefs(iri: SmartIri, directRelations: Map[SmartIri, Set[SmartIri]]): Seq[SmartIri] = {
def getAllBaseDefsRec(initialIri: SmartIri, currentIri: SmartIri): Seq[SmartIri] = {
directRelations.get(currentIri) match {
case Some(baseDefs) =>
baseDefs ++ baseDefs.flatMap {
val baseDefsSequence = baseDefs.toSeq
baseDefsSequence ++ baseDefsSequence.flatMap {
baseDef =>
if (baseDef == initialIri) {
throw InconsistentTriplestoreDataException(s"Entity $initialIri has an inheritance cycle with entity $baseDef")
Expand All @@ -46,7 +48,7 @@ object OntologyUtil {
}
}

case None => Set.empty[SmartIri]
case None => Seq.empty[SmartIri]
}
}

Expand Down
Expand Up @@ -879,33 +879,32 @@ class InferringGravsearchTypeInspector(nextInspector: Option[GravsearchTypeInspe
* @return the IRI of a common base class.
*/
def findCommonBaseResourceClass(typesToBeChecked: Set[GravsearchEntityTypeInfo]): SmartIri = {
val baseClassesOfFirstType: Set[SmartIri] = entityInfo.classInfoMap.get(iriOfGravsearchTypeInfo(typesToBeChecked.head)) match {
val baseClassesOfFirstType: Seq[SmartIri] = entityInfo.classInfoMap.get(iriOfGravsearchTypeInfo(typesToBeChecked.head)) match {
case Some(classDef: ReadClassInfoV2) =>
classDef.allBaseClasses
case _ => Set.empty[SmartIri]
case _ => Seq.empty[SmartIri]
}

if (baseClassesOfFirstType.nonEmpty) {
val commonBaseClasses: Set[SmartIri] = typesToBeChecked.tail.foldLeft(baseClassesOfFirstType) {
val commonBaseClasses: Seq[SmartIri] = typesToBeChecked.tail.foldLeft(baseClassesOfFirstType) {
(acc, aType) =>
// get class info of the type Iri
val baseClassesOfType: Set[SmartIri] = entityInfo.classInfoMap.get(iriOfGravsearchTypeInfo(aType)) match {
val baseClassesOfType: Seq[SmartIri] = entityInfo.classInfoMap.get(iriOfGravsearchTypeInfo(aType)) match {
case Some(classDef: ReadClassInfoV2) =>
classDef.allBaseClasses
case _ => Set.empty[SmartIri]
case _ => Seq.empty[SmartIri]
}

// find the common base classes
baseClassesOfType.intersect(acc)
}

if (commonBaseClasses.nonEmpty) {
// return any available base class. TODO: the most specific one should be returned.
// returns the most specific common base class.
commonBaseClasses.head
} else {
InferenceRuleUtil.getResourceTypeIriForSchema(querySchema)
}

} else {
InferenceRuleUtil.getResourceTypeIriForSchema(querySchema)
}
Expand Down Expand Up @@ -973,7 +972,8 @@ class InferringGravsearchTypeInspector(nextInspector: Option[GravsearchTypeInspe
allTypes.exists(
aType =>
entityInfo.classInfoMap.get(iriOfGravsearchTypeInfo(aType)) match {
case Some(classDef: ReadClassInfoV2) => classDef.allBaseClasses.contains(currTypeIri)
case Some(classDef: ReadClassInfoV2) =>
classDef.allBaseClasses.contains(currTypeIri)
case _ => false
}
)
Expand Down
Expand Up @@ -692,7 +692,7 @@ object KnoraBaseToApiV2SimpleTransformationRules extends OntologyTransformationR
}.toMap + rdfType,
ontologySchema = ApiV2Simple
),
allBaseClasses = Set(datatypeIri.toSmartIri)
allBaseClasses = Seq(datatypeIri.toSmartIri)
)
}
}
Expand Up @@ -2073,7 +2073,7 @@ sealed trait ReadEntityInfoV2 {
* Represents an OWL class definition as returned in an API response.
*
* @param entityInfoContent a [[ReadClassInfoV2]] providing information about the class.
* @param allBaseClasses a set of the IRIs of all the base classes of the class.
* @param allBaseClasses a seq of the IRIs of all the base classes of the class.
* @param isResourceClass `true` if this is a subclass of `knora-base:Resource`.
* @param isStandoffClass `true` if this is a subclass of `knora-base:StandoffTag`.
* @param isValueClass `true` if the class is a Knora value class.
Expand All @@ -2088,7 +2088,7 @@ sealed trait ReadEntityInfoV2 {
* @param fileValueProperties a [[Set]] of IRIs of properties in `allCardinalities` that point to `FileValue` objects.
*/
case class ReadClassInfoV2(entityInfoContent: ClassInfoContentV2,
allBaseClasses: Set[SmartIri],
allBaseClasses: Seq[SmartIri],
isResourceClass: Boolean = false,
isStandoffClass: Boolean = false,
isValueClass: Boolean = false,
Expand Down Expand Up @@ -2153,7 +2153,7 @@ case class ReadClassInfoV2(entityInfoContent: ClassInfoContentV2,

// Remove base classes that don't exist in the target schema.

val allBaseClassesFilteredForTargetSchema = allBaseClasses.diff(transformationRules.internalClassesToRemove)
val allBaseClassesFilteredForTargetSchema = allBaseClasses.diff(transformationRules.internalClassesToRemove.toSeq)

// Convert all IRIs to the target schema.

Expand Down

0 comments on commit a9e72d8

Please sign in to comment.