Skip to content

Commit

Permalink
more optics
Browse files Browse the repository at this point in the history
  • Loading branch information
seakayone committed Nov 22, 2024
1 parent f2f49c4 commit 5399d56
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import org.knora.webapi.messages.util.rdf.*
import org.knora.webapi.messages.util.standoff.StandoffTagUtilV2
import org.knora.webapi.messages.util.standoff.XMLUtil
import org.knora.webapi.messages.v2.responder.*
import org.knora.webapi.messages.v2.responder.resourcemessages.ResourceMessagesV2Optics.ReadResourceV2Optics
import org.knora.webapi.messages.v2.responder.standoffmessages.MappingXMLtoStandoff
import org.knora.webapi.messages.v2.responder.valuemessages.*
import org.knora.webapi.messages.v2.responder.valuemessages.ValueMessagesV2Optics.*
Expand Down Expand Up @@ -587,24 +588,32 @@ object ReadResourceV2 {
private def setCopyrightAndLicenceIfMissingResourceValues(
copyright: Option[CopyrightAttribution],
license: Option[License],
): ReadResourceV2 => ReadResourceV2 =
setIfMissing(FileValueV2Optics.licenseOption)(license)
.andThen(setIfMissing(FileValueV2Optics.copyrightAttributionOption)(copyright))
): ReadResourceV2 => ReadResourceV2 = { rr =>

private def ifMissingMapper[T](optional: Optional[ReadValueV2, Option[T]], newValue: Option[T]) =
(smartIri: SmartIri, seq: Seq[ReadValueV2]) =>
(
smartIri,
seq.map { readValue =>
optional.getOption(readValue).flatten match
case Some(_) => readValue
case None => optional.replace(newValue)(readValue)
},
)
def readValueWith(predicate: FileValueV2 => Boolean): ReadValueV2 => Boolean = rv =>
ReadValueV2Optics.fileValueV2.getOption(rv).exists(predicate)

def readValuesWith(predicate: FileValueV2 => Boolean): Optional[Seq[ReadValueV2], FileValueV2] =
ReadValueV2Optics
.elements(readValueWith(predicate))
.andThen(ReadValueV2Optics.fileValueV2)

private def setIfMissing[T](opt: Optional[FileValueV2, Option[T]]): Option[T] => ReadResourceV2 => ReadResourceV2 =
value =>
rr => rr.copy(values = rr.values.map(ifMissingMapper(ReadValueV2Optics.fileValueV2.andThen(opt), value)(_, _)))
def readValuesWithPred(predicate: FileValueV2 => Boolean): Seq[ReadValueV2] => Boolean =
readValuesWith(predicate).getOption(_).isDefined

def readResourcesWith(predicate: FileValueV2 => Boolean): Optional[ReadResourceV2, Seq[ReadValueV2]] =
ReadResourceV2Optics.values(readValuesWithPred(predicate))

def fileValueWith(predicate: FileValueV2 => Boolean): Optional[ReadResourceV2, FileValueV2] =
readResourcesWith(predicate).andThen(readValuesWith(predicate))

def setIfMissing[T](opt: Optional[FileValueV2, Option[T]], newValue: Option[T]): ReadResourceV2 => ReadResourceV2 =
r => fileValueWith(v => opt.getOption(v).flatten.isEmpty).andThen(opt).modifyOption(_ => newValue)(r).getOrElse(r)

setIfMissing(FileValueV2Optics.licenseOption, license).andThen(
setIfMissing(FileValueV2Optics.copyrightAttributionOption, copyright),
)(rr)
}

private def setCopyrightAndLicenceIfMissingOnLinkedResources(
copyright: Option[CopyrightAttribution],
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright © 2021 - 2024 Swiss National Data and Service Center for the Humanities and/or DaSCH Service Platform contributors.
* SPDX-License-Identifier: Apache-2.0
*/

package org.knora.webapi.messages.v2.responder.resourcemessages

import monocle.*
import monocle.macros.*

import org.knora.webapi.messages.SmartIri
import org.knora.webapi.messages.v2.responder.valuemessages.ReadValueV2

object ResourceMessagesV2Optics {

type ReadResourceV2Values = Map[SmartIri, Seq[ReadValueV2]]

object ReadResourceV2Optics {

val values: Lens[ReadResourceV2, ReadResourceV2Values] = GenLens[ReadResourceV2](_.values)

private def inValues(predicate: Seq[ReadValueV2] => Boolean): Optional[ReadResourceV2Values, Seq[ReadValueV2]] =
Optional[ReadResourceV2Values, Seq[ReadValueV2]](_.values.find(predicate))(newValue =>
values =>
values.map {
case (k, v) if predicate(v) => (k, newValue)
case other => other
},
)

def values(predicate: Seq[ReadValueV2] => Boolean): Optional[ReadResourceV2, Seq[ReadValueV2]] =
values.andThen(inValues(predicate))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -69,5 +69,13 @@ object ValueMessagesV2Optics {
val nestedResourceOfLinkValueContent: Optional[ReadValueV2, ReadResourceV2] =
ReadValueV2Optics.linkValueContentV2.andThen(LinkValueContentV2Optics.nestedResource)

def elements(predicate: ReadValueV2 => Boolean): Optional[Seq[ReadValueV2], ReadValueV2] =
Optional[Seq[ReadValueV2], ReadValueV2](_.find(predicate))(newValue =>
values =>
values.map {
case v if predicate(v) => newValue
case other => other
},
)
}
}

0 comments on commit 5399d56

Please sign in to comment.