From c322879fcbcad35d31e65da5597dd935d797b049 Mon Sep 17 00:00:00 2001 From: Balduin Landolt <33053745+BalduinLandolt@users.noreply.github.com> Date: Sun, 22 Dec 2024 17:36:43 +0100 Subject: [PATCH 1/6] make standoff entities in cache private and expose through methods --- .../responders/v2/OntologyResponderV2.scala | 20 +++++++++---------- .../repo/model/OntologyCacheData.scala | 8 +++++++- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/webapi/src/main/scala/org/knora/webapi/responders/v2/OntologyResponderV2.scala b/webapi/src/main/scala/org/knora/webapi/responders/v2/OntologyResponderV2.scala index f0917addd3..650b949b5f 100644 --- a/webapi/src/main/scala/org/knora/webapi/responders/v2/OntologyResponderV2.scala +++ b/webapi/src/main/scala/org/knora/webapi/responders/v2/OntologyResponderV2.scala @@ -198,13 +198,12 @@ final case class OntologyResponderV2( } }.toMap - propertyDefsAvailable = propertyOntologies.flatMap { ontology => - ontology.properties.filter { case (propertyIri, _) => - standoffPropertyIris.contains(propertyIri) && cacheData.standoffProperties.contains( - propertyIri, - ) - } - }.toMap + propertyDefsAvailable = + propertyOntologies.flatMap { ontology => + ontology.properties.filter { case (propertyIri, _) => + standoffPropertyIris.contains(propertyIri) && cacheData.containsStandoffProperty(propertyIri) + } + }.toMap missingClassDefs = classIrisForCache -- classDefsAvailable.keySet missingPropertyDefs = propertyIrisForCache -- propertyDefsAvailable.keySet @@ -248,10 +247,9 @@ final case class OntologyResponderV2( * @return a [[StandoffAllPropertyEntitiesGetResponseV2]]. */ private def getAllStandoffPropertyEntitiesV2: Task[StandoffAllPropertyEntitiesGetResponseV2] = - ontologyCache.getCacheData.map { data => - val ontologies: Iterable[ReadOntologyV2] = data.ontologies.values - ontologies.flatMap(_.properties.view.filterKeys(data.standoffProperties)).toMap - }.map(StandoffAllPropertyEntitiesGetResponseV2.apply) + ontologyCache.getCacheData + .map(_.getAllStandoffPropertyEntities) + .map(StandoffAllPropertyEntitiesGetResponseV2.apply) /** * Checks whether a certain Knora resource or value class is a subclass of another class. diff --git a/webapi/src/main/scala/org/knora/webapi/slice/ontology/repo/model/OntologyCacheData.scala b/webapi/src/main/scala/org/knora/webapi/slice/ontology/repo/model/OntologyCacheData.scala index 54c24bab7d..ce81aafd4c 100644 --- a/webapi/src/main/scala/org/knora/webapi/slice/ontology/repo/model/OntologyCacheData.scala +++ b/webapi/src/main/scala/org/knora/webapi/slice/ontology/repo/model/OntologyCacheData.scala @@ -7,6 +7,7 @@ package org.knora.webapi.slice.ontology.repo.model import org.knora.webapi.messages.SmartIri import org.knora.webapi.messages.v2.responder.ontologymessages.PropertyInfoContentV2 import org.knora.webapi.messages.v2.responder.ontologymessages.ReadOntologyV2 +import org.knora.webapi.messages.v2.responder.ontologymessages.ReadPropertyInfoV2 /** * The in-memory cache of ontologies. @@ -30,13 +31,18 @@ case class OntologyCacheData( classDefinedInOntology: Map[SmartIri, SmartIri], propertyDefinedInOntology: Map[SmartIri, SmartIri], entityDefinedInOntology: Map[SmartIri, SmartIri], - standoffProperties: Set[SmartIri], + private val standoffProperties: Set[SmartIri], ) { lazy val allPropertyDefs: Map[SmartIri, PropertyInfoContentV2] = ontologies.values .flatMap(_.properties.map { case (propertyIri, readPropertyInfo) => propertyIri -> readPropertyInfo.entityInfoContent }) .toMap + + def containsStandoffProperty(propertyIri: SmartIri): Boolean = standoffProperties.contains(propertyIri) + + def getAllStandoffPropertyEntities: Map[SmartIri, ReadPropertyInfoV2] = + ontologies.values.flatMap(_.properties.view.filterKeys(standoffProperties)).toMap } object OntologyCacheData { val Empty = OntologyCacheData( From 287600d2459157942bd4e0c701f4627f6c9d82d8 Mon Sep 17 00:00:00 2001 From: Balduin Landolt <33053745+BalduinLandolt@users.noreply.github.com> Date: Sun, 22 Dec 2024 17:52:01 +0100 Subject: [PATCH 2/6] make entity definition map a lookup function --- .../prequery/InferenceOptimizationService.scala | 10 ++++------ .../slice/ontology/repo/model/OntologyCacheData.scala | 4 +++- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/webapi/src/main/scala/org/knora/webapi/messages/util/search/gravsearch/prequery/InferenceOptimizationService.scala b/webapi/src/main/scala/org/knora/webapi/messages/util/search/gravsearch/prequery/InferenceOptimizationService.scala index 194c6df2a2..d0c211fc65 100644 --- a/webapi/src/main/scala/org/knora/webapi/messages/util/search/gravsearch/prequery/InferenceOptimizationService.scala +++ b/webapi/src/main/scala/org/knora/webapi/messages/util/search/gravsearch/prequery/InferenceOptimizationService.scala @@ -38,14 +38,14 @@ final case class InferenceOptimizationService( * if so, all ontologies defined by the project to which the data belongs, will be included in the results. * * @param entity an RDF entity. - * @param map a map of entity IRIs to the IRIs of the ontology where they are defined. + * @param lookup a function optionally defining the ontology in an entity is defined. * @return a sequence of ontology IRIs which relate to the input RDF entity. */ - private def resolveEntity(entity: Entity, map: Map[SmartIri, SmartIri]): Task[Seq[SmartIri]] = + private def resolveEntity(entity: Entity, lookup: SmartIri => Option[SmartIri]): Task[Seq[SmartIri]] = entity match { case IriRef(iri, _) => val internal = iri.toOntologySchema(InternalSchema) - val maybeOntoIri = map.get(internal) + val maybeOntoIri = lookup(internal) maybeOntoIri match { // if the map contains an ontology IRI corresponding to the entity IRI, then this can be returned case Some(iri) => ZIO.succeed(Seq(iri)) @@ -105,10 +105,8 @@ final case class InferenceOptimizationService( for { ontoCache <- ontologyCache.getCacheData - // from the cache, get the map from entity to the ontology where the entity is defined - entityMap = ontoCache.entityDefinedInOntology // resolve all entities from the WHERE clause to the ontology where they are defined - relevantOntologies <- ZIO.foreach(entities)(resolveEntity(_, entityMap)) + relevantOntologies <- ZIO.foreach(entities)(resolveEntity(_, ontoCache.entityDefinedInOntology)) relevantOntologiesSet = relevantOntologies.flatten.toSet relevantOntologiesMaybe = relevantOntologiesSet match { diff --git a/webapi/src/main/scala/org/knora/webapi/slice/ontology/repo/model/OntologyCacheData.scala b/webapi/src/main/scala/org/knora/webapi/slice/ontology/repo/model/OntologyCacheData.scala index ce81aafd4c..c6e152c35e 100644 --- a/webapi/src/main/scala/org/knora/webapi/slice/ontology/repo/model/OntologyCacheData.scala +++ b/webapi/src/main/scala/org/knora/webapi/slice/ontology/repo/model/OntologyCacheData.scala @@ -30,7 +30,7 @@ case class OntologyCacheData( superPropertyOfRelations: Map[SmartIri, Set[SmartIri]], classDefinedInOntology: Map[SmartIri, SmartIri], propertyDefinedInOntology: Map[SmartIri, SmartIri], - entityDefinedInOntology: Map[SmartIri, SmartIri], + private val entityDefinedInOntology: Map[SmartIri, SmartIri], private val standoffProperties: Set[SmartIri], ) { lazy val allPropertyDefs: Map[SmartIri, PropertyInfoContentV2] = ontologies.values @@ -43,6 +43,8 @@ case class OntologyCacheData( def getAllStandoffPropertyEntities: Map[SmartIri, ReadPropertyInfoV2] = ontologies.values.flatMap(_.properties.view.filterKeys(standoffProperties)).toMap + + def entityDefinedInOntology(propertyIri: SmartIri): Option[SmartIri] = entityDefinedInOntology.get(propertyIri) } object OntologyCacheData { val Empty = OntologyCacheData( From 70e3ea9209245e963876670fa9f8590874e0777e Mon Sep 17 00:00:00 2001 From: Balduin Landolt <33053745+BalduinLandolt@users.noreply.github.com> Date: Sun, 22 Dec 2024 18:05:22 +0100 Subject: [PATCH 3/6] make class and property definition lookup functions --- .../gravsearch/transformers/OntologyInferencer.scala | 4 ++-- .../slice/ontology/repo/model/OntologyCacheData.scala | 8 +++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/webapi/src/main/scala/org/knora/webapi/messages/util/search/gravsearch/transformers/OntologyInferencer.scala b/webapi/src/main/scala/org/knora/webapi/messages/util/search/gravsearch/transformers/OntologyInferencer.scala index 181f037734..0b69c06acf 100644 --- a/webapi/src/main/scala/org/knora/webapi/messages/util/search/gravsearch/transformers/OntologyInferencer.scala +++ b/webapi/src/main/scala/org/knora/webapi/messages/util/search/gravsearch/transformers/OntologyInferencer.scala @@ -43,7 +43,7 @@ final case class OntologyInferencer( case None => knownSubClasses case Some(relevantOntologyIris) => // filter the known subclasses against the relevant ontologies - knownSubClasses.filter(cache.classDefinedInOntology.get(_).exists(relevantOntologyIris.contains(_))) + knownSubClasses.filter(cache.classDefinedInOntology(_).exists(relevantOntologyIris.contains(_))) } // Searches for a `?v a `, or if multiple subclasses are present, then @@ -68,7 +68,7 @@ final case class OntologyInferencer( // if provided, limit the child properties to those that belong to relevant ontologies val subProps = limitInferenceToOntologies match { case Some(ontologyIris) => - knownSubProps.filter(cache.propertyDefinedInOntology.get(_).exists(ontologyIris.contains(_))) + knownSubProps.filter(cache.propertyDefinedInOntology(_).exists(ontologyIris.contains(_))) case None => knownSubProps } // Searches for a `?v ?b`, or if multiple propertyIRIs are present, then diff --git a/webapi/src/main/scala/org/knora/webapi/slice/ontology/repo/model/OntologyCacheData.scala b/webapi/src/main/scala/org/knora/webapi/slice/ontology/repo/model/OntologyCacheData.scala index c6e152c35e..5257e47ea4 100644 --- a/webapi/src/main/scala/org/knora/webapi/slice/ontology/repo/model/OntologyCacheData.scala +++ b/webapi/src/main/scala/org/knora/webapi/slice/ontology/repo/model/OntologyCacheData.scala @@ -28,8 +28,8 @@ case class OntologyCacheData( classToSubclassLookup: Map[SmartIri, Set[SmartIri]], subPropertyOfRelations: Map[SmartIri, Set[SmartIri]], superPropertyOfRelations: Map[SmartIri, Set[SmartIri]], - classDefinedInOntology: Map[SmartIri, SmartIri], - propertyDefinedInOntology: Map[SmartIri, SmartIri], + private val classDefinedInOntology: Map[SmartIri, SmartIri], + private val propertyDefinedInOntology: Map[SmartIri, SmartIri], private val entityDefinedInOntology: Map[SmartIri, SmartIri], private val standoffProperties: Set[SmartIri], ) { @@ -44,7 +44,9 @@ case class OntologyCacheData( def getAllStandoffPropertyEntities: Map[SmartIri, ReadPropertyInfoV2] = ontologies.values.flatMap(_.properties.view.filterKeys(standoffProperties)).toMap - def entityDefinedInOntology(propertyIri: SmartIri): Option[SmartIri] = entityDefinedInOntology.get(propertyIri) + def entityDefinedInOntology(propertyIri: SmartIri): Option[SmartIri] = entityDefinedInOntology.get(propertyIri) + def classDefinedInOntology(classIri: SmartIri): Option[SmartIri] = classDefinedInOntology.get(classIri) + def propertyDefinedInOntology(propertyIri: SmartIri): Option[SmartIri] = propertyDefinedInOntology.get(propertyIri) } object OntologyCacheData { val Empty = OntologyCacheData( From 3e452b3a998e9f4d169c99bc69b479fc72135ab8 Mon Sep 17 00:00:00 2001 From: Balduin Landolt <33053745+BalduinLandolt@users.noreply.github.com> Date: Sun, 22 Dec 2024 18:29:10 +0100 Subject: [PATCH 4/6] move more access into functions --- .../transformers/OntologyInferencer.scala | 2 +- .../responders/v2/OntologyResponderV2.scala | 9 ++++---- .../v2/ontology/OntologyHelpers.scala | 22 +++++++++---------- .../repo/model/OntologyCacheData.scala | 7 ++++-- .../ontology/repo/service/OntologyCache.scala | 6 ++--- 5 files changed, 25 insertions(+), 21 deletions(-) diff --git a/webapi/src/main/scala/org/knora/webapi/messages/util/search/gravsearch/transformers/OntologyInferencer.scala b/webapi/src/main/scala/org/knora/webapi/messages/util/search/gravsearch/transformers/OntologyInferencer.scala index 0b69c06acf..196b37c295 100644 --- a/webapi/src/main/scala/org/knora/webapi/messages/util/search/gravsearch/transformers/OntologyInferencer.scala +++ b/webapi/src/main/scala/org/knora/webapi/messages/util/search/gravsearch/transformers/OntologyInferencer.scala @@ -63,7 +63,7 @@ final case class OntologyInferencer( queryVariableSuffix: Option[String], ): Seq[QueryPattern] = { // look up subproperties from ontology cache - val knownSubProps = cache.superPropertyOfRelations.get(predIri).getOrElse(Set(predIri)).toSeq + val knownSubProps = cache.getSubPropertiesOf(predIri).getOrElse(Set(predIri)).toSeq // if provided, limit the child properties to those that belong to relevant ontologies val subProps = limitInferenceToOntologies match { diff --git a/webapi/src/main/scala/org/knora/webapi/responders/v2/OntologyResponderV2.scala b/webapi/src/main/scala/org/knora/webapi/responders/v2/OntologyResponderV2.scala index 650b949b5f..459a860b56 100644 --- a/webapi/src/main/scala/org/knora/webapi/responders/v2/OntologyResponderV2.scala +++ b/webapi/src/main/scala/org/knora/webapi/responders/v2/OntologyResponderV2.scala @@ -1974,10 +1974,11 @@ final case class OntologyResponderV2( // Check for rdfs:subPropertyOf cycles. allKnoraSuperPropertyIrisWithoutSelf: Set[SmartIri] = knoraSuperProperties.flatMap { superPropertyIri => - cacheData.subPropertyOfRelations.getOrElse( - superPropertyIri, - Set.empty[SmartIri], - ) + cacheData + .getSuperPropertiesOf(superPropertyIri) + .getOrElse( + Set.empty[SmartIri], + ) } _ <- ZIO.when(allKnoraSuperPropertyIrisWithoutSelf.contains(internalPropertyIri)) { diff --git a/webapi/src/main/scala/org/knora/webapi/responders/v2/ontology/OntologyHelpers.scala b/webapi/src/main/scala/org/knora/webapi/responders/v2/ontology/OntologyHelpers.scala index b113491121..20594995d5 100644 --- a/webapi/src/main/scala/org/knora/webapi/responders/v2/ontology/OntologyHelpers.scala +++ b/webapi/src/main/scala/org/knora/webapi/responders/v2/ontology/OntologyHelpers.scala @@ -176,7 +176,7 @@ object OntologyHelpers { directClassCardinalities: Map[SmartIri, Map[SmartIri, KnoraCardinalityInfo]], classCardinalitiesWithInheritance: Map[SmartIri, Map[SmartIri, KnoraCardinalityInfo]], allSubClassOfRelations: Map[SmartIri, Seq[SmartIri]], - allSubPropertyOfRelations: Map[SmartIri, Set[SmartIri]], + superPropertyLookup: SmartIri => Option[Set[SmartIri]], allPropertyDefs: Map[SmartIri, PropertyInfoContentV2], allKnoraResourceProps: Set[SmartIri], allLinkProps: Set[SmartIri], @@ -266,7 +266,7 @@ object OntologyHelpers { val maybePropertyAndSubproperty: Option[(SmartIri, SmartIri)] = OntologyHelpers.findPropertyAndSubproperty( propertyIris = allPropertyIrisForCardinalitiesInClass, - subPropertyOfRelations = allSubPropertyOfRelations, + superPropertyLookup = superPropertyLookup, ) maybePropertyAndSubproperty match { @@ -875,11 +875,11 @@ object OntologyHelpers { */ private def findPropertyAndSubproperty( propertyIris: Set[SmartIri], - subPropertyOfRelations: Map[SmartIri, Set[SmartIri]], + superPropertyLookup: SmartIri => Option[Set[SmartIri]], ): Option[(SmartIri, SmartIri)] = propertyIris.flatMap { propertyIri => val maybeBasePropertyIri: Option[SmartIri] = (propertyIris - propertyIri).find { otherPropertyIri => - subPropertyOfRelations.get(propertyIri).exists { (baseProperties: Set[SmartIri]) => + superPropertyLookup(propertyIri).exists { (baseProperties: Set[SmartIri]) => baseProperties.contains(otherPropertyIri) } } @@ -1038,7 +1038,7 @@ object OntologyHelpers { classIri = internalClassDef.classIri, thisClassCardinalities = classDefWithAddedLinkValueProps.directCardinalities, inheritableCardinalities = cardinalitiesAvailableToInherit, - allSubPropertyOfRelations = cacheData.subPropertyOfRelations, + superPropertyLookup = cacheData.getSuperPropertiesOf, errorSchema = ApiV2Complex, errorFun = { msg => throw BadRequestException(msg) }, ), @@ -1079,7 +1079,7 @@ object OntologyHelpers { _ <- findPropertyAndSubproperty( propertyIris = cardinalitiesForClassWithInheritance.keySet, - subPropertyOfRelations = cacheData.subPropertyOfRelations, + superPropertyLookup = cacheData.getSuperPropertiesOf, ) match { case Some((basePropertyIri, propertyIri)) => Validation.fail( @@ -1158,7 +1158,7 @@ object OntologyHelpers { classIri: SmartIri, thisClassCardinalities: Map[SmartIri, KnoraCardinalityInfo], inheritableCardinalities: Map[SmartIri, KnoraCardinalityInfo], - allSubPropertyOfRelations: Map[SmartIri, Set[SmartIri]], + superPropertyLookup: SmartIri => Option[Set[SmartIri]], errorSchema: OntologySchema, errorFun: String => Nothing, ): Map[SmartIri, KnoraCardinalityInfo] = { @@ -1169,7 +1169,7 @@ object OntologyHelpers { // If the class has a cardinality for a non-Knora property like rdfs:label (which can happen only // if it's a built-in class), we won't have any information about the base properties of that property. val basePropsOfThisClassProp: Set[SmartIri] = - allSubPropertyOfRelations.getOrElse(thisClassProp, Set.empty[SmartIri]) + superPropertyLookup(thisClassProp).getOrElse(Set.empty[SmartIri]) val overriddenBaseProps: Set[SmartIri] = inheritableCardinalities.foldLeft(Set.empty[SmartIri]) { case (acc, (baseClassProp, baseClassCardinality)) => @@ -1377,7 +1377,7 @@ object OntologyHelpers { def inheritCardinalitiesInLoadedClass( classIri: SmartIri, directSubClassOfRelations: Map[SmartIri, Set[SmartIri]], - allSubPropertyOfRelations: Map[SmartIri, Set[SmartIri]], + superPropertyLookup: SmartIri => Option[Set[SmartIri]], directClassCardinalities: Map[SmartIri, Map[SmartIri, KnoraCardinalityInfo]], ): Map[SmartIri, KnoraCardinalityInfo] = { // Recursively get properties that are available to inherit from base classes. If we have no information about @@ -1390,7 +1390,7 @@ object OntologyHelpers { acc ++ inheritCardinalitiesInLoadedClass( classIri = baseClass, directSubClassOfRelations = directSubClassOfRelations, - allSubPropertyOfRelations = allSubPropertyOfRelations, + superPropertyLookup = superPropertyLookup, directClassCardinalities = directClassCardinalities, ) } @@ -1405,7 +1405,7 @@ object OntologyHelpers { classIri = classIri, thisClassCardinalities = thisClassCardinalities, inheritableCardinalities = cardinalitiesAvailableToInherit, - allSubPropertyOfRelations = allSubPropertyOfRelations, + superPropertyLookup = superPropertyLookup, errorSchema = InternalSchema, (msg: String) => throw InconsistentRepositoryDataException(msg), ) diff --git a/webapi/src/main/scala/org/knora/webapi/slice/ontology/repo/model/OntologyCacheData.scala b/webapi/src/main/scala/org/knora/webapi/slice/ontology/repo/model/OntologyCacheData.scala index 5257e47ea4..94188e4b2e 100644 --- a/webapi/src/main/scala/org/knora/webapi/slice/ontology/repo/model/OntologyCacheData.scala +++ b/webapi/src/main/scala/org/knora/webapi/slice/ontology/repo/model/OntologyCacheData.scala @@ -26,8 +26,8 @@ case class OntologyCacheData( ontologies: Map[SmartIri, ReadOntologyV2], classToSuperClassLookup: Map[SmartIri, Seq[SmartIri]], classToSubclassLookup: Map[SmartIri, Set[SmartIri]], - subPropertyOfRelations: Map[SmartIri, Set[SmartIri]], - superPropertyOfRelations: Map[SmartIri, Set[SmartIri]], + private val subPropertyOfRelations: Map[SmartIri, Set[SmartIri]], + private val superPropertyOfRelations: Map[SmartIri, Set[SmartIri]], private val classDefinedInOntology: Map[SmartIri, SmartIri], private val propertyDefinedInOntology: Map[SmartIri, SmartIri], private val entityDefinedInOntology: Map[SmartIri, SmartIri], @@ -47,6 +47,9 @@ case class OntologyCacheData( def entityDefinedInOntology(propertyIri: SmartIri): Option[SmartIri] = entityDefinedInOntology.get(propertyIri) def classDefinedInOntology(classIri: SmartIri): Option[SmartIri] = classDefinedInOntology.get(classIri) def propertyDefinedInOntology(propertyIri: SmartIri): Option[SmartIri] = propertyDefinedInOntology.get(propertyIri) + + def getSubPropertiesOf(propertyIri: SmartIri): Option[Set[SmartIri]] = subPropertyOfRelations.get(propertyIri) + def getSuperPropertiesOf(propertyIri: SmartIri): Option[Set[SmartIri]] = superPropertyOfRelations.get(propertyIri) } object OntologyCacheData { val Empty = OntologyCacheData( diff --git a/webapi/src/main/scala/org/knora/webapi/slice/ontology/repo/service/OntologyCache.scala b/webapi/src/main/scala/org/knora/webapi/slice/ontology/repo/service/OntologyCache.scala index 68f1b7b2fd..25dcb63d2c 100644 --- a/webapi/src/main/scala/org/knora/webapi/slice/ontology/repo/service/OntologyCache.scala +++ b/webapi/src/main/scala/org/knora/webapi/slice/ontology/repo/service/OntologyCache.scala @@ -679,7 +679,7 @@ final case class OntologyCacheLive(triplestore: TriplestoreService, cacheDataRef OntologyHelpers.inheritCardinalitiesInLoadedClass( classIri = resourceClassIri, directSubClassOfRelations = directSubClassOfRelations, - allSubPropertyOfRelations = allSubPropertyOfRelations, + superPropertyLookup = allSubPropertyOfRelations.get, directClassCardinalities = directClassCardinalities, ) @@ -692,7 +692,7 @@ final case class OntologyCacheLive(triplestore: TriplestoreService, cacheDataRef directClassCardinalities = directClassCardinalities, classCardinalitiesWithInheritance = classCardinalitiesWithInheritance, allSubClassOfRelations = allSubClassOfRelations, - allSubPropertyOfRelations = allSubPropertyOfRelations, + superPropertyLookup = allSubPropertyOfRelations.get, allPropertyDefs = allPropertyDefs, allKnoraResourceProps = allKnoraResourceProps, allLinkProps = allLinkProps, @@ -914,7 +914,7 @@ final case class OntologyCacheLive(triplestore: TriplestoreService, cacheDataRef classIri = directSubClassIri, thisClassCardinalities = directSubClass.entityInfoContent.directCardinalities, inheritableCardinalities = inheritableCardinalities, - allSubPropertyOfRelations = cacheData.subPropertyOfRelations, + superPropertyLookup = cacheData.getSuperPropertiesOf, errorSchema = ApiV2Complex, errorFun = { (msg: String) => throw BadRequestException(msg) From 4b67814d5e20736e09f25c0895450ce26fc17bdc Mon Sep 17 00:00:00 2001 From: Balduin Landolt <33053745+BalduinLandolt@users.noreply.github.com> Date: Sun, 22 Dec 2024 18:37:25 +0100 Subject: [PATCH 5/6] move more access into methods --- .../transformers/OntologyInferencer.scala | 2 +- .../responders/v2/OntologyResponderV2.scala | 27 ++++++++++--------- .../v2/ontology/CardinalityHandler.scala | 10 ++----- .../repo/model/OntologyCacheData.scala | 7 +++-- .../ontology/repo/service/OntologyCache.scala | 6 ++--- 5 files changed, 26 insertions(+), 26 deletions(-) diff --git a/webapi/src/main/scala/org/knora/webapi/messages/util/search/gravsearch/transformers/OntologyInferencer.scala b/webapi/src/main/scala/org/knora/webapi/messages/util/search/gravsearch/transformers/OntologyInferencer.scala index 196b37c295..4fd346737f 100644 --- a/webapi/src/main/scala/org/knora/webapi/messages/util/search/gravsearch/transformers/OntologyInferencer.scala +++ b/webapi/src/main/scala/org/knora/webapi/messages/util/search/gravsearch/transformers/OntologyInferencer.scala @@ -36,7 +36,7 @@ final case class OntologyInferencer( } } yield { // look up subclasses from ontology cache - val knownSubClasses = cache.classToSubclassLookup.get(baseClassIri.iri).getOrElse(Set(baseClassIri.iri)).toSeq + val knownSubClasses = cache.getSubClassesOf(baseClassIri.iri).getOrElse(Set(baseClassIri.iri)).toSeq // if provided, limit the child classes to those that belong to relevant ontologies val subClasses = limitInferenceToOntologies match { diff --git a/webapi/src/main/scala/org/knora/webapi/responders/v2/OntologyResponderV2.scala b/webapi/src/main/scala/org/knora/webapi/responders/v2/OntologyResponderV2.scala index 459a860b56..9df03890b5 100644 --- a/webapi/src/main/scala/org/knora/webapi/responders/v2/OntologyResponderV2.scala +++ b/webapi/src/main/scala/org/knora/webapi/responders/v2/OntologyResponderV2.scala @@ -262,7 +262,7 @@ final case class OntologyResponderV2( for { cacheData <- ontologyCache.getCacheData isSubClass <- ZIO - .fromOption(cacheData.classToSuperClassLookup.get(subClassIri)) + .fromOption(cacheData.getSuperClassesOf(subClassIri)) .map(_.contains(superClassIri)) .orElseFail(BadRequestException(s"Class $subClassIri not found")) } yield CheckSubClassResponseV2(isSubClass) @@ -277,7 +277,7 @@ final case class OntologyResponderV2( for { cacheData <- ontologyCache.getCacheData subClasses <- - ZIO.foreach(cacheData.classToSubclassLookup(classIri).toVector.sorted) { subClassIri => + ZIO.foreach(cacheData.getSubClassesOf(classIri).get.toVector.sorted) { subClassIri => val labelValueMaybe = cacheData .ontologies(subClassIri.getOntologyFromEntity) .classes(subClassIri) @@ -784,8 +784,9 @@ final case class OntologyResponderV2( // Check for rdfs:subClassOf cycles. allBaseClassIrisWithoutSelf: Set[SmartIri] = internalClassDef.subClassOf.flatMap { baseClassIri => - cacheData.classToSuperClassLookup - .getOrElse(baseClassIri, Set.empty[SmartIri]) + cacheData + .getSuperClassesOf(baseClassIri) + .getOrElse(Set.empty[SmartIri]) .toSet } @@ -1145,10 +1146,11 @@ final case class OntologyResponderV2( // Check that the new cardinalities are valid, and add any inherited cardinalities. allBaseClassIrisWithoutInternal = newInternalClassDef.subClassOf.toSeq.flatMap { baseClassIri => - cacheData.classToSuperClassLookup.getOrElse( - baseClassIri, - Seq.empty[SmartIri], - ) + cacheData + .getSuperClassesOf(baseClassIri) + .getOrElse( + Seq.empty[SmartIri], + ) } allBaseClassIris = internalClassIri +: allBaseClassIrisWithoutInternal @@ -1318,10 +1320,11 @@ final case class OntologyResponderV2( // Check that the new cardinalities are valid, and don't add any inherited cardinalities. newInternalClassDef = oldClassInfo.copy(directCardinalities = newClassInfo.directCardinalities) allBaseClassIrisWithoutInternal = newInternalClassDef.subClassOf.toSeq.flatMap { baseClassIri => - cacheData.classToSuperClassLookup.getOrElse( - baseClassIri, - Seq.empty[SmartIri], - ) + cacheData + .getSuperClassesOf(baseClassIri) + .getOrElse( + Seq.empty[SmartIri], + ) } allBaseClassIris = classIri +: allBaseClassIrisWithoutInternal diff --git a/webapi/src/main/scala/org/knora/webapi/responders/v2/ontology/CardinalityHandler.scala b/webapi/src/main/scala/org/knora/webapi/responders/v2/ontology/CardinalityHandler.scala index 335a99fdc6..6658980872 100644 --- a/webapi/src/main/scala/org/knora/webapi/responders/v2/ontology/CardinalityHandler.scala +++ b/webapi/src/main/scala/org/knora/webapi/responders/v2/ontology/CardinalityHandler.scala @@ -100,10 +100,7 @@ final case class CardinalityHandler( allBaseClassIrisWithoutInternal = newClassDefinitionWithRemovedCardinality.subClassOf.toSeq.flatMap { baseClassIri => - cacheData.classToSuperClassLookup.getOrElse( - baseClassIri, - Seq.empty[SmartIri], - ) + cacheData.getSuperClassesOf(baseClassIri).getOrElse(Seq.empty[SmartIri]) } allBaseClassIris = internalClassIri +: allBaseClassIrisWithoutInternal @@ -242,10 +239,7 @@ final case class CardinalityHandler( allBaseClassIrisWithoutInternal = newClassDefinitionWithRemovedCardinality.subClassOf.toSeq.flatMap { baseClassIri => - cacheData.classToSuperClassLookup.getOrElse( - baseClassIri, - Seq.empty[SmartIri], - ) + cacheData.getSuperClassesOf(baseClassIri).getOrElse(Seq.empty[SmartIri]) } allBaseClassIris = internalClassIri +: allBaseClassIrisWithoutInternal diff --git a/webapi/src/main/scala/org/knora/webapi/slice/ontology/repo/model/OntologyCacheData.scala b/webapi/src/main/scala/org/knora/webapi/slice/ontology/repo/model/OntologyCacheData.scala index 94188e4b2e..09b9652e66 100644 --- a/webapi/src/main/scala/org/knora/webapi/slice/ontology/repo/model/OntologyCacheData.scala +++ b/webapi/src/main/scala/org/knora/webapi/slice/ontology/repo/model/OntologyCacheData.scala @@ -24,8 +24,8 @@ import org.knora.webapi.messages.v2.responder.ontologymessages.ReadPropertyInfoV */ case class OntologyCacheData( ontologies: Map[SmartIri, ReadOntologyV2], - classToSuperClassLookup: Map[SmartIri, Seq[SmartIri]], - classToSubclassLookup: Map[SmartIri, Set[SmartIri]], + private val classToSuperClassLookup: Map[SmartIri, Seq[SmartIri]], + private val classToSubclassLookup: Map[SmartIri, Set[SmartIri]], private val subPropertyOfRelations: Map[SmartIri, Set[SmartIri]], private val superPropertyOfRelations: Map[SmartIri, Set[SmartIri]], private val classDefinedInOntology: Map[SmartIri, SmartIri], @@ -50,6 +50,9 @@ case class OntologyCacheData( def getSubPropertiesOf(propertyIri: SmartIri): Option[Set[SmartIri]] = subPropertyOfRelations.get(propertyIri) def getSuperPropertiesOf(propertyIri: SmartIri): Option[Set[SmartIri]] = superPropertyOfRelations.get(propertyIri) + + def getSubClassesOf(classIri: SmartIri): Option[Set[SmartIri]] = classToSubclassLookup.get(classIri) + def getSuperClassesOf(classIri: SmartIri): Option[Seq[SmartIri]] = classToSuperClassLookup.get(classIri) } object OntologyCacheData { val Empty = OntologyCacheData( diff --git a/webapi/src/main/scala/org/knora/webapi/slice/ontology/repo/service/OntologyCache.scala b/webapi/src/main/scala/org/knora/webapi/slice/ontology/repo/service/OntologyCache.scala index 25dcb63d2c..0344377792 100644 --- a/webapi/src/main/scala/org/knora/webapi/slice/ontology/repo/service/OntologyCache.scala +++ b/webapi/src/main/scala/org/knora/webapi/slice/ontology/repo/service/OntologyCache.scala @@ -352,9 +352,9 @@ object OntologyCache { if (OntologyConstants.Owl.ClassesThatCanBeKnoraClassConstraints.contains(constraintValueToBeChecked.toString)) { Set(constraintValueToBeChecked) } else { - cacheData.classToSuperClassLookup + cacheData + .getSuperClassesOf(constraintValueToBeChecked) .getOrElse( - constraintValueToBeChecked, errorFun( s"Property ${internalPropertyIri.toOntologySchema(errorSchema)} cannot have a ${constraintPredicateIri .toOntologySchema(errorSchema)} of " + @@ -881,7 +881,7 @@ final case class OntologyCacheLive(triplestore: TriplestoreService, cacheDataRef private def updateSubClasses(baseClassIri: SmartIri, cacheData: OntologyCacheData): OntologyCacheData = { // Get the class definitions of all the subclasses of the base class. - val allSubClassIris: Set[SmartIri] = cacheData.classToSubclassLookup(baseClassIri) + val allSubClassIris: Set[SmartIri] = cacheData.getSubClassesOf(baseClassIri).get val allSubClasses: Set[ReadClassInfoV2] = allSubClassIris.map { subClassIri => cacheData.ontologies(subClassIri.getOntologyFromEntity).classes(subClassIri) From ec27abb43b488d6eb73700d188145d6a615871c4 Mon Sep 17 00:00:00 2001 From: Balduin Landolt <33053745+BalduinLandolt@users.noreply.github.com> Date: Sun, 22 Dec 2024 23:24:20 +0100 Subject: [PATCH 6/6] fix flip --- .../webapi/slice/ontology/repo/model/OntologyCacheData.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/webapi/src/main/scala/org/knora/webapi/slice/ontology/repo/model/OntologyCacheData.scala b/webapi/src/main/scala/org/knora/webapi/slice/ontology/repo/model/OntologyCacheData.scala index 09b9652e66..6703ae8655 100644 --- a/webapi/src/main/scala/org/knora/webapi/slice/ontology/repo/model/OntologyCacheData.scala +++ b/webapi/src/main/scala/org/knora/webapi/slice/ontology/repo/model/OntologyCacheData.scala @@ -48,8 +48,8 @@ case class OntologyCacheData( def classDefinedInOntology(classIri: SmartIri): Option[SmartIri] = classDefinedInOntology.get(classIri) def propertyDefinedInOntology(propertyIri: SmartIri): Option[SmartIri] = propertyDefinedInOntology.get(propertyIri) - def getSubPropertiesOf(propertyIri: SmartIri): Option[Set[SmartIri]] = subPropertyOfRelations.get(propertyIri) - def getSuperPropertiesOf(propertyIri: SmartIri): Option[Set[SmartIri]] = superPropertyOfRelations.get(propertyIri) + def getSubPropertiesOf(propertyIri: SmartIri): Option[Set[SmartIri]] = superPropertyOfRelations.get(propertyIri) + def getSuperPropertiesOf(propertyIri: SmartIri): Option[Set[SmartIri]] = subPropertyOfRelations.get(propertyIri) def getSubClassesOf(classIri: SmartIri): Option[Set[SmartIri]] = classToSubclassLookup.get(classIri) def getSuperClassesOf(classIri: SmartIri): Option[Seq[SmartIri]] = classToSuperClassLookup.get(classIri)