diff --git a/docs/03-endpoints/api-v2/editing-values.md b/docs/03-endpoints/api-v2/editing-values.md index 852efffb27..30550ba83a 100644 --- a/docs/03-endpoints/api-v2/editing-values.md +++ b/docs/03-endpoints/api-v2/editing-values.md @@ -365,7 +365,7 @@ and the `knora-api:externalUrl` property is used to provide the URL of the image "@type": "anything:ThingPicture", "knora-api:hasStillImageFileValue": { "@type": "knora-api:StillImageExternalFileValue", - "knora-api:externalUrl": "https://example.com/iiif/3UIsXH9bP0j-BV0D4sN51Xz.jp2/full/max/0/default.jpg" + "knora-api:stillImageFileValueHasExternalUrl": "https://example.com/iiif/3UIsXH9bP0j-BV0D4sN51Xz.jp2/full/max/0/default.jpg" }, "knora-api:attachedToProject": { "@id": "http://rdfh.ch/projects/0001" @@ -381,7 +381,10 @@ and the `knora-api:externalUrl` property is used to provide the URL of the image } ``` -In the case of a `knora-api:StillImageExternalFileValue` DSP-API does not retrieve any metadata from external IIIF server. +*Note:* For backwards compatibility, the `knora-api:fileValueHasExternalUrl` property may be used instead of +`knora-api:stillImageFileValueHasExternalUrl`. +The `knora-api:fileValueHasExternalUrl` property is deprecated and will be removed in the future. +The `knora-api:stillImageFileValueHasExternalUrl` property is correct and must be used for reading and writing. #### PDF Documents diff --git a/webapi/src/main/scala/org/knora/webapi/messages/OntologyConstants.scala b/webapi/src/main/scala/org/knora/webapi/messages/OntologyConstants.scala index 5e7fb5b0b8..37fa73df89 100644 --- a/webapi/src/main/scala/org/knora/webapi/messages/OntologyConstants.scala +++ b/webapi/src/main/scala/org/knora/webapi/messages/OntologyConstants.scala @@ -789,8 +789,9 @@ object OntologyConstants { val LinkValueHasSource: IRI = KnoraApiV2PrefixExpansion + "linkValueHasSource" val LinkValueHasSourceIri: IRI = KnoraApiV2PrefixExpansion + "linkValueHasSourceIri" - val FileValueAsUrl: IRI = KnoraApiV2PrefixExpansion + "fileValueAsUrl" - val FileValueHasFilename: IRI = KnoraApiV2PrefixExpansion + "fileValueHasFilename" + val FileValueAsUrl: IRI = KnoraApiV2PrefixExpansion + "fileValueAsUrl" + val FileValueHasFilename: IRI = KnoraApiV2PrefixExpansion + "fileValueHasFilename" + // deprecated, use StillImageFileValueHasExternalUrl instead val FileValueHasExternalUrl: IRI = KnoraApiV2PrefixExpansion + "fileValueHasExternalUrl" val StillImageFileValueHasDimX: IRI = KnoraApiV2PrefixExpansion + "stillImageFileValueHasDimX" diff --git a/webapi/src/main/scala/org/knora/webapi/messages/util/rdf/JsonLDUtil.scala b/webapi/src/main/scala/org/knora/webapi/messages/util/rdf/JsonLDUtil.scala index 677d5c5bed..5f4c9ff85b 100644 --- a/webapi/src/main/scala/org/knora/webapi/messages/util/rdf/JsonLDUtil.scala +++ b/webapi/src/main/scala/org/knora/webapi/messages/util/rdf/JsonLDUtil.scala @@ -549,6 +549,24 @@ case class JsonLDObject(value: Map[String, JsonLDValue]) extends JsonLDValue { case None => Left(s"No $key provided") } + /** + * Gets a required String value by checking the provided property keys in order. + * @param keys The names of the properties to check in the JSON-LD object. + * @return the [[String]] value for the first key where it exists, + * fails if the given key exists but is not a [[JsonLDString]], + * fails if none of the keys exist. + */ + def getRequiredString(keys: String*): Either[String, String] = + keys.collectFirst { + case key if getString(key).exists(_.nonEmpty) => + getString(key) match + case Right(Some(str)) => str + case _ => "" // unreachable + } match { + case Some(str) => Right(str) + case None => Left(s"Property not found for '${keys.mkString(" or ")}'") + } + /** * Gets an optional string value of a property of this JSON-LD object, throwing * [[BadRequestException]] if the property's value is not a string. Parses the value with the specified validation diff --git a/webapi/src/main/scala/org/knora/webapi/messages/v2/responder/valuemessages/ValueMessagesV2.scala b/webapi/src/main/scala/org/knora/webapi/messages/v2/responder/valuemessages/ValueMessagesV2.scala index 5cb61e54ec..d6a76939fd 100644 --- a/webapi/src/main/scala/org/knora/webapi/messages/v2/responder/valuemessages/ValueMessagesV2.scala +++ b/webapi/src/main/scala/org/knora/webapi/messages/v2/responder/valuemessages/ValueMessagesV2.scala @@ -2805,13 +2805,16 @@ case class StillImageExternalFileValueContentV2( * Constructs [[StillImageFileValueContentV2]] objects based on JSON-LD input. */ object StillImageExternalFileValueContentV2 { + def fromJsonLdObject( jsonLDObject: JsonLDObject, ): ZIO[StringFormatter, Throwable, StillImageExternalFileValueContentV2] = for { - comment <- JsonLDUtil.getComment(jsonLDObject) - externalUrlEither = jsonLDObject.getRequiredString(FileValueHasExternalUrl).flatMap(IiifImageRequestUrl.from) - externalUrl <- ZIO.fromEither(externalUrlEither).mapError(BadRequestException.apply) + comment <- JsonLDUtil.getComment(jsonLDObject) + externalUrlEither = jsonLDObject + .getRequiredString(StillImageFileValueHasExternalUrl, FileValueHasExternalUrl) + .flatMap(IiifImageRequestUrl.from) + externalUrl <- ZIO.fromEither(externalUrlEither).mapError(BadRequestException.apply) } yield StillImageExternalFileValueContentV2( ontologySchema = ApiV2Complex, fileValue = FileValueV2( diff --git a/webapi/src/test/scala/org/knora/webapi/messages/util/rdf/JsonLDObjectSpec.scala b/webapi/src/test/scala/org/knora/webapi/messages/util/rdf/JsonLDObjectSpec.scala index c42c252f7d..e1f1d90ee5 100644 --- a/webapi/src/test/scala/org/knora/webapi/messages/util/rdf/JsonLDObjectSpec.scala +++ b/webapi/src/test/scala/org/knora/webapi/messages/util/rdf/JsonLDObjectSpec.scala @@ -158,6 +158,12 @@ object JsonLDObjectSpec extends ZIOSpecDefault { test("getRequiredString should fail with correct message") { assertTrue(emptyJsonLdObject.getRequiredString(someKey) == Left("No someKey provided")) }, + test("getRequiredString(key*) should fail with correct message") { + assertTrue( + emptyJsonLdObject.getRequiredString(Array(someKey)*) == Left(s"Property not found for '$someKey'"), + emptyJsonLdObject.getRequiredString("unknown", someKey) == Left(s"Property not found for 'unknown or $someKey'"), + ) + }, ) def stringValueWhenGivenValidString: Spec[Any, Serializable] = { @@ -178,6 +184,12 @@ object JsonLDObjectSpec extends ZIOSpecDefault { test("getRequiredString should return correct value") { assertTrue(jsonLdObject.getRequiredString(someKey) == Right(someString)) }, + test("getRequiredString(key*) should return correct value") { + assertTrue( + jsonLdObject.getRequiredString("unknown", someKey) == Right(someString), + jsonLdObject.getRequiredString(someKey, "unknown") == Right(someString), + ) + }, ) }