Skip to content

Commit

Permalink
Merge branch 'main' into refactor/make-Project-join-typed
Browse files Browse the repository at this point in the history
  • Loading branch information
seakayone authored Feb 6, 2025
2 parents b674223 + 8ee061c commit 6bc6285
Show file tree
Hide file tree
Showing 8 changed files with 228 additions and 102 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import org.knora.webapi.messages.util.rdf.SparqlSelectResult
import org.knora.webapi.messages.v2.responder.CanDoResponseV2
import org.knora.webapi.messages.v2.responder.SuccessResponseV2
import org.knora.webapi.messages.v2.responder.ontologymessages.*
import org.knora.webapi.messages.v2.responder.ontologymessages.ChangeClassLabelsOrCommentsRequestV2.LabelOrComment
import org.knora.webapi.messages.v2.responder.ontologymessages.OwlCardinality.KnoraCardinalityInfo
import org.knora.webapi.messages.v2.responder.resourcemessages.CreateResourceRequestV2
import org.knora.webapi.messages.v2.responder.resourcemessages.CreateResourceV2
Expand Down Expand Up @@ -89,7 +90,7 @@ class OntologyResponderV2Spec extends CoreSpec with ImplicitSender {
private val chairIri = new MutableTestIri
private val ExampleSharedOntologyIri = "http://api.knora.org/ontology/shared/example-box/v2".toSmartIri
private val IncunabulaOntologyIri = "http://0.0.0.0:3333/ontology/0803/incunabula/v2".toSmartIri
private val AnythingOntologyIri = "http://0.0.0.0:3333/ontology/0001/anything/v2".toSmartIri
private val AnythingOntologyIri = OntologyIri.unsafeFrom("http://0.0.0.0:3333/ontology/0001/anything/v2".toSmartIri)
private val FreeTestOntologyIri = "http://0.0.0.0:3333/ontology/0001/freetest/v2".toSmartIri
private var fooLastModDate: Instant = Instant.now
private var barLastModDate: Instant = Instant.now
Expand Down Expand Up @@ -469,13 +470,13 @@ class OntologyResponderV2Spec extends CoreSpec with ImplicitSender {
anythingLastModDate = metadataResponse
.toOntologySchema(ApiV2Complex)
.ontologies
.find(_.ontologyIri == AnythingOntologyIri)
.find(_.ontologyIri == AnythingOntologyIri.smartIri)
.get
.lastModificationDate
.get

appActor ! DeleteOntologyRequestV2(
ontologyIri = OntologyIri.unsafeFrom(AnythingOntologyIri),
ontologyIri = AnythingOntologyIri,
lastModificationDate = anythingLastModDate,
apiRequestID = UUID.randomUUID,
requestingUser = anythingAdminUser,
Expand Down Expand Up @@ -675,7 +676,7 @@ class OntologyResponderV2Spec extends CoreSpec with ImplicitSender {
anythingLastModDate = metadataResponse
.toOntologySchema(ApiV2Complex)
.ontologies
.find(_.ontologyIri == AnythingOntologyIri)
.find(_.ontologyIri == AnythingOntologyIri.smartIri)
.get
.lastModificationDate
.get
Expand Down Expand Up @@ -734,7 +735,7 @@ class OntologyResponderV2Spec extends CoreSpec with ImplicitSender {
anythingLastModDate = metadataResponse
.toOntologySchema(ApiV2Complex)
.ontologies
.find(_.ontologyIri == AnythingOntologyIri)
.find(_.ontologyIri == AnythingOntologyIri.smartIri)
.get
.lastModificationDate
.get
Expand Down Expand Up @@ -820,7 +821,7 @@ class OntologyResponderV2Spec extends CoreSpec with ImplicitSender {
anythingLastModDate = metadataResponse
.toOntologySchema(ApiV2Complex)
.ontologies
.find(_.ontologyIri == AnythingOntologyIri)
.find(_.ontologyIri == AnythingOntologyIri.smartIri)
.get
.lastModificationDate
.get
Expand Down Expand Up @@ -2720,7 +2721,7 @@ class OntologyResponderV2Spec extends CoreSpec with ImplicitSender {
val newLabel = "The modified anything ontology"

appActor ! ChangeOntologyMetadataRequestV2(
ontologyIri = OntologyIri.unsafeFrom(AnythingOntologyIri),
ontologyIri = AnythingOntologyIri,
label = Some(newLabel),
lastModificationDate = anythingLastModDate,
apiRequestID = UUID.randomUUID,
Expand All @@ -2730,7 +2731,7 @@ class OntologyResponderV2Spec extends CoreSpec with ImplicitSender {
val response = expectMsgType[ReadOntologyMetadataV2](timeout)
assert(response.ontologies.size == 1)
val metadata = response.ontologies.head
assert(metadata.ontologyIri.toOntologySchema(ApiV2Complex) == AnythingOntologyIri)
assert(metadata.ontologyIri.toOntologySchema(ApiV2Complex) == AnythingOntologyIri.smartIri)
assert(metadata.label.contains(newLabel))
val newAnythingLastModDate = metadata.lastModificationDate.getOrElse(
throw AssertionException(s"${metadata.ontologyIri} has no last modification date"),
Expand Down Expand Up @@ -3147,7 +3148,7 @@ class OntologyResponderV2Spec extends CoreSpec with ImplicitSender {

"not allow a user to change the labels of a class if they are not a sysadmin or an admin in the ontology's project" in {

val classIri = AnythingOntologyIri.makeEntityIri("Nothing")
val classIri = AnythingOntologyIri.makeClass("Nothing")

val newObjects = Seq(
StringLiteralV2.from("nothing", Some("en")),
Expand All @@ -3156,7 +3157,7 @@ class OntologyResponderV2Spec extends CoreSpec with ImplicitSender {

appActor ! ChangeClassLabelsOrCommentsRequestV2(
classIri = classIri,
predicateToUpdate = Rdfs.Label.toSmartIri,
predicateToUpdate = LabelOrComment.Label,
newObjects = newObjects,
lastModificationDate = anythingLastModDate,
apiRequestID = UUID.randomUUID,
Expand All @@ -3170,7 +3171,7 @@ class OntologyResponderV2Spec extends CoreSpec with ImplicitSender {
}

"change the labels of a class" in {
val classIri = AnythingOntologyIri.makeEntityIri("Nothing")
val classIri = AnythingOntologyIri.makeClass("Nothing")

val newObjects = Seq(
StringLiteralV2.from("nothing", Some("en")),
Expand All @@ -3179,7 +3180,7 @@ class OntologyResponderV2Spec extends CoreSpec with ImplicitSender {

appActor ! ChangeClassLabelsOrCommentsRequestV2(
classIri = classIri,
predicateToUpdate = Rdfs.Label.toSmartIri,
predicateToUpdate = LabelOrComment.Label,
newObjects = newObjects,
lastModificationDate = anythingLastModDate,
apiRequestID = UUID.randomUUID,
Expand All @@ -3189,7 +3190,7 @@ class OntologyResponderV2Spec extends CoreSpec with ImplicitSender {
expectMsgPF(timeout) { case msg: ReadOntologyV2 =>
val externalOntology = msg.toOntologySchema(ApiV2Complex)
assert(externalOntology.classes.size == 1)
val readClassInfo = externalOntology.classes(classIri)
val readClassInfo = externalOntology.classes(classIri.smartIri)
readClassInfo.entityInfoContent.predicates(Rdfs.Label.toSmartIri).objects should ===(
newObjects,
)
Expand All @@ -3204,7 +3205,7 @@ class OntologyResponderV2Spec extends CoreSpec with ImplicitSender {
}

"change the labels of a class, submitting the same labels again" in {
val classIri = AnythingOntologyIri.makeEntityIri("Nothing")
val classIri = AnythingOntologyIri.makeClass("Nothing")

val newObjects = Seq(
StringLiteralV2.from("nothing", Some("en")),
Expand All @@ -3213,7 +3214,7 @@ class OntologyResponderV2Spec extends CoreSpec with ImplicitSender {

appActor ! ChangeClassLabelsOrCommentsRequestV2(
classIri = classIri,
predicateToUpdate = Rdfs.Label.toSmartIri,
predicateToUpdate = LabelOrComment.Label,
newObjects = newObjects,
lastModificationDate = anythingLastModDate,
apiRequestID = UUID.randomUUID,
Expand All @@ -3223,7 +3224,7 @@ class OntologyResponderV2Spec extends CoreSpec with ImplicitSender {
expectMsgPF(timeout) { case msg: ReadOntologyV2 =>
val externalOntology = msg.toOntologySchema(ApiV2Complex)
assert(externalOntology.classes.size == 1)
val readClassInfo = externalOntology.classes(classIri)
val readClassInfo = externalOntology.classes(classIri.smartIri)
readClassInfo.entityInfoContent.predicates(Rdfs.Label.toSmartIri).objects should ===(
newObjects,
)
Expand All @@ -3239,7 +3240,7 @@ class OntologyResponderV2Spec extends CoreSpec with ImplicitSender {

"not allow a user to change the comments of a class if they are not a sysadmin or an admin in the ontology's project" in {

val classIri = AnythingOntologyIri.makeEntityIri("Nothing")
val classIri = AnythingOntologyIri.makeClass("Nothing")

val newObjects = Seq(
StringLiteralV2.from("Represents nothing", Some("en")),
Expand All @@ -3248,7 +3249,7 @@ class OntologyResponderV2Spec extends CoreSpec with ImplicitSender {

appActor ! ChangeClassLabelsOrCommentsRequestV2(
classIri = classIri,
predicateToUpdate = Rdfs.Comment.toSmartIri,
predicateToUpdate = LabelOrComment.Comment,
newObjects = newObjects,
lastModificationDate = anythingLastModDate,
apiRequestID = UUID.randomUUID,
Expand All @@ -3262,7 +3263,7 @@ class OntologyResponderV2Spec extends CoreSpec with ImplicitSender {
}

"change the comments of a class" in {
val classIri = AnythingOntologyIri.makeEntityIri("Nothing")
val classIri = AnythingOntologyIri.makeClass("Nothing")

val newObjects = Seq(
StringLiteralV2.from("Represents nothing", Some("en")),
Expand All @@ -3276,7 +3277,7 @@ class OntologyResponderV2Spec extends CoreSpec with ImplicitSender {

appActor ! ChangeClassLabelsOrCommentsRequestV2(
classIri = classIri,
predicateToUpdate = Rdfs.Comment.toSmartIri,
predicateToUpdate = LabelOrComment.Comment,
newObjects = newObjects,
lastModificationDate = anythingLastModDate,
apiRequestID = UUID.randomUUID,
Expand All @@ -3286,7 +3287,7 @@ class OntologyResponderV2Spec extends CoreSpec with ImplicitSender {
expectMsgPF(timeout) { case msg: ReadOntologyV2 =>
val externalOntology = msg.toOntologySchema(ApiV2Complex)
assert(externalOntology.classes.size == 1)
val readClassInfo = externalOntology.classes(classIri)
val readClassInfo = externalOntology.classes(classIri.smartIri)
readClassInfo.entityInfoContent.predicates(Rdfs.Comment.toSmartIri).objects should ===(
newObjectsUnescaped,
)
Expand All @@ -3301,7 +3302,7 @@ class OntologyResponderV2Spec extends CoreSpec with ImplicitSender {
}

"change the comments of a class, submitting the same comments again" in {
val classIri = AnythingOntologyIri.makeEntityIri("Nothing")
val classIri = AnythingOntologyIri.makeClass("Nothing")

val newObjects = Seq(
StringLiteralV2.from("Represents nothing", Some("en")),
Expand All @@ -3315,7 +3316,7 @@ class OntologyResponderV2Spec extends CoreSpec with ImplicitSender {

appActor ! ChangeClassLabelsOrCommentsRequestV2(
classIri = classIri,
predicateToUpdate = Rdfs.Comment.toSmartIri,
predicateToUpdate = LabelOrComment.Comment,
newObjects = newObjects,
lastModificationDate = anythingLastModDate,
apiRequestID = UUID.randomUUID,
Expand All @@ -3325,7 +3326,7 @@ class OntologyResponderV2Spec extends CoreSpec with ImplicitSender {
expectMsgPF(timeout) { case msg: ReadOntologyV2 =>
val externalOntology = msg.toOntologySchema(ApiV2Complex)
assert(externalOntology.classes.size == 1)
val readClassInfo = externalOntology.classes(classIri)
val readClassInfo = externalOntology.classes(classIri.smartIri)
readClassInfo.entityInfoContent.predicates(Rdfs.Comment.toSmartIri).objects should ===(
newObjectsUnescaped,
)
Expand Down Expand Up @@ -6199,7 +6200,7 @@ class OntologyResponderV2Spec extends CoreSpec with ImplicitSender {
anythingLastModDate = metadataResponse
.toOntologySchema(ApiV2Complex)
.ontologies
.find(_.ontologyIri == AnythingOntologyIri)
.find(_.ontologyIri == AnythingOntologyIri.smartIri)
.get
.lastModificationDate
.get
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import org.knora.webapi.messages.v2.responder.standoffmessages.StandoffDataTypeC
import org.knora.webapi.slice.admin.domain.model.KnoraProject.ProjectIri
import org.knora.webapi.slice.admin.domain.model.User
import org.knora.webapi.slice.common.KnoraIris.OntologyIri
import org.knora.webapi.slice.common.KnoraIris.ResourceClassIri
import org.knora.webapi.slice.ontology.domain.model.Cardinality

/**
Expand Down Expand Up @@ -781,49 +782,26 @@ object DeletePropertyCommentRequestV2 {
* @param requestingUser the user making the request.
*/
case class ChangeClassLabelsOrCommentsRequestV2(
classIri: SmartIri,
predicateToUpdate: SmartIri,
classIri: ResourceClassIri,
predicateToUpdate: ChangeClassLabelsOrCommentsRequestV2.LabelOrComment,
newObjects: Seq[StringLiteralV2],
lastModificationDate: Instant,
apiRequestID: UUID,
requestingUser: User,
) extends OntologiesResponderRequestV2
with ChangeLabelsOrCommentsRequest

/**
* Constructs instances of [[ChangeClassLabelsOrCommentsRequestV2]] based on JSON-LD input.
*/
object ChangeClassLabelsOrCommentsRequestV2 {
enum LabelOrComment {
case Label
case Comment

/**
* Converts a JSON-LD request to a [[ChangeClassLabelsOrCommentsRequestV2]].
*
* @param jsonLDDocument the JSON-LD input.
* @param apiRequestID the UUID of the API request.
* @param requestingUser the user making the request.
* @return a [[ChangeClassLabelsOrCommentsRequestV2]] representing the input.
*/
def fromJsonLd(
jsonLDDocument: JsonLDDocument,
apiRequestID: UUID,
requestingUser: User,
): ChangeClassLabelsOrCommentsRequestV2 = {
val inputOntologiesV2 = InputOntologyV2.fromJsonLD(jsonLDDocument)
val classUpdateInfo = OntologyUpdateHelper.getClassDef(inputOntologiesV2)
val classInfoContent = classUpdateInfo.classInfoContent
val lastModificationDate = classUpdateInfo.lastModificationDate
val predicateInfoToUpdate = OntologyUpdateHelper.getLabelsOrComments(classInfoContent)

ChangeClassLabelsOrCommentsRequestV2(
classIri = classInfoContent.classIri,
predicateToUpdate = predicateInfoToUpdate.predicateIri,
newObjects = predicateInfoToUpdate.objects.collect { case strLiteral: StringLiteralV2 =>
strLiteral
},
lastModificationDate = lastModificationDate,
apiRequestID = apiRequestID,
requestingUser = requestingUser,
)
override def toString: String = this match {
case Label => RDFS.LABEL.toString
case Comment => RDFS.COMMENT.toString
}
}
object LabelOrComment {
def fromString(str: String): Option[LabelOrComment] =
LabelOrComment.values.find(_.toString == str)
}
}

Expand Down Expand Up @@ -975,7 +953,6 @@ case class EntityInfoGetResponseV2(
*
* @param standoffClassIris the IRIs of the resource entities to be queried.
* @param standoffPropertyIris the IRIs of the property entities to be queried.
* @param requestingUser the user making the request.
*/
case class StandoffEntityInfoGetRequestV2(
standoffClassIris: Set[SmartIri] = Set.empty,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1986,26 +1986,29 @@ final case class OntologyResponderV2(
/**
* Changes the values of `rdfs:label` or `rdfs:comment` in a class definition.
*
* @param changeClassLabelsOrCommentsRequest the request to change the class's labels or comments.
* @param req the request to change the class's labels or comments.
* @return a [[ReadOntologyV2]] containing the modified class definition.
*/
private def changeClassLabelsOrComments(
changeClassLabelsOrCommentsRequest: ChangeClassLabelsOrCommentsRequestV2,
): Task[ReadOntologyV2] = {
def makeTaskFuture(internalClassIri: SmartIri, internalOntologyIri: SmartIri): Task[ReadOntologyV2] =
private def changeClassLabelsOrComments(req: ChangeClassLabelsOrCommentsRequestV2): Task[ReadOntologyV2] = {
val internalClassIri = req.classIri.toInternalSchema
val internalOntologyIri = req.classIri.ontologyIri.toInternalSchema
val externalClassIri = req.classIri.toComplexSchema
val externalOntologyIri = req.classIri.ontologyIri.toComplexSchema

val changeTask: Task[ReadOntologyV2] =
for {
cacheData <- ontologyCache.getCacheData

ontology = cacheData.ontologies(internalOntologyIri)
currentReadClassInfo <-
ZIO
.fromOption(ontology.classes.get(internalClassIri))
.orElseFail(NotFoundException(s"Class ${changeClassLabelsOrCommentsRequest.classIri} not found"))
.orElseFail(NotFoundException(s"Class ${req.classIri} not found"))

// Check that the ontology exists and has not been updated by another user since the client last read it.
_ <- ontologyTriplestoreHelpers.checkOntologyLastModificationDate(
internalOntologyIri,
changeClassLabelsOrCommentsRequest.lastModificationDate,
req.lastModificationDate,
)

// Do the update.
Expand All @@ -2016,9 +2019,9 @@ final case class OntologyResponderV2(
ontologyNamedGraphIri = internalOntologyIri,
ontologyIri = internalOntologyIri,
classIri = internalClassIri,
predicateToUpdate = changeClassLabelsOrCommentsRequest.predicateToUpdate,
newObjects = changeClassLabelsOrCommentsRequest.newObjects,
lastModificationDate = changeClassLabelsOrCommentsRequest.lastModificationDate,
predicateToUpdate = req.predicateToUpdate,
newObjects = req.newObjects,
lastModificationDate = req.lastModificationDate,
currentTime = currentTime,
)
_ <- save(Update(updateSparql))
Expand All @@ -2027,28 +2030,18 @@ final case class OntologyResponderV2(
response <- ontologyCacheHelpers.getClassDefinitionsFromOntologyV2(
classIris = Set(internalClassIri),
allLanguages = true,
requestingUser = changeClassLabelsOrCommentsRequest.requestingUser,
requestingUser = req.requestingUser,
)
} yield response

for {
requestingUser <- ZIO.succeed(changeClassLabelsOrCommentsRequest.requestingUser)

externalClassIri = changeClassLabelsOrCommentsRequest.classIri
externalOntologyIri = externalClassIri.getOntologyFromEntity
requestingUser <- ZIO.succeed(req.requestingUser)

_ <-
ontologyCacheHelpers.checkOntologyAndEntityIrisForUpdate(externalOntologyIri, externalClassIri, requestingUser)

internalClassIri = externalClassIri.toOntologySchema(InternalSchema)
internalOntologyIri = externalOntologyIri.toOntologySchema(InternalSchema)

// Do the remaining pre-update checks and the update while holding a global ontology cache lock.
taskResult <- IriLocker.runWithIriLock(
changeClassLabelsOrCommentsRequest.apiRequestID,
ONTOLOGY_CACHE_LOCK_IRI,
makeTaskFuture(internalClassIri, internalOntologyIri),
)
taskResult <- IriLocker.runWithIriLock(req.apiRequestID, ONTOLOGY_CACHE_LOCK_IRI, changeTask)
} yield taskResult
}

Expand Down
Loading

0 comments on commit 6bc6285

Please sign in to comment.