Skip to content

Commit

Permalink
refactor: Remove nested template calls (#3271)
Browse files Browse the repository at this point in the history
Co-authored-by: Christian Kleinbölting <[email protected]>
  • Loading branch information
BalduinLandolt and seakayone authored Jun 12, 2024
1 parent 0484780 commit affee1f
Show file tree
Hide file tree
Showing 20 changed files with 1,525 additions and 1,091 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,9 @@ object StringFormatter {

def isKnoraOntologyIri(iri: SmartIri): Boolean =
iri.isKnoraApiV2DefinitionIri && OntologyConstants.InternalOntologyLabels.contains(iri.getOntologyName)

def makeValueIri(resourceIri: IRI, uuid: UUID): IRI =
s"$resourceIri/values/${UuidUtil.base64Encode(uuid)}"
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,12 @@

package org.knora.webapi.messages.twirl

import java.time.Instant
import java.util.UUID

import org.knora.webapi.IRI
import org.knora.webapi.messages.SmartIri
import org.knora.webapi.messages.v2.responder.valuemessages.ValueContentV2

/**
* Contains instructions that can be given to a SPARQL template for updating direct links and `knora-base:LinkValue`
Expand Down Expand Up @@ -46,3 +50,25 @@ case class SparqlTemplateLinkUpdate(
newLinkValueCreator: IRI,
newLinkValuePermissions: String,
)

final case class NewLinkValueInfo(
linkPropertyIri: IRI,
newLinkValueIri: IRI,
linkTargetIri: IRI,
newReferenceCount: Int,
newLinkValueCreator: IRI,
newLinkValuePermissions: String,
valueUuid: String,
)

final case class NewValueInfo(
resourceIri: IRI,
propertyIri: IRI,
value: ValueContentV2,
newValueIri: IRI,
newValueUUID: UUID,
valueCreator: IRI,
valuePermissions: String,
creationDate: Instant,
valueHasOrder: Int,
)

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,24 @@ package org.knora.webapi.slice.resources.repo.service

import zio.*

import java.time.Instant

import dsp.constants.SalsahGui.IRI
import org.knora.webapi.messages.SmartIri
import org.knora.webapi.messages.twirl.NewLinkValueInfo
import org.knora.webapi.messages.twirl.NewValueInfo
import org.knora.webapi.messages.twirl.queries.sparql
import org.knora.webapi.messages.v2.responder.valuemessages.UnverifiedValueV2
import org.knora.webapi.responders.v2.resources.SparqlTemplateResourceToCreate
import org.knora.webapi.slice.resourceinfo.domain.InternalIri
import org.knora.webapi.store.triplestore.api.TriplestoreService
import org.knora.webapi.store.triplestore.api.TriplestoreService.Queries.Update

/**
* Represents a resource that is ready to be created and whose contents can be verified afterwards.
*
* @param sparqlTemplateResourceToCreate a [[SparqlTemplateResourceToCreate]] describing SPARQL for creating
* the resource.
* @param values the resource's values for verification.
* @param hasStandoffLink `true` if the property `knora-base:hasStandoffLinkToValue` was automatically added.
*/
case class ResourceReadyToCreate(
sparqlTemplateResourceToCreate: SparqlTemplateResourceToCreate,
values: Map[SmartIri, Seq[UnverifiedValueV2]],
hasStandoffLink: Boolean,
resourceIri: IRI,
resourceClassIri: IRI,
resourceLabel: String,
creationDate: Instant,
permissions: String,
newValueInfos: Seq[NewValueInfo],
linkUpdates: Seq[NewLinkValueInfo],
)

trait ResourcesRepo {
Expand All @@ -48,16 +45,37 @@ final case class ResourcesRepoLive(triplestore: TriplestoreService) extends Reso
projectIri: IRI,
): Task[Unit] =
triplestore.query(
Update(
sparql.v2.txt.createNewResource(
dataNamedGraph = dataGraphIri.value,
resourceToCreate = resource.sparqlTemplateResourceToCreate,
projectIri = projectIri,
creatorIri = userIri,
),
ResourcesRepoLive.createNewResourceQuery(
dataGraphIri,
resource,
projectIri,
userIri,
),
)

}

object ResourcesRepoLive { val layer = ZLayer.derive[ResourcesRepoLive] }
object ResourcesRepoLive {
val layer = ZLayer.derive[ResourcesRepoLive]

private[service] def createNewResourceQuery(
dataGraphIri: InternalIri,
resourceToCreate: ResourceReadyToCreate,
projectIri: IRI,
creatorIri: IRI,
): Update =
Update(
sparql.v2.txt.createNewResource(
dataNamedGraph = dataGraphIri.value,
projectIri = projectIri,
creatorIri = creatorIri,
creationDate = resourceToCreate.creationDate,
resourceIri = resourceToCreate.resourceIri,
resourceClassIri = resourceToCreate.resourceClassIri,
resourceLabel = resourceToCreate.resourceLabel,
permissions = resourceToCreate.permissions,
linkUpdates = resourceToCreate.linkUpdates,
newValueInfos = resourceToCreate.newValueInfos,
),
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@
* SPDX-License-Identifier: Apache-2.0
*@

@import dsp.errors.SparqlGenerationException
@import dsp.valueobjects.UuidUtil
@import java.time.Instant
@import java.util.UUID
@import dsp.valueobjects.UuidUtil
@import org.knora.webapi.IRI
@import org.knora.webapi._
@import org.knora.webapi.messages.SmartIri
@import org.knora.webapi.messages.twirl.SparqlTemplateLinkUpdate
@import org.knora.webapi.messages.v2.responder.valuemessages._
Expand Down Expand Up @@ -93,9 +94,214 @@ DELETE {
knora-base:valueHasString """@value.valueHasString""" ;
knora-base:valueHasUUID ?currentValueUUID .

@{
org.knora.webapi.messages.twirl.queries.sparql.v2.txt.generateInsertStatementsForValueContent(value = value,
newValueIri = newValueIri)

@value match {

case textValue: TextValueContentV2 => {

@if(!textValue.valueHasLanguage.isEmpty) {
<@newValueIri> knora-base:valueHasLanguage """@textValue.valueHasLanguage.get""" .
}

@if(textValue.standoff.nonEmpty) {

@* Create a Standoff node for each standoff tag. *@

@textValue.mappingIri match {
case Some(definedMappingIri) => {
<@newValueIri> knora-base:valueHasMapping <@definedMappingIri> .
}

case None => {}
}

<@newValueIri> knora-base:valueHasMaxStandoffStartIndex @textValue.computedMaxStandoffStartIndex.get .

@for((createStandoff: CreateStandoffTagV2InTriplestore, standoffNodeIndex) <- textValue.prepareForSparqlInsert(newValueIri).zipWithIndex) {

<@newValueIri> knora-base:valueHasStandoff <@createStandoff.standoffTagInstanceIri> .

<@createStandoff.standoffTagInstanceIri>

@*

Check for optional standoff properties

*@

@if(createStandoff.standoffNode.endIndex.isDefined) {
knora-base:standoffTagHasEndIndex @createStandoff.standoffNode.endIndex.get ;
}

@if(createStandoff.startParentIri.isDefined) {
knora-base:standoffTagHasStartParent <@createStandoff.startParentIri.get> ;
}

@if(createStandoff.endParentIri.isDefined) {
knora-base:standoffTagHasEndParent <@createStandoff.endParentIri.get> ;
}

@if(createStandoff.standoffNode.originalXMLID.isDefined) {
knora-base:standoffTagHasOriginalXMLID """@createStandoff.standoffNode.originalXMLID.get""" ;
}

@*

Handle standoff class specific standoff properties

*@
@for(createProperty <- createStandoff.standoffNode.attributes) {

<@createProperty.standoffPropertyIri> @createProperty.rdfValue ;

}

knora-base:standoffTagHasStartIndex @createStandoff.standoffNode.startIndex ;
knora-base:standoffTagHasUUID "@{UuidUtil.base64Encode(createStandoff.standoffNode.uuid)}" ;
knora-base:standoffTagHasStart @createStandoff.standoffNode.startPosition ;
knora-base:standoffTagHasEnd @createStandoff.standoffNode.endPosition ;
rdf:type <@createStandoff.standoffNode.standoffTagClassIri> .

}

}
}


case intValue: IntegerValueContentV2 => {

<@newValueIri> knora-base:valueHasInteger @intValue.valueHasInteger .

}

case decimalValue: DecimalValueContentV2 => {

<@newValueIri> knora-base:valueHasDecimal "@decimalValue.valueHasDecimal"^^xsd:decimal .

}

case booleanValue: BooleanValueContentV2 => {

<@newValueIri> knora-base:valueHasBoolean @booleanValue.valueHasBoolean .

}

case uriValue: UriValueContentV2 => {

<@newValueIri> knora-base:valueHasUri """@uriValue.valueHasUri"""^^xsd:anyURI .

}

case dateValue: DateValueContentV2 => {

<@newValueIri> knora-base:valueHasStartJDN @dateValue.valueHasStartJDN ;
knora-base:valueHasEndJDN @dateValue.valueHasEndJDN ;
knora-base:valueHasStartPrecision "@dateValue.valueHasStartPrecision" ;
knora-base:valueHasEndPrecision "@dateValue.valueHasEndPrecision" ;
knora-base:valueHasCalendar "@dateValue.valueHasCalendar" .

}

case colorValue: ColorValueContentV2 => {

<@newValueIri> knora-base:valueHasColor """@colorValue.valueHasColor""" .

}

case geometryValue: GeomValueContentV2 => {

<@newValueIri> knora-base:valueHasGeometry """@geometryValue.valueHasGeometry""" .

}

case fileValueContentV2: FileValueContentV2 => {
<@newValueIri> knora-base:internalFilename """@fileValueContentV2.fileValue.internalFilename""" ;
knora-base:internalMimeType """@fileValueContentV2.fileValue.internalMimeType""" .

@fileValueContentV2.fileValue.originalFilename match {
case Some(definedOriginalFilename) => {
<@newValueIri> knora-base:originalFilename """@definedOriginalFilename""" .
}

case None => {}
}

@fileValueContentV2.fileValue.originalMimeType match {
case Some(definedOriginalMimeType) => {
<@newValueIri> knora-base:originalMimeType """@definedOriginalMimeType""" .
}

case None => {}
}

@fileValueContentV2 match {
case stillImageFileValue: StillImageFileValueContentV2 => {
<@newValueIri> knora-base:dimX @stillImageFileValue.dimX ;
knora-base:dimY @stillImageFileValue.dimY .
}

case stillImageFileValue: StillImageExternalFileValueContentV2 => {
<@newValueIri> knora-base:externalUrl """@stillImageFileValue.externalUrl.value.toString""" .
}

case documentFileValue: DocumentFileValueContentV2 => {
@documentFileValue.dimX match {
case Some(definedDimX) => {
<@newValueIri> knora-base:dimX @definedDimX .
}

case None => {}
}

@documentFileValue.dimY match {
case Some(definedDimY) => {
<@newValueIri> knora-base:dimY @definedDimY .
}

case None => {}
}

@documentFileValue.pageCount match {
case Some(definedPageCount) => {
<@newValueIri> knora-base:pageCount @definedPageCount .
}

case None => {}
}
}

case _ => {}
}
}

case listValue: HierarchicalListValueContentV2 => {

<@newValueIri> knora-base:valueHasListNode <@listValue.valueHasListNode> .

}

case intervalValue: IntervalValueContentV2 => {

<@newValueIri> knora-base:valueHasIntervalStart "@intervalValue.valueHasIntervalStart"^^xsd:decimal ;
knora-base:valueHasIntervalEnd "@intervalValue.valueHasIntervalEnd"^^xsd:decimal .

}

case timeValue: TimeValueContentV2 => {

<@newValueIri> knora-base:valueHasTimeStamp "@timeValue.valueHasTimeStamp"^^xsd:dateTime .

}

case geonameValue: GeonameValueContentV2 => {

<@newValueIri> knora-base:valueHasGeonameCode """@geonameValue.valueHasGeonameCode""" .

}

case other => {
@{throw SparqlGenerationException(s"Value object $other is not supported in this SPARQL template"); ()}
}
}

@* Insert the value's comment, if given. *@
Expand Down
Loading

0 comments on commit affee1f

Please sign in to comment.