From 300b83c3db2eb56003c948aa41617b630642579e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20Kleinb=C3=B6lting?=
Date: Fri, 15 Nov 2024 12:45:54 +0100
Subject: [PATCH 01/18] add properties to knora base and admin ontologies
---
.../knora-ontologies/knora-admin.ttl | 18 ++++++++++-----
.../resources/knora-ontologies/knora-base.ttl | 23 +++++++++++++++++--
.../main/scala/org/knora/webapi/package.scala | 2 +-
3 files changed, 34 insertions(+), 9 deletions(-)
diff --git a/webapi/src/main/resources/knora-ontologies/knora-admin.ttl b/webapi/src/main/resources/knora-ontologies/knora-admin.ttl
index 5e291d0e58..5368c6e3f7 100644
--- a/webapi/src/main/resources/knora-ontologies/knora-admin.ttl
+++ b/webapi/src/main/resources/knora-ontologies/knora-admin.ttl
@@ -377,12 +377,18 @@
[ rdf:type owl:Restriction ;
owl:onProperty :projectRestrictedViewWatermark ;
owl:maxCardinality "1"^^xsd:nonNegativeInteger ],
- [ rdf:type owl:Restriction ;
- owl:onProperty :status ;
- owl:cardinality "1"^^xsd:nonNegativeInteger ],
- [ rdf:type owl:Restriction ;
- owl:onProperty :hasSelfJoinEnabled ;
- owl:cardinality "1"^^xsd:nonNegativeInteger ] ;
+ [ rdf:type owl:Restriction ;
+ owl:onProperty :status ;
+ owl:cardinality "1"^^xsd:nonNegativeInteger ],
+ [ rdf:type owl:Restriction ;
+ owl:onProperty :hasSelfJoinEnabled ;
+ owl:cardinality "1"^^xsd:nonNegativeInteger ],
+ [ rdf:type owl:Restriction ;
+ owl:onProperty knora-base:hasCopyrightAttribution ;
+ owl:maxCardinality "1"^^xsd:nonNegativeInteger ],
+ [ rdf:type owl:Restriction ;
+ owl:onProperty knora-base:hasLicense ;
+ owl:maxCardinality "1"^^xsd:nonNegativeInteger ];
rdfs:comment "Represents a project that uses Knora."@en .
diff --git a/webapi/src/main/resources/knora-ontologies/knora-base.ttl b/webapi/src/main/resources/knora-ontologies/knora-base.ttl
index ac026f6bf5..3e976e6513 100644
--- a/webapi/src/main/resources/knora-ontologies/knora-base.ttl
+++ b/webapi/src/main/resources/knora-ontologies/knora-base.ttl
@@ -20,7 +20,7 @@
rdf:type owl:Ontology ;
rdfs:label "The Knora base ontology"@en ;
:attachedToProject knora-admin:SystemProject ;
- :ontologyVersion "knora-base v41" .
+ :ontologyVersion "knora-base v42" .
#################################################################
@@ -527,6 +527,19 @@
:subjectClassConstraint :Resource ;
:objectClassConstraint :Value .
+### http://www.knora.org/ontology/knora-base#hasCopyrightAttribution
+
+:hasCopyrightAttribution
+ rdf:type owl:DatatypeProperty ;
+ rdfs:comment "The copyright statement that gives credit to the original author."@en ;
+ :objectDatatypeConstraint xsd:string .
+
+### http://www.knora.org/ontology/knora-base#hasLicense
+
+:hasLicense
+ rdf:type owl:DatatypeProperty ;
+ rdfs:comment "Specifies the terms under which a work can be used. This statement may be a reference to a well-known license, such as Creative Commons (e.g. 'CC BY-SA') or a custom license."@en ;
+ :objectDatatypeConstraint xsd:string .
### http://www.knora.org/ontology/knora-base#isAnnotationOf
@@ -1479,7 +1492,13 @@
owl:maxCardinality "1"^^xsd:nonNegativeInteger ],
[ rdf:type owl:Restriction ;
owl:onProperty :originalMimeType ;
- owl:maxCardinality "1"^^xsd:nonNegativeInteger ] .
+ owl:maxCardinality "1"^^xsd:nonNegativeInteger ],
+ [ rdf:type owl:Restriction ;
+ owl:onProperty :hasCopyrightAttribution ;
+ owl:maxCardinality "1"^^xsd:nonNegativeInteger ],
+ [ rdf:type owl:Restriction ;
+ owl:onProperty :hasLicense ;
+ owl:maxCardinality "1"^^xsd:nonNegativeInteger ].
### http://www.knora.org/ontology/knora-base#DecimalBase
diff --git a/webapi/src/main/scala/org/knora/webapi/package.scala b/webapi/src/main/scala/org/knora/webapi/package.scala
index ebe9fca3d4..0e40b8f2d7 100644
--- a/webapi/src/main/scala/org/knora/webapi/package.scala
+++ b/webapi/src/main/scala/org/knora/webapi/package.scala
@@ -14,7 +14,7 @@ package object webapi {
* The version of `knora-base` and of the other built-in ontologies that this version of Knora requires.
* Must be the same as the object of `knora-base:ontologyVersion` in the `knora-base` ontology being used.
*/
- val KnoraBaseVersion: Int = 41
+ val KnoraBaseVersion: Int = 42
val KnoraBaseVersionString: String = s"$versionPrefix$KnoraBaseVersion"
/**
From 102cac0441d6d65d4ca0426e8100b3d7e6273b3f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20Kleinb=C3=B6lting?=
Date: Fri, 15 Nov 2024 12:50:14 +0100
Subject: [PATCH 02/18] sort lines
---
...aseToApiV2ComplexTransformationRules.scala | 102 +++++++++---------
1 file changed, 51 insertions(+), 51 deletions(-)
diff --git a/webapi/src/main/scala/org/knora/webapi/messages/v2/responder/ontologymessages/KnoraBaseToApiV2ComplexTransformationRules.scala b/webapi/src/main/scala/org/knora/webapi/messages/v2/responder/ontologymessages/KnoraBaseToApiV2ComplexTransformationRules.scala
index 0801f609e1..4987cdf5ee 100644
--- a/webapi/src/main/scala/org/knora/webapi/messages/v2/responder/ontologymessages/KnoraBaseToApiV2ComplexTransformationRules.scala
+++ b/webapi/src/main/scala/org/knora/webapi/messages/v2/responder/ontologymessages/KnoraBaseToApiV2ComplexTransformationRules.scala
@@ -625,70 +625,70 @@ object KnoraBaseToApiV2ComplexTransformationRules extends OntologyTransformation
* See also [[OntologyConstants.CorrespondingIris]].
*/
override val externalPropertiesToAdd: Map[SmartIri, ReadPropertyInfoV2] = Set(
- Label,
- Result,
- MayHaveMoreResults,
- Error,
- CanDo,
- UserHasPermission,
- VersionDate,
ArkUrl,
- VersionArkUrl,
Author,
- IsShared,
- IsBuiltIn,
- IsResourceClass,
- IsStandoffClass,
- IsValueClass,
- IsEditable,
- IsLinkProperty,
- IsLinkValueProperty,
- IsInherited,
- NewModificationDate,
- OntologyName,
- MappingHasName,
- ValueAsString,
- HasIncomingLinkValue,
- SubjectType,
- ObjectType,
- TextValueHasMarkup,
- TextValueHasStandoff,
- TextValueHasMaxStandoffStartIndex,
- NextStandoffStartIndex,
- StandoffTagHasStartParentIndex,
- StandoffTagHasEndParentIndex,
- TextValueHasLanguage,
- TextValueAsXml,
- TextValueAsHtml,
- TextValueHasMapping,
- DateValueHasStartYear,
- DateValueHasEndYear,
- DateValueHasStartMonth,
+ BooleanValueAsBoolean,
+ CanDo,
+ ColorValueAsColor,
+ DateValueHasCalendar,
+ DateValueHasEndDay,
+ DateValueHasEndEra,
DateValueHasEndMonth,
+ DateValueHasEndYear,
DateValueHasStartDay,
- DateValueHasEndDay,
DateValueHasStartEra,
- DateValueHasEndEra,
- DateValueHasCalendar,
- IntervalValueHasStart,
+ DateValueHasStartMonth,
+ DateValueHasStartYear,
+ DecimalValueAsDecimal,
+ Error,
+ FileValueAsUrl,
+ FileValueHasFilename,
+ GeometryValueAsGeometry,
+ GeonameValueAsGeonameCode,
+ HasIncomingLinkValue,
+ IntValueAsInt,
IntervalValueHasEnd,
+ IntervalValueHasStart,
+ IsBuiltIn,
+ IsEditable,
+ IsInherited,
+ IsLinkProperty,
+ IsLinkValueProperty,
+ IsResourceClass,
+ IsShared,
+ IsStandoffClass,
+ IsValueClass,
+ Label,
LinkValueHasSource,
LinkValueHasSourceIri,
LinkValueHasTarget,
LinkValueHasTargetIri,
- IntValueAsInt,
- DecimalValueAsDecimal,
- BooleanValueAsBoolean,
- GeometryValueAsGeometry,
ListValueAsListNode,
- ColorValueAsColor,
- UriValueAsUri,
- GeonameValueAsGeonameCode,
- FileValueAsUrl,
- FileValueHasFilename,
+ MappingHasName,
+ MayHaveMoreResults,
+ NewModificationDate,
+ NextStandoffStartIndex,
+ ObjectType,
+ OntologyName,
+ Result,
+ StandoffTagHasEndParentIndex,
+ StandoffTagHasStartParentIndex,
StillImageFileValueHasDimX,
StillImageFileValueHasDimY,
- StillImageFileValueHasIIIFBaseUrl,
StillImageFileValueHasExternalUrl,
+ StillImageFileValueHasIIIFBaseUrl,
+ SubjectType,
+ TextValueAsHtml,
+ TextValueAsXml,
+ TextValueHasLanguage,
+ TextValueHasMapping,
+ TextValueHasMarkup,
+ TextValueHasMaxStandoffStartIndex,
+ TextValueHasStandoff,
+ UriValueAsUri,
+ UserHasPermission,
+ ValueAsString,
+ VersionArkUrl,
+ VersionDate,
).map(_.build()).map(info => info.entityInfoContent.propertyIri -> info).toMap
}
From fbd579e5dd918ab4283f62f7a550db16c040ec88 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20Kleinb=C3=B6lting?=
Date: Fri, 15 Nov 2024 13:06:59 +0100
Subject: [PATCH 03/18] add to knora-api v2
---
.../webapi/messages/OntologyConstants.scala | 38 ++++++++++---------
...aseToApiV2ComplexTransformationRules.scala | 12 ++++++
2 files changed, 33 insertions(+), 17 deletions(-)
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 37fa73df89..ed6fc1db1e 100644
--- a/webapi/src/main/scala/org/knora/webapi/messages/OntologyConstants.scala
+++ b/webapi/src/main/scala/org/knora/webapi/messages/OntologyConstants.scala
@@ -263,6 +263,8 @@ object OntologyConstants {
val HasTextFileValue: IRI = KnoraBasePrefixExpansion + "hasTextFileValue"
val HasDocumentFileValue: IRI = KnoraBasePrefixExpansion + "hasDocumentFileValue"
val HasArchiveFileValue: IRI = KnoraBasePrefixExpansion + "hasArchiveFileValue"
+ val HasCopyrightAttribution: IRI = KnoraBasePrefixExpansion + "hasCopyrightAttribution"
+ val HasLicense: IRI = KnoraBasePrefixExpansion + "hasLicense"
val ResourceIcon: IRI = KnoraBasePrefixExpansion + "resourceIcon"
@@ -617,23 +619,25 @@ object OntologyConstants {
val ValueHasComment: IRI = KnoraApiV2PrefixExpansion + "valueHasComment"
val NewValueVersionIri: IRI = KnoraApiV2PrefixExpansion + "newValueVersionIri"
- val User: IRI = KnoraApiV2PrefixExpansion + "User"
- val AttachedToUser: IRI = KnoraApiV2PrefixExpansion + "attachedToUser"
- val AttachedToProject: IRI = KnoraApiV2PrefixExpansion + "attachedToProject"
- val HasStandoffLinkTo: IRI = KnoraApiV2PrefixExpansion + "hasStandoffLinkTo"
- val HasStandoffLinkToValue: IRI = KnoraApiV2PrefixExpansion + "hasStandoffLinkToValue"
- val HasPermissions: IRI = KnoraApiV2PrefixExpansion + "hasPermissions"
- val UserHasPermission: String = KnoraApiV2PrefixExpansion + "userHasPermission"
- val CreationDate: IRI = KnoraApiV2PrefixExpansion + "creationDate"
- val LastModificationDate: IRI = KnoraApiV2PrefixExpansion + "lastModificationDate"
- val VersionDate: IRI = KnoraApiV2PrefixExpansion + "versionDate"
- val NewModificationDate: IRI = KnoraApiV2PrefixExpansion + "newModificationDate"
- val IsDeleted: IRI = KnoraApiV2PrefixExpansion + "isDeleted"
- val DeleteDate: IRI = KnoraApiV2PrefixExpansion + "deleteDate"
- val DeleteComment: IRI = KnoraApiV2PrefixExpansion + "deleteComment"
- val ArkUrl: IRI = KnoraApiV2PrefixExpansion + "arkUrl"
- val VersionArkUrl: IRI = KnoraApiV2PrefixExpansion + "versionArkUrl"
- val Author: IRI = KnoraApiV2PrefixExpansion + "author"
+ val User: IRI = KnoraApiV2PrefixExpansion + "User"
+ val AttachedToUser: IRI = KnoraApiV2PrefixExpansion + "attachedToUser"
+ val AttachedToProject: IRI = KnoraApiV2PrefixExpansion + "attachedToProject"
+ val HasStandoffLinkTo: IRI = KnoraApiV2PrefixExpansion + "hasStandoffLinkTo"
+ val HasStandoffLinkToValue: IRI = KnoraApiV2PrefixExpansion + "hasStandoffLinkToValue"
+ val HasPermissions: IRI = KnoraApiV2PrefixExpansion + "hasPermissions"
+ val HasCopyrightAttribution: IRI = KnoraApiV2PrefixExpansion + "hasCopyrightAttribution"
+ val HasLicense: IRI = KnoraApiV2PrefixExpansion + "hasLicense"
+ val UserHasPermission: String = KnoraApiV2PrefixExpansion + "userHasPermission"
+ val CreationDate: IRI = KnoraApiV2PrefixExpansion + "creationDate"
+ val LastModificationDate: IRI = KnoraApiV2PrefixExpansion + "lastModificationDate"
+ val VersionDate: IRI = KnoraApiV2PrefixExpansion + "versionDate"
+ val NewModificationDate: IRI = KnoraApiV2PrefixExpansion + "newModificationDate"
+ val IsDeleted: IRI = KnoraApiV2PrefixExpansion + "isDeleted"
+ val DeleteDate: IRI = KnoraApiV2PrefixExpansion + "deleteDate"
+ val DeleteComment: IRI = KnoraApiV2PrefixExpansion + "deleteComment"
+ val ArkUrl: IRI = KnoraApiV2PrefixExpansion + "arkUrl"
+ val VersionArkUrl: IRI = KnoraApiV2PrefixExpansion + "versionArkUrl"
+ val Author: IRI = KnoraApiV2PrefixExpansion + "author"
val Resource: IRI = KnoraApiV2PrefixExpansion + "Resource"
val DeletedResource: IRI = KnoraApiV2PrefixExpansion + "DeletedResource"
diff --git a/webapi/src/main/scala/org/knora/webapi/messages/v2/responder/ontologymessages/KnoraBaseToApiV2ComplexTransformationRules.scala b/webapi/src/main/scala/org/knora/webapi/messages/v2/responder/ontologymessages/KnoraBaseToApiV2ComplexTransformationRules.scala
index 4987cdf5ee..c28fa904fa 100644
--- a/webapi/src/main/scala/org/knora/webapi/messages/v2/responder/ontologymessages/KnoraBaseToApiV2ComplexTransformationRules.scala
+++ b/webapi/src/main/scala/org/knora/webapi/messages/v2/responder/ontologymessages/KnoraBaseToApiV2ComplexTransformationRules.scala
@@ -152,6 +152,16 @@ object KnoraBaseToApiV2ComplexTransformationRules extends OntologyTransformation
.withIsResourceProp()
.withIsLinkValueProp()
+ private val HasCopyrightAttribution = makeOwlDatatypeProperty(KA.HasCopyrightAttribution, XSD.STRING)
+ .withRdfLabelEn("has copyright attribution")
+ .withRdfCommentEn("The copyright statement that gives credit to the original author.")
+
+ private val HasLicense = makeOwlDatatypeProperty(KA.HasLicense, XSD.STRING)
+ .withRdfLabelEn("has copyright attribution")
+ .withRdfCommentEn(
+ "Specifies the terms under which a work can be used. This statement may be a reference to a well-known license, such as Creative Commons (e.g. CC BY-SA) or a custom license.",
+ )
+
private val ValueAsString = makeOwlDatatypeProperty(KA.ValueAsString, XSD.STRING)
.withSubjectType(KA.Value)
.withRdfCommentEn("A plain string representation of a value")
@@ -645,7 +655,9 @@ object KnoraBaseToApiV2ComplexTransformationRules extends OntologyTransformation
FileValueHasFilename,
GeometryValueAsGeometry,
GeonameValueAsGeonameCode,
+ HasCopyrightAttribution,
HasIncomingLinkValue,
+ HasLicense,
IntValueAsInt,
IntervalValueHasEnd,
IntervalValueHasStart,
From d7e1ec18f9847ff70cea1cd06ae0b63d0cb47d96 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20Kleinb=C3=B6lting?=
Date: Fri, 15 Nov 2024 14:09:26 +0100
Subject: [PATCH 04/18] feat: Add copyright attribution and license to Project
---
.../org/knora/webapi/ProjectEraseIT.scala | 2 ++
.../IntegrationTestAdminJsonProtocol.scala | 2 ++
.../admin/ProjectRestServiceSpec.scala | 15 ++++++++-
.../sharedtestdata/SharedTestDataADM.scala | 20 ++++++++++++
.../webapi/slice/admin/api/Examples.scala | 2 ++
...rojectsEndpointsRequestsAndResponses.scala | 2 ++
.../admin/api/model/ProjectsMessagesADM.scala | 2 ++
.../admin/domain/model/KnoraProject.scala | 2 ++
.../domain/service/KnoraProjectRepo.scala | 2 ++
.../domain/service/KnoraProjectService.scala | 2 ++
.../admin/domain/service/ProjectService.scala | 4 +++
.../repo/service/KnoraProjectRepoLive.scala | 32 +++++++++++++------
.../slice/common/repo/rdf/Vocabulary.scala | 2 ++
.../org/knora/webapi/TestDataFactory.scala | 2 ++
.../domain/service/ProjectServiceSpec.scala | 4 +++
.../service/KnoraProjectRepoLiveSpec.scala | 8 +++--
16 files changed, 90 insertions(+), 13 deletions(-)
diff --git a/integration/src/test/scala/org/knora/webapi/ProjectEraseIT.scala b/integration/src/test/scala/org/knora/webapi/ProjectEraseIT.scala
index dfd542331a..aaee0bc1fd 100644
--- a/integration/src/test/scala/org/knora/webapi/ProjectEraseIT.scala
+++ b/integration/src/test/scala/org/knora/webapi/ProjectEraseIT.scala
@@ -83,6 +83,8 @@ object ProjectEraseIT extends E2EZSpec {
None,
KnoraProject.Status.Active,
KnoraProject.SelfJoin.CanJoin,
+ None,
+ None,
),
),
).orDie
diff --git a/integration/src/test/scala/org/knora/webapi/messages/admin/responder/IntegrationTestAdminJsonProtocol.scala b/integration/src/test/scala/org/knora/webapi/messages/admin/responder/IntegrationTestAdminJsonProtocol.scala
index fd36ebe999..c0efc1325f 100644
--- a/integration/src/test/scala/org/knora/webapi/messages/admin/responder/IntegrationTestAdminJsonProtocol.scala
+++ b/integration/src/test/scala/org/knora/webapi/messages/admin/responder/IntegrationTestAdminJsonProtocol.scala
@@ -189,6 +189,8 @@ object IntegrationTestAdminJsonProtocol extends TriplestoreJsonProtocol {
"ontologies",
"status",
"selfjoin",
+ "copyrightAttribution",
+ "license",
),
)
diff --git a/integration/src/test/scala/org/knora/webapi/responders/admin/ProjectRestServiceSpec.scala b/integration/src/test/scala/org/knora/webapi/responders/admin/ProjectRestServiceSpec.scala
index 945c7126b4..b250f5f43d 100644
--- a/integration/src/test/scala/org/knora/webapi/responders/admin/ProjectRestServiceSpec.scala
+++ b/integration/src/test/scala/org/knora/webapi/responders/admin/ProjectRestServiceSpec.scala
@@ -162,6 +162,8 @@ class ProjectRestServiceSpec extends CoreSpec with ImplicitSender {
logo = Some(Logo.unsafeFrom("/fu/bar/baz.jpg")),
status = Status.Active,
selfjoin = SelfJoin.CannotJoin,
+ copyrightAttribution = Some("2024, Example Project"),
+ license = Some("CC-BY-4.0"),
),
SharedTestDataADM.rootUser,
),
@@ -174,6 +176,8 @@ class ProjectRestServiceSpec extends CoreSpec with ImplicitSender {
received.project.description should be(
Seq(StringLiteralV2.from(value = "project description", language = Some("en"))),
)
+ received.project.copyrightAttribution should be(Some("2024, Example Project"))
+ received.project.license should be(Some("CC-BY-4.0"))
newProjectIri.set(received.project.id)
@@ -257,6 +261,8 @@ class ProjectRestServiceSpec extends CoreSpec with ImplicitSender {
logo = Some(Logo.unsafeFrom("/fu/bar/baz.jpg")),
status = Status.Active,
selfjoin = SelfJoin.CannotJoin,
+ None,
+ None,
),
SharedTestDataADM.rootUser,
),
@@ -269,7 +275,8 @@ class ProjectRestServiceSpec extends CoreSpec with ImplicitSender {
received.project.description should be(
Seq(StringLiteralV2.from(value = "project description", language = Some("en"))),
)
-
+ received.project.copyrightAttribution should be(None)
+ received.project.license should be(None)
}
"CREATE a project that its info has special characters" in {
@@ -292,6 +299,8 @@ class ProjectRestServiceSpec extends CoreSpec with ImplicitSender {
logo = Some(Logo.unsafeFrom("/fu/bar/baz.jpg")),
status = Status.Active,
selfjoin = SelfJoin.CannotJoin,
+ None,
+ None,
),
SharedTestDataADM.rootUser,
),
@@ -324,6 +333,8 @@ class ProjectRestServiceSpec extends CoreSpec with ImplicitSender {
logo = Some(Logo.unsafeFrom("/fu/bar/baz.jpg")),
status = Status.Active,
selfjoin = SelfJoin.CannotJoin,
+ copyrightAttribution = None,
+ license = None,
),
SharedTestDataADM.rootUser,
),
@@ -346,6 +357,8 @@ class ProjectRestServiceSpec extends CoreSpec with ImplicitSender {
logo = Some(Logo.unsafeFrom("/fu/bar/baz.jpg")),
status = Status.Active,
selfjoin = SelfJoin.CannotJoin,
+ copyrightAttribution = None,
+ license = None,
),
SharedTestDataADM.rootUser,
),
diff --git a/integration/src/test/scala/org/knora/webapi/sharedtestdata/SharedTestDataADM.scala b/integration/src/test/scala/org/knora/webapi/sharedtestdata/SharedTestDataADM.scala
index f40a35403f..b4e11edcc4 100644
--- a/integration/src/test/scala/org/knora/webapi/sharedtestdata/SharedTestDataADM.scala
+++ b/integration/src/test/scala/org/knora/webapi/sharedtestdata/SharedTestDataADM.scala
@@ -169,6 +169,8 @@ object SharedTestDataADM {
),
status = true,
selfjoin = false,
+ copyrightAttribution = None,
+ license = None,
)
/* represents the full ProjectADM of the default shared ontologies project */
@@ -183,6 +185,8 @@ object SharedTestDataADM {
ontologies = Seq.empty[IRI],
status = true,
selfjoin = false,
+ copyrightAttribution = None,
+ license = None,
)
/**
@@ -295,6 +299,8 @@ object SharedTestDataADM {
ontologies = Seq(SharedOntologyTestDataADM.IMAGES_ONTOLOGY_IRI),
status = true,
selfjoin = false,
+ copyrightAttribution = None,
+ license = None,
)
/* represents the full ProjectADM of the images project in the external format */
@@ -309,6 +315,8 @@ object SharedTestDataADM {
ontologies = Seq(SharedOntologyTestDataADM.IMAGES_ONTOLOGY_IRI_LocalHost),
status = true,
selfjoin = false,
+ copyrightAttribution = None,
+ license = None,
)
/* represents the full GroupADM of the images ProjectAdmin group */
@@ -472,6 +480,8 @@ object SharedTestDataADM {
ontologies = Seq(SharedOntologyTestDataADM.INCUNABULA_ONTOLOGY_IRI),
status = true,
selfjoin = false,
+ copyrightAttribution = None,
+ license = None,
)
/* represents the ProjectADM of the incunabula project in the external format*/
@@ -507,6 +517,8 @@ object SharedTestDataADM {
ontologies = Seq(SharedOntologyTestDataADM.INCUNABULA_ONTOLOGY_IRI_LocalHost),
status = true,
selfjoin = false,
+ copyrightAttribution = None,
+ license = None,
)
/**
@@ -619,6 +631,8 @@ object SharedTestDataADM {
ontologies = Seq(SharedOntologyTestDataADM.ANYTHING_ONTOLOGY_IRI, SharedOntologyTestDataADM.SomethingOntologyIri),
status = true,
selfjoin = false,
+ copyrightAttribution = None,
+ license = None,
)
def anythingProjectExternal: Project = Project(
@@ -635,6 +649,8 @@ object SharedTestDataADM {
),
status = true,
selfjoin = false,
+ copyrightAttribution = None,
+ license = None,
)
/* represents the full GroupADM of the Thing searcher group */
@@ -672,6 +688,8 @@ object SharedTestDataADM {
),
status = true,
selfjoin = false,
+ copyrightAttribution = None,
+ license = None,
)
/* represents the user profile of 'superuser' as found in admin-data.ttl */
@@ -721,5 +739,7 @@ object SharedTestDataADM {
ontologies = Seq("http://www.knora.org/ontology/0804/dokubib"),
status = false,
selfjoin = false,
+ copyrightAttribution = None,
+ license = None,
)
}
diff --git a/webapi/src/main/scala/org/knora/webapi/slice/admin/api/Examples.scala b/webapi/src/main/scala/org/knora/webapi/slice/admin/api/Examples.scala
index f669607840..45737e59cd 100644
--- a/webapi/src/main/scala/org/knora/webapi/slice/admin/api/Examples.scala
+++ b/webapi/src/main/scala/org/knora/webapi/slice/admin/api/Examples.scala
@@ -93,6 +93,8 @@ object Examples {
status = true,
ontologies = Seq.empty,
selfjoin = false,
+ copyrightAttribution = Some("2024, Example Project"),
+ license = Some("CC-BY-4.0"),
)
private val group = Group(
diff --git a/webapi/src/main/scala/org/knora/webapi/slice/admin/api/model/ProjectsEndpointsRequestsAndResponses.scala b/webapi/src/main/scala/org/knora/webapi/slice/admin/api/model/ProjectsEndpointsRequestsAndResponses.scala
index 89b8bce775..ad9bca8bd8 100644
--- a/webapi/src/main/scala/org/knora/webapi/slice/admin/api/model/ProjectsEndpointsRequestsAndResponses.scala
+++ b/webapi/src/main/scala/org/knora/webapi/slice/admin/api/model/ProjectsEndpointsRequestsAndResponses.scala
@@ -27,6 +27,8 @@ object ProjectsEndpointsRequestsAndResponses {
logo: Option[Logo] = None,
status: Status,
selfjoin: SelfJoin,
+ copyrightAttribution: Option[String],
+ license: Option[String],
)
object ProjectCreateRequest {
implicit val codec: JsonCodec[ProjectCreateRequest] = DeriveJsonCodec.gen[ProjectCreateRequest]
diff --git a/webapi/src/main/scala/org/knora/webapi/slice/admin/api/model/ProjectsMessagesADM.scala b/webapi/src/main/scala/org/knora/webapi/slice/admin/api/model/ProjectsMessagesADM.scala
index dcb3b218f2..c2c4dcdfff 100644
--- a/webapi/src/main/scala/org/knora/webapi/slice/admin/api/model/ProjectsMessagesADM.scala
+++ b/webapi/src/main/scala/org/knora/webapi/slice/admin/api/model/ProjectsMessagesADM.scala
@@ -40,6 +40,8 @@ case class Project(
ontologies: Seq[IRI],
status: Boolean,
selfjoin: Boolean,
+ copyrightAttribution: Option[String],
+ license: Option[String],
) extends Ordered[Project] {
def projectIri: ProjectIri = ProjectIri.unsafeFrom(id)
diff --git a/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/model/KnoraProject.scala b/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/model/KnoraProject.scala
index 42889abb00..e3771c5802 100644
--- a/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/model/KnoraProject.scala
+++ b/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/model/KnoraProject.scala
@@ -34,6 +34,8 @@ case class KnoraProject(
status: Status,
selfjoin: SelfJoin,
restrictedView: RestrictedView,
+ copyrightAttribution: Option[String],
+ license: Option[String],
) extends EntityWithId[ProjectIri]
object KnoraProject {
diff --git a/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/service/KnoraProjectRepo.scala b/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/service/KnoraProjectRepo.scala
index 0e231dce98..2d82da3468 100644
--- a/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/service/KnoraProjectRepo.scala
+++ b/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/service/KnoraProjectRepo.scala
@@ -47,6 +47,8 @@ object KnoraProjectRepo {
KnoraProject.Status.Active,
KnoraProject.SelfJoin.CannotJoin,
RestrictedView.default,
+ None,
+ None,
)
val SystemProject: KnoraProject = makeBuiltIn(
diff --git a/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/service/KnoraProjectService.scala b/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/service/KnoraProjectService.scala
index 9c3837ecf5..9a05ca32c4 100644
--- a/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/service/KnoraProjectService.scala
+++ b/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/service/KnoraProjectService.scala
@@ -52,6 +52,8 @@ final case class KnoraProjectService(knoraProjectRepo: KnoraProjectRepo, ontolog
req.status,
req.selfjoin,
RestrictedView.default,
+ req.copyrightAttribution,
+ req.license,
)
project <- knoraProjectRepo.save(project)
} yield project
diff --git a/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/service/ProjectService.scala b/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/service/ProjectService.scala
index 82a2db205a..e4af95ef9c 100644
--- a/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/service/ProjectService.scala
+++ b/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/service/ProjectService.scala
@@ -56,6 +56,8 @@ final case class ProjectService(
ontologies,
knoraProject.status.value,
knoraProject.selfjoin.value,
+ knoraProject.copyrightAttribution,
+ knoraProject.license,
),
)
@@ -73,6 +75,8 @@ final case class ProjectService(
status = Status.from(project.status),
selfjoin = SelfJoin.from(project.selfjoin),
restrictedView,
+ project.copyrightAttribution,
+ project.license,
)
def setProjectRestrictedView(project: Project, settings: RestrictedView): Task[RestrictedView] =
diff --git a/webapi/src/main/scala/org/knora/webapi/slice/admin/repo/service/KnoraProjectRepoLive.scala b/webapi/src/main/scala/org/knora/webapi/slice/admin/repo/service/KnoraProjectRepoLive.scala
index 045cc486a4..8c9336c874 100644
--- a/webapi/src/main/scala/org/knora/webapi/slice/admin/repo/service/KnoraProjectRepoLive.scala
+++ b/webapi/src/main/scala/org/knora/webapi/slice/admin/repo/service/KnoraProjectRepoLive.scala
@@ -14,6 +14,8 @@ import zio.*
import org.knora.webapi.messages.OntologyConstants.KnoraAdmin
import org.knora.webapi.messages.OntologyConstants.KnoraAdmin.*
+import org.knora.webapi.messages.OntologyConstants.KnoraBase.HasCopyrightAttribution
+import org.knora.webapi.messages.OntologyConstants.KnoraBase.HasLicense
import org.knora.webapi.slice.admin.domain.model.KnoraProject
import org.knora.webapi.slice.admin.domain.model.KnoraProject.*
import org.knora.webapi.slice.admin.domain.model.RestrictedView
@@ -48,6 +50,8 @@ final case class KnoraProjectRepoLive(
Vocabulary.KnoraAdmin.projectLongname,
Vocabulary.KnoraAdmin.projectRestrictedViewSize,
Vocabulary.KnoraAdmin.projectRestrictedViewWatermark,
+ Vocabulary.KnoraBase.hasCopyrightAttribution,
+ Vocabulary.KnoraBase.hasLicense,
),
)
@@ -91,16 +95,18 @@ object KnoraProjectRepoLive {
} yield size.orElse(watermark).getOrElse(RestrictedView.default)
for {
- iri <- resource.getSubjectIri
- shortcode <- resource.getStringLiteralOrFail[Shortcode](ProjectShortcode)
- shortname <- resource.getStringLiteralOrFail[Shortname](ProjectShortname)
- longname <- resource.getStringLiteral[Longname](ProjectLongname)
- description <- resource.getLangStringLiteralsOrFail[Description](ProjectDescription)
- keywords <- resource.getStringLiterals[Keyword](ProjectKeyword)
- logo <- resource.getStringLiteral[Logo](ProjectLogo)
- status <- resource.getBooleanLiteralOrFail[Status](StatusProp)
- selfjoin <- resource.getBooleanLiteralOrFail[SelfJoin](HasSelfJoinEnabled)
- restrictedView <- getRestrictedView
+ iri <- resource.getSubjectIri
+ shortcode <- resource.getStringLiteralOrFail[Shortcode](ProjectShortcode)
+ shortname <- resource.getStringLiteralOrFail[Shortname](ProjectShortname)
+ longname <- resource.getStringLiteral[Longname](ProjectLongname)
+ description <- resource.getLangStringLiteralsOrFail[Description](ProjectDescription)
+ keywords <- resource.getStringLiterals[Keyword](ProjectKeyword)
+ logo <- resource.getStringLiteral[Logo](ProjectLogo)
+ status <- resource.getBooleanLiteralOrFail[Status](StatusProp)
+ selfjoin <- resource.getBooleanLiteralOrFail[SelfJoin](HasSelfJoinEnabled)
+ copyrightAttribution <- resource.getStringLiteral[String](HasCopyrightAttribution)(Right(_))
+ license <- resource.getStringLiteral[String](HasLicense)(Right(_))
+ restrictedView <- getRestrictedView
} yield KnoraProject(
id = ProjectIri.unsafeFrom(iri.value),
shortcode = shortcode,
@@ -112,6 +118,8 @@ object KnoraProjectRepoLive {
status = status,
selfjoin = selfjoin,
restrictedView = restrictedView,
+ copyrightAttribution = copyrightAttribution,
+ license = license,
)
}
@@ -136,6 +144,10 @@ object KnoraProjectRepoLive {
case RestrictedView.Watermark(watermark) =>
pattern.andHas(Vocabulary.KnoraAdmin.projectRestrictedViewWatermark, watermark)
}
+
+ project.copyrightAttribution.foreach(attr => pattern.andHas(Vocabulary.KnoraBase.hasCopyrightAttribution, attr))
+ project.license.foreach(license => pattern.andHas(Vocabulary.KnoraBase.hasLicense, license))
+
pattern
}
}
diff --git a/webapi/src/main/scala/org/knora/webapi/slice/common/repo/rdf/Vocabulary.scala b/webapi/src/main/scala/org/knora/webapi/slice/common/repo/rdf/Vocabulary.scala
index 0e6d2097bc..471e2710a0 100644
--- a/webapi/src/main/scala/org/knora/webapi/slice/common/repo/rdf/Vocabulary.scala
+++ b/webapi/src/main/scala/org/knora/webapi/slice/common/repo/rdf/Vocabulary.scala
@@ -108,6 +108,8 @@ object Vocabulary {
val valueHasMapping: Iri = iri(kb + "valueHasMapping")
val valueHasMaxStandoffStartIndex: Iri = iri(kb + "valueHasMaxStandoffStartIndex")
val valueHasStandoff: Iri = iri(kb + "valueHasStandoff")
+ val hasCopyrightAttribution: Iri = iri(kb + "hasCopyrightAttribution")
+ val hasLicense: Iri = iri(kb + "hasLicense")
val internalFilename: Iri = iri(kb + "internalFilename")
val internalMimeType: Iri = iri(kb + "internalMimeType")
diff --git a/webapi/src/test/scala/org/knora/webapi/TestDataFactory.scala b/webapi/src/test/scala/org/knora/webapi/TestDataFactory.scala
index aa361d10d1..2a026dacfe 100644
--- a/webapi/src/test/scala/org/knora/webapi/TestDataFactory.scala
+++ b/webapi/src/test/scala/org/knora/webapi/TestDataFactory.scala
@@ -99,5 +99,7 @@ object TestDataFactory {
Status.Active,
SelfJoin.CannotJoin,
RestrictedView.default,
+ Some("2024, Example Project"),
+ Some("CC-BY-4.0"),
)
}
diff --git a/webapi/src/test/scala/org/knora/webapi/slice/admin/domain/service/ProjectServiceSpec.scala b/webapi/src/test/scala/org/knora/webapi/slice/admin/domain/service/ProjectServiceSpec.scala
index 659c4433b8..e6f842faa6 100644
--- a/webapi/src/test/scala/org/knora/webapi/slice/admin/domain/service/ProjectServiceSpec.scala
+++ b/webapi/src/test/scala/org/knora/webapi/slice/admin/domain/service/ProjectServiceSpec.scala
@@ -35,6 +35,8 @@ object ProjectServiceSpec extends ZIOSpecDefault {
ontologies = List.empty,
status = true,
selfjoin = true,
+ copyrightAttribution = None,
+ license = None,
)
assertTrue(
ProjectService.projectDataNamedGraphV2(p).value == s"http://www.knora.org/data/$shortcode/$shortname",
@@ -55,6 +57,8 @@ object ProjectServiceSpec extends ZIOSpecDefault {
status = Status.Active,
selfjoin = SelfJoin.CanJoin,
restrictedView = RestrictedView.default,
+ copyrightAttribution = None,
+ license = None,
)
assertTrue(
ProjectService
diff --git a/webapi/src/test/scala/org/knora/webapi/slice/admin/repo/service/KnoraProjectRepoLiveSpec.scala b/webapi/src/test/scala/org/knora/webapi/slice/admin/repo/service/KnoraProjectRepoLiveSpec.scala
index 0a4977a8fb..7168f0a2cd 100644
--- a/webapi/src/test/scala/org/knora/webapi/slice/admin/repo/service/KnoraProjectRepoLiveSpec.scala
+++ b/webapi/src/test/scala/org/knora/webapi/slice/admin/repo/service/KnoraProjectRepoLiveSpec.scala
@@ -45,6 +45,8 @@ object KnoraProjectRepoLiveSpec extends ZIOSpecDefault {
Status.Active,
SelfJoin.CannotJoin,
RestrictedView.default,
+ Some("2024, Example Project"),
+ Some("Apache-2.0"),
)
private val someProjectTrig =
@@ -62,7 +64,9 @@ object KnoraProjectRepoLiveSpec extends ZIOSpecDefault {
| knora-admin:projectLogo "logo.png" ;
| knora-admin:status true ;
| knora-admin:hasSelfJoinEnabled false ;
- | knora-admin:projectRestrictedViewSize "!128,128" .
+ | knora-admin:projectRestrictedViewSize "!128,128" ;
+ | knora-base:hasCopyrightAttribution "2024, Example Project" ;
+ | knora-base:hasLicense "Apache-2.0" .
|}
|""".stripMargin
@@ -106,7 +110,7 @@ object KnoraProjectRepoLiveSpec extends ZIOSpecDefault {
for {
_ <- TriplestoreServiceInMemory.setDataSetFromTriG(someProjectTrig)
project <- KnoraProjectRepo(_.findById(ProjectIri.unsafeFrom("http://rdfh.ch/projects/1234")))
- } yield assertTrue(project.contains(someProject))
+ } yield assertTrue(project == Some(someProject))
},
test("return None if project does not exist") {
for {
From 2f937305fe74f0827ccb64a85f3653b0d5625b17 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20Kleinb=C3=B6lting?=
Date: Fri, 15 Nov 2024 14:24:47 +0100
Subject: [PATCH 05/18] feat: Add copyright attribution and license to update
Project
---
...rojectsEndpointsRequestsAndResponses.scala | 2 +
.../domain/service/KnoraProjectService.scala | 2 +
.../service/KnoraProjectServiceSpec.scala | 42 +++++++++++++++++++
3 files changed, 46 insertions(+)
create mode 100644 webapi/src/test/scala/org/knora/webapi/slice/admin/domain/service/KnoraProjectServiceSpec.scala
diff --git a/webapi/src/main/scala/org/knora/webapi/slice/admin/api/model/ProjectsEndpointsRequestsAndResponses.scala b/webapi/src/main/scala/org/knora/webapi/slice/admin/api/model/ProjectsEndpointsRequestsAndResponses.scala
index ad9bca8bd8..25623f24a9 100644
--- a/webapi/src/main/scala/org/knora/webapi/slice/admin/api/model/ProjectsEndpointsRequestsAndResponses.scala
+++ b/webapi/src/main/scala/org/knora/webapi/slice/admin/api/model/ProjectsEndpointsRequestsAndResponses.scala
@@ -42,6 +42,8 @@ object ProjectsEndpointsRequestsAndResponses {
logo: Option[Logo] = None,
status: Option[Status] = None,
selfjoin: Option[SelfJoin] = None,
+ copyrightAttribution: Option[String] = None,
+ license: Option[String] = None,
)
object ProjectUpdateRequest {
implicit val codec: JsonCodec[ProjectUpdateRequest] = DeriveJsonCodec.gen[ProjectUpdateRequest]
diff --git a/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/service/KnoraProjectService.scala b/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/service/KnoraProjectService.scala
index 9a05ca32c4..3af6f33f00 100644
--- a/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/service/KnoraProjectService.scala
+++ b/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/service/KnoraProjectService.scala
@@ -99,6 +99,8 @@ final case class KnoraProjectService(knoraProjectRepo: KnoraProjectRepo, ontolog
logo = updateReq.logo.orElse(project.logo),
status = updateReq.status.getOrElse(project.status),
selfjoin = updateReq.selfjoin.getOrElse(project.selfjoin),
+ copyrightAttribution = updateReq.copyrightAttribution.orElse(project.copyrightAttribution),
+ license = updateReq.license.orElse(project.license),
),
)
} yield updated
diff --git a/webapi/src/test/scala/org/knora/webapi/slice/admin/domain/service/KnoraProjectServiceSpec.scala b/webapi/src/test/scala/org/knora/webapi/slice/admin/domain/service/KnoraProjectServiceSpec.scala
new file mode 100644
index 0000000000..f8fb2cf9d4
--- /dev/null
+++ b/webapi/src/test/scala/org/knora/webapi/slice/admin/domain/service/KnoraProjectServiceSpec.scala
@@ -0,0 +1,42 @@
+/*
+ * 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.slice.admin.domain.service
+
+import zio.ZIO
+import zio.test.*
+import zio.test.Assertion.*
+
+import org.knora.webapi.TestDataFactory
+import org.knora.webapi.messages.StringFormatter
+import org.knora.webapi.slice.admin.api.model.ProjectsEndpointsRequestsAndResponses.ProjectUpdateRequest
+import org.knora.webapi.slice.admin.domain.repo.KnoraProjectRepoInMemory
+import org.knora.webapi.slice.ontology.repo.service.OntologyRepoInMemory
+import org.knora.webapi.slice.resourceinfo.domain.IriConverter
+
+object KnoraProjectServiceSpec extends ZIOSpecDefault {
+
+ private val projectService = ZIO.serviceWithZIO[KnoraProjectService]
+ private val repo = ZIO.serviceWithZIO[KnoraProjectRepoInMemory]
+
+ private val updateSuite = suite("updateProject")(
+ test("should update the license and copyright attribution") {
+ val project = TestDataFactory.someProject
+ for {
+ _ <- repo(_.save(project))
+ updateRequest = ProjectUpdateRequest(copyrightAttribution = Some("Foo"), license = Some("bar"))
+ actual <- projectService(_.updateProject(project, updateRequest))
+ } yield assertTrue(actual == project.copy(copyrightAttribution = Some("Foo"), license = Some("bar")))
+ },
+ )
+ val spec = suite("KnoraProjectService")(updateSuite)
+ .provide(
+ KnoraProjectService.layer,
+ KnoraProjectRepoInMemory.layer,
+ OntologyRepoInMemory.emptyLayer,
+ IriConverter.layer,
+ StringFormatter.test,
+ )
+}
From f1389a8354fbe66f15f49e9e48090c86f8af9bc1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20Kleinb=C3=B6lting?=
Date: Fri, 15 Nov 2024 14:40:41 +0100
Subject: [PATCH 06/18] feat: Add copyright attribution and license to test
data
---
.../knoraApiOntologySimple.jsonld | 32 ++++
.../knoraApiOntologyWithValueObjects.jsonld | 176 ++++++++++++++++++
2 files changed, 208 insertions(+)
diff --git a/test_data/generated_test_data/ontologyR2RV2/knoraApiOntologySimple.jsonld b/test_data/generated_test_data/ontologyR2RV2/knoraApiOntologySimple.jsonld
index 92990a3815..a012f6a442 100644
--- a/test_data/generated_test_data/ontologyR2RV2/knoraApiOntologySimple.jsonld
+++ b/test_data/generated_test_data/ontologyR2RV2/knoraApiOntologySimple.jsonld
@@ -902,6 +902,22 @@
{
"@id": "knora-api:StillImageAbstractFileValue",
"@type": "owl:Class",
+ "rdfs:subClassOf": [
+ {
+ "@type": "owl:Restriction",
+ "owl:onProperty": {
+ "@id": "knora-api:hasCopyrightAttribution"
+ },
+ "owl:maxCardinality": 1
+ },
+ {
+ "@type": "owl:Restriction",
+ "owl:onProperty": {
+ "@id": "knora-api:hasLicense"
+ },
+ "owl:maxCardinality": 1
+ }
+ ],
"rdfs:comment": "A file containing a two-dimensional still image"
},
{
@@ -1267,6 +1283,14 @@
},
"@id": "knora-api:hasComment"
},
+ {
+ "@id": "knora-api:hasCopyrightAttribution",
+ "@type": "owl:DatatypeProperty",
+ "knora-api:objectType": {
+ "@id": "xsd:string"
+ },
+ "rdfs:comment": "The copyright statement that gives credit to the original author."
+ },
{
"rdfs:label": "has 3D-file",
"rdfs:subPropertyOf": {
@@ -1394,6 +1418,14 @@
},
"@id": "knora-api:hasKeyword"
},
+ {
+ "@id": "knora-api:hasLicense",
+ "@type": "owl:DatatypeProperty",
+ "knora-api:objectType": {
+ "@id": "xsd:string"
+ },
+ "rdfs:comment": "Specifies the terms under which a work can be used. This statement may be a reference to a well-known license, such as Creative Commons (e.g. 'CC BY-SA') or a custom license."
+ },
{
"rdfs:label": "has Link to",
"rdfs:subPropertyOf": {
diff --git a/test_data/generated_test_data/ontologyR2RV2/knoraApiOntologyWithValueObjects.jsonld b/test_data/generated_test_data/ontologyR2RV2/knoraApiOntologyWithValueObjects.jsonld
index 39bd56e9b4..667d0eb6aa 100644
--- a/test_data/generated_test_data/ontologyR2RV2/knoraApiOntologyWithValueObjects.jsonld
+++ b/test_data/generated_test_data/ontologyR2RV2/knoraApiOntologyWithValueObjects.jsonld
@@ -234,6 +234,22 @@
"owl:cardinality": 1,
"knora-api:isInherited": true
},
+ {
+ "@type": "owl:Restriction",
+ "owl:onProperty": {
+ "@id": "knora-api:hasCopyrightAttribution"
+ },
+ "owl:maxCardinality": 1,
+ "knora-api:isInherited": true
+ },
+ {
+ "@type": "owl:Restriction",
+ "owl:onProperty": {
+ "@id": "knora-api:hasLicense"
+ },
+ "owl:maxCardinality": 1,
+ "knora-api:isInherited": true
+ },
{
"@type": "owl:Restriction",
"owl:onProperty": {
@@ -517,6 +533,22 @@
"owl:cardinality": 1,
"knora-api:isInherited": true
},
+ {
+ "@type": "owl:Restriction",
+ "owl:onProperty": {
+ "@id": "knora-api:hasCopyrightAttribution"
+ },
+ "owl:maxCardinality": 1,
+ "knora-api:isInherited": true
+ },
+ {
+ "@type": "owl:Restriction",
+ "owl:onProperty": {
+ "@id": "knora-api:hasLicense"
+ },
+ "owl:maxCardinality": 1,
+ "knora-api:isInherited": true
+ },
{
"@type": "owl:Restriction",
"owl:onProperty": {
@@ -1315,6 +1347,22 @@
"owl:cardinality": 1,
"knora-api:isInherited": true
},
+ {
+ "@type": "owl:Restriction",
+ "owl:onProperty": {
+ "@id": "knora-api:hasCopyrightAttribution"
+ },
+ "owl:maxCardinality": 1,
+ "knora-api:isInherited": true
+ },
+ {
+ "@type": "owl:Restriction",
+ "owl:onProperty": {
+ "@id": "knora-api:hasLicense"
+ },
+ "owl:maxCardinality": 1,
+ "knora-api:isInherited": true
+ },
{
"@type": "owl:Restriction",
"owl:onProperty": {
@@ -2270,6 +2318,22 @@
"owl:cardinality": 1,
"knora-api:isInherited": true
},
+ {
+ "@type": "owl:Restriction",
+ "owl:onProperty": {
+ "@id": "knora-api:hasCopyrightAttribution"
+ },
+ "owl:maxCardinality": 1,
+ "knora-api:isInherited": true
+ },
+ {
+ "@type": "owl:Restriction",
+ "owl:onProperty": {
+ "@id": "knora-api:hasLicense"
+ },
+ "owl:maxCardinality": 1,
+ "knora-api:isInherited": true
+ },
{
"@type": "owl:Restriction",
"owl:onProperty": {
@@ -2559,6 +2623,20 @@
},
"owl:cardinality": 1
},
+ {
+ "@type": "owl:Restriction",
+ "owl:onProperty": {
+ "@id": "knora-api:hasCopyrightAttribution"
+ },
+ "owl:maxCardinality": 1
+ },
+ {
+ "@type": "owl:Restriction",
+ "owl:onProperty": {
+ "@id": "knora-api:hasLicense"
+ },
+ "owl:maxCardinality": 1
+ },
{
"@type": "owl:Restriction",
"owl:onProperty": {
@@ -3695,6 +3773,22 @@
"owl:cardinality": 1,
"knora-api:isInherited": true
},
+ {
+ "@type": "owl:Restriction",
+ "owl:onProperty": {
+ "@id": "knora-api:hasCopyrightAttribution"
+ },
+ "owl:maxCardinality": 1,
+ "knora-api:isInherited": true
+ },
+ {
+ "@type": "owl:Restriction",
+ "owl:onProperty": {
+ "@id": "knora-api:hasLicense"
+ },
+ "owl:maxCardinality": 1,
+ "knora-api:isInherited": true
+ },
{
"@type": "owl:Restriction",
"owl:onProperty": {
@@ -5925,6 +6019,22 @@
"owl:cardinality": 1,
"knora-api:isInherited": true
},
+ {
+ "@type": "owl:Restriction",
+ "owl:onProperty": {
+ "@id": "knora-api:hasCopyrightAttribution"
+ },
+ "owl:maxCardinality": 1,
+ "knora-api:isInherited": true
+ },
+ {
+ "@type": "owl:Restriction",
+ "owl:onProperty": {
+ "@id": "knora-api:hasLicense"
+ },
+ "owl:maxCardinality": 1,
+ "knora-api:isInherited": true
+ },
{
"@type": "owl:Restriction",
"owl:onProperty": {
@@ -6063,6 +6173,22 @@
"owl:cardinality": 1,
"knora-api:isInherited": true
},
+ {
+ "@type": "owl:Restriction",
+ "owl:onProperty": {
+ "@id": "knora-api:hasCopyrightAttribution"
+ },
+ "owl:maxCardinality": 1,
+ "knora-api:isInherited": true
+ },
+ {
+ "@type": "owl:Restriction",
+ "owl:onProperty": {
+ "@id": "knora-api:hasLicense"
+ },
+ "owl:maxCardinality": 1,
+ "knora-api:isInherited": true
+ },
{
"@type": "owl:Restriction",
"owl:onProperty": {
@@ -6208,6 +6334,22 @@
"owl:cardinality": 1,
"knora-api:isInherited": true
},
+ {
+ "@type": "owl:Restriction",
+ "owl:onProperty": {
+ "@id": "knora-api:hasCopyrightAttribution"
+ },
+ "owl:maxCardinality": 1,
+ "knora-api:isInherited": true
+ },
+ {
+ "@type": "owl:Restriction",
+ "owl:onProperty": {
+ "@id": "knora-api:hasLicense"
+ },
+ "owl:maxCardinality": 1,
+ "knora-api:isInherited": true
+ },
{
"@type": "owl:Restriction",
"owl:onProperty": {
@@ -6518,6 +6660,22 @@
"owl:cardinality": 1,
"knora-api:isInherited": true
},
+ {
+ "@type": "owl:Restriction",
+ "owl:onProperty": {
+ "@id": "knora-api:hasCopyrightAttribution"
+ },
+ "owl:maxCardinality": 1,
+ "knora-api:isInherited": true
+ },
+ {
+ "@type": "owl:Restriction",
+ "owl:onProperty": {
+ "@id": "knora-api:hasLicense"
+ },
+ "owl:maxCardinality": 1,
+ "knora-api:isInherited": true
+ },
{
"@type": "owl:Restriction",
"owl:onProperty": {
@@ -8129,6 +8287,15 @@
},
"rdfs:comment": "Represents a comment on a resource as a knora-base:TextValue"
},
+ {
+ "rdfs:label": "has copyright attribution",
+ "rdfs:comment": "The copyright statement that gives credit to the original author.",
+ "@type": "owl:DatatypeProperty",
+ "knora-api:objectType": {
+ "@id": "xsd:string"
+ },
+ "@id": "knora-api:hasCopyrightAttribution"
+ },
{
"rdfs:label": "has 3D-file",
"rdfs:subPropertyOf": {
@@ -8287,6 +8454,15 @@
},
"rdfs:comment": "Indicates a keyword of a resource"
},
+ {
+ "rdfs:label": "has copyright attribution",
+ "rdfs:comment": "Specifies the terms under which a work can be used. This statement may be a reference to a well-known license, such as Creative Commons (e.g. CC BY-SA) or a custom license.",
+ "@type": "owl:DatatypeProperty",
+ "knora-api:objectType": {
+ "@id": "xsd:string"
+ },
+ "@id": "knora-api:hasLicense"
+ },
{
"rdfs:label": "has Link to",
"rdfs:subPropertyOf": {
From 97b0377e24002c4fabf2dd66821a4c34bbc7698f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20Kleinb=C3=B6lting?=
Date: Fri, 15 Nov 2024 15:47:37 +0100
Subject: [PATCH 07/18] feat: Introduce StringValues for copyright attribution
and license
---
.../IntegrationTestAdminJsonProtocol.scala | 20 +++++++++++++++-
.../admin/ProjectRestServiceSpec.scala | 8 +++----
.../knora/webapi/slice/admin/api/Codecs.scala | 12 ++++++----
.../webapi/slice/admin/api/Examples.scala | 6 +++--
...rojectsEndpointsRequestsAndResponses.scala | 8 +++----
.../admin/api/model/ProjectsMessagesADM.scala | 6 +++--
.../admin/domain/model/KnoraProject.scala | 23 +++++++++++++++++--
.../slice/admin/repo/rdf/RdfConversions.scala | 3 +++
.../repo/service/KnoraProjectRepoLive.scala | 10 ++++----
.../org/knora/webapi/TestDataFactory.scala | 4 ++--
.../service/KnoraProjectServiceSpec.scala | 18 +++++++++++----
.../service/KnoraProjectRepoLiveSpec.scala | 6 +++--
12 files changed, 92 insertions(+), 32 deletions(-)
diff --git a/integration/src/test/scala/org/knora/webapi/messages/admin/responder/IntegrationTestAdminJsonProtocol.scala b/integration/src/test/scala/org/knora/webapi/messages/admin/responder/IntegrationTestAdminJsonProtocol.scala
index c0efc1325f..e4382aa8f3 100644
--- a/integration/src/test/scala/org/knora/webapi/messages/admin/responder/IntegrationTestAdminJsonProtocol.scala
+++ b/integration/src/test/scala/org/knora/webapi/messages/admin/responder/IntegrationTestAdminJsonProtocol.scala
@@ -6,7 +6,6 @@
package org.knora.webapi.messages.admin.responder
import spray.json.*
-
import org.knora.webapi.messages.admin.responder.groupsmessages.GroupGetResponseADM
import org.knora.webapi.messages.admin.responder.groupsmessages.GroupsGetResponseADM
import org.knora.webapi.messages.admin.responder.permissionsmessages.AdministrativePermissionADM
@@ -45,7 +44,10 @@ import org.knora.webapi.slice.admin.api.model.ProjectAdminMembersGetResponseADM
import org.knora.webapi.slice.admin.api.model.ProjectMembersGetResponseADM
import org.knora.webapi.slice.admin.api.model.ProjectOperationResponseADM
import org.knora.webapi.slice.admin.domain.model.Group
+import org.knora.webapi.slice.admin.domain.model.KnoraProject.CopyrightAttribution
+import org.knora.webapi.slice.admin.domain.model.KnoraProject.License
import org.knora.webapi.slice.admin.domain.model.User
+import org.knora.webapi.slice.common.Value.StringValue
/**
* A spray-json protocol for generating Knora API JSON providing data about projects.
@@ -194,6 +196,22 @@ object IntegrationTestAdminJsonProtocol extends TriplestoreJsonProtocol {
),
)
+ trait StringValueFormat[T <: StringValue] extends JsonFormat[T] { self =>
+ def from: String => Either[String, T]
+ override def write(v: T): JsValue = JsString(v.value)
+ override def read(json: JsValue): T = json match
+ case JsString(str) => self.from(str).fold(err => throw DeserializationException(err), identity)
+ case _ => throw DeserializationException("Must be a json String")
+ }
+
+ implicit object CopyrightAttributionFormat extends StringValueFormat[CopyrightAttribution] {
+ override val from: String => Either[String, CopyrightAttribution] = CopyrightAttribution.from
+ }
+
+ implicit object LicenseFormat extends StringValueFormat[License] {
+ override val from: String => Either[String, License] = License.from
+ }
+
implicit val groupFormat: JsonFormat[Group] = jsonFormat6(Group.apply)
implicit val projectAdminMembersGetResponseADMFormat: RootJsonFormat[ProjectAdminMembersGetResponseADM] = rootFormat(
diff --git a/integration/src/test/scala/org/knora/webapi/responders/admin/ProjectRestServiceSpec.scala b/integration/src/test/scala/org/knora/webapi/responders/admin/ProjectRestServiceSpec.scala
index b250f5f43d..24db171d85 100644
--- a/integration/src/test/scala/org/knora/webapi/responders/admin/ProjectRestServiceSpec.scala
+++ b/integration/src/test/scala/org/knora/webapi/responders/admin/ProjectRestServiceSpec.scala
@@ -162,8 +162,8 @@ class ProjectRestServiceSpec extends CoreSpec with ImplicitSender {
logo = Some(Logo.unsafeFrom("/fu/bar/baz.jpg")),
status = Status.Active,
selfjoin = SelfJoin.CannotJoin,
- copyrightAttribution = Some("2024, Example Project"),
- license = Some("CC-BY-4.0"),
+ copyrightAttribution = Some(CopyrightAttribution.unsafeFrom("2024, Example Project")),
+ license = Some(License.unsafeFrom("CC-BY-4.0")),
),
SharedTestDataADM.rootUser,
),
@@ -176,8 +176,8 @@ class ProjectRestServiceSpec extends CoreSpec with ImplicitSender {
received.project.description should be(
Seq(StringLiteralV2.from(value = "project description", language = Some("en"))),
)
- received.project.copyrightAttribution should be(Some("2024, Example Project"))
- received.project.license should be(Some("CC-BY-4.0"))
+ received.project.copyrightAttribution should be(Some(CopyrightAttribution.unsafeFrom("2024, Example Project")))
+ received.project.license should be(Some(License.unsafeFrom("CC-BY-4.0")))
newProjectIri.set(received.project.id)
diff --git a/webapi/src/main/scala/org/knora/webapi/slice/admin/api/Codecs.scala b/webapi/src/main/scala/org/knora/webapi/slice/admin/api/Codecs.scala
index 7a92b5c308..d0486968d8 100644
--- a/webapi/src/main/scala/org/knora/webapi/slice/admin/api/Codecs.scala
+++ b/webapi/src/main/scala/org/knora/webapi/slice/admin/api/Codecs.scala
@@ -102,11 +102,13 @@ object Codecs {
implicit val restrictedViewWatermark: StringCodec[RestrictedView.Watermark] = booleanCodec(
RestrictedView.Watermark.from,
)
- implicit val selfJoin: StringCodec[SelfJoin] = booleanCodec(SelfJoin.from)
- implicit val shortcode: StringCodec[Shortcode] = stringCodec(Shortcode.from)
- implicit val shortname: StringCodec[Shortname] = stringCodec(Shortname.from)
- implicit val sparqlEncodedString: StringCodec[SparqlEncodedString] = stringCodec(SparqlEncodedString.from)
- implicit val status: StringCodec[Status] = booleanCodec(Status.from)
+ implicit val selfJoin: StringCodec[SelfJoin] = booleanCodec(SelfJoin.from)
+ implicit val shortcode: StringCodec[Shortcode] = stringCodec(Shortcode.from)
+ implicit val shortname: StringCodec[Shortname] = stringCodec(Shortname.from)
+ implicit val sparqlEncodedString: StringCodec[SparqlEncodedString] = stringCodec(SparqlEncodedString.from)
+ implicit val status: StringCodec[Status] = booleanCodec(Status.from)
+ implicit val copyrightAttribution: StringCodec[CopyrightAttribution] = stringCodec(CopyrightAttribution.from)
+ implicit val license: StringCodec[License] = stringCodec(License.from)
// user
implicit val userIri: StringCodec[UserIri] = stringCodec(UserIri.from)
diff --git a/webapi/src/main/scala/org/knora/webapi/slice/admin/api/Examples.scala b/webapi/src/main/scala/org/knora/webapi/slice/admin/api/Examples.scala
index 45737e59cd..c76501dd20 100644
--- a/webapi/src/main/scala/org/knora/webapi/slice/admin/api/Examples.scala
+++ b/webapi/src/main/scala/org/knora/webapi/slice/admin/api/Examples.scala
@@ -23,6 +23,8 @@ import org.knora.webapi.slice.admin.domain.model.GroupIri
import org.knora.webapi.slice.admin.domain.model.GroupName
import org.knora.webapi.slice.admin.domain.model.GroupSelfJoin
import org.knora.webapi.slice.admin.domain.model.GroupStatus
+import org.knora.webapi.slice.admin.domain.model.KnoraProject.CopyrightAttribution
+import org.knora.webapi.slice.admin.domain.model.KnoraProject.License
import org.knora.webapi.slice.admin.domain.model.KnoraProject.ProjectIri
import org.knora.webapi.slice.admin.domain.model.User
import org.knora.webapi.slice.admin.domain.model.UserIri
@@ -93,8 +95,8 @@ object Examples {
status = true,
ontologies = Seq.empty,
selfjoin = false,
- copyrightAttribution = Some("2024, Example Project"),
- license = Some("CC-BY-4.0"),
+ copyrightAttribution = Some(CopyrightAttribution.unsafeFrom("2024, Example Project")),
+ license = Some(License.unsafeFrom("CC-BY-4.0")),
)
private val group = Group(
diff --git a/webapi/src/main/scala/org/knora/webapi/slice/admin/api/model/ProjectsEndpointsRequestsAndResponses.scala b/webapi/src/main/scala/org/knora/webapi/slice/admin/api/model/ProjectsEndpointsRequestsAndResponses.scala
index 25623f24a9..109144d967 100644
--- a/webapi/src/main/scala/org/knora/webapi/slice/admin/api/model/ProjectsEndpointsRequestsAndResponses.scala
+++ b/webapi/src/main/scala/org/knora/webapi/slice/admin/api/model/ProjectsEndpointsRequestsAndResponses.scala
@@ -27,8 +27,8 @@ object ProjectsEndpointsRequestsAndResponses {
logo: Option[Logo] = None,
status: Status,
selfjoin: SelfJoin,
- copyrightAttribution: Option[String],
- license: Option[String],
+ copyrightAttribution: Option[CopyrightAttribution],
+ license: Option[License],
)
object ProjectCreateRequest {
implicit val codec: JsonCodec[ProjectCreateRequest] = DeriveJsonCodec.gen[ProjectCreateRequest]
@@ -42,8 +42,8 @@ object ProjectsEndpointsRequestsAndResponses {
logo: Option[Logo] = None,
status: Option[Status] = None,
selfjoin: Option[SelfJoin] = None,
- copyrightAttribution: Option[String] = None,
- license: Option[String] = None,
+ copyrightAttribution: Option[CopyrightAttribution] = None,
+ license: Option[License] = None,
)
object ProjectUpdateRequest {
implicit val codec: JsonCodec[ProjectUpdateRequest] = DeriveJsonCodec.gen[ProjectUpdateRequest]
diff --git a/webapi/src/main/scala/org/knora/webapi/slice/admin/api/model/ProjectsMessagesADM.scala b/webapi/src/main/scala/org/knora/webapi/slice/admin/api/model/ProjectsMessagesADM.scala
index c2c4dcdfff..dcab052e59 100644
--- a/webapi/src/main/scala/org/knora/webapi/slice/admin/api/model/ProjectsMessagesADM.scala
+++ b/webapi/src/main/scala/org/knora/webapi/slice/admin/api/model/ProjectsMessagesADM.scala
@@ -11,6 +11,8 @@ import zio.json.JsonCodec
import org.knora.webapi.IRI
import org.knora.webapi.messages.admin.responder.AdminKnoraResponseADM
import org.knora.webapi.messages.store.triplestoremessages.StringLiteralV2
+import org.knora.webapi.slice.admin.api.Codecs.ZioJsonCodec.copyrightAttribution
+import org.knora.webapi.slice.admin.api.Codecs.ZioJsonCodec.license
import org.knora.webapi.slice.admin.domain.model.KnoraProject.*
import org.knora.webapi.slice.admin.domain.model.RestrictedView
import org.knora.webapi.slice.admin.domain.model.User
@@ -40,8 +42,8 @@ case class Project(
ontologies: Seq[IRI],
status: Boolean,
selfjoin: Boolean,
- copyrightAttribution: Option[String],
- license: Option[String],
+ copyrightAttribution: Option[CopyrightAttribution],
+ license: Option[License],
) extends Ordered[Project] {
def projectIri: ProjectIri = ProjectIri.unsafeFrom(id)
diff --git a/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/model/KnoraProject.scala b/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/model/KnoraProject.scala
index e3771c5802..67ffcfef1e 100644
--- a/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/model/KnoraProject.scala
+++ b/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/model/KnoraProject.scala
@@ -34,8 +34,8 @@ case class KnoraProject(
status: Status,
selfjoin: SelfJoin,
restrictedView: RestrictedView,
- copyrightAttribution: Option[String],
- license: Option[String],
+ copyrightAttribution: Option[CopyrightAttribution],
+ license: Option[License],
) extends EntityWithId[ProjectIri]
object KnoraProject {
@@ -175,4 +175,23 @@ object KnoraProject {
def from(value: Boolean): SelfJoin = if (value) CanJoin else CannotJoin
}
+
+ final case class CopyrightAttribution private (override val value: String) extends StringValue
+ object CopyrightAttribution extends StringValueCompanion[CopyrightAttribution] {
+ private val maxLength = 1_000
+ def from(str: String): Either[String, CopyrightAttribution] =
+ if (str.isEmpty) Left("Copyright attribution cannot be empty.")
+ else if (str.contains("\n")) Left("Copyright attribution may not contain line breaks.")
+ else if (str.length >= maxLength) Left(s"Copyright attribution may only be ${maxLength} characters long.")
+ else Right(CopyrightAttribution(str))
+ }
+
+ final case class License private (override val value: String) extends StringValue
+ object License extends StringValueCompanion[License] {
+ private val maxLength = 10_000
+ def from(str: String): Either[String, License] =
+ if (str.isEmpty) Left("License cannot be empty.")
+ else if (str.length >= maxLength) Left(s"License may only be ${maxLength} characters long.")
+ else Right(License(str))
+ }
}
diff --git a/webapi/src/main/scala/org/knora/webapi/slice/admin/repo/rdf/RdfConversions.scala b/webapi/src/main/scala/org/knora/webapi/slice/admin/repo/rdf/RdfConversions.scala
index 1b7c9264ab..1b04ab0b29 100644
--- a/webapi/src/main/scala/org/knora/webapi/slice/admin/repo/rdf/RdfConversions.scala
+++ b/webapi/src/main/scala/org/knora/webapi/slice/admin/repo/rdf/RdfConversions.scala
@@ -42,6 +42,9 @@ object RdfConversions {
implicit val selfjoinConverter: Boolean => Either[String, SelfJoin] = value => Right(SelfJoin.from(value))
implicit val descriptionConverter: LangString => Either[String, Description] = langString =>
Description.from(StringLiteralV2.from(langString.value, langString.lang))
+ implicit val copyrightAttributionConverter: String => Either[String, CopyrightAttribution] = value =>
+ CopyrightAttribution.from(value)
+ implicit val licenseConverter: String => Either[String, License] = value => License.from(value)
// User properties
implicit val usernameConverter: String => Either[String, Username] = Username.from
diff --git a/webapi/src/main/scala/org/knora/webapi/slice/admin/repo/service/KnoraProjectRepoLive.scala b/webapi/src/main/scala/org/knora/webapi/slice/admin/repo/service/KnoraProjectRepoLive.scala
index 8c9336c874..9268f786c1 100644
--- a/webapi/src/main/scala/org/knora/webapi/slice/admin/repo/service/KnoraProjectRepoLive.scala
+++ b/webapi/src/main/scala/org/knora/webapi/slice/admin/repo/service/KnoraProjectRepoLive.scala
@@ -104,8 +104,8 @@ object KnoraProjectRepoLive {
logo <- resource.getStringLiteral[Logo](ProjectLogo)
status <- resource.getBooleanLiteralOrFail[Status](StatusProp)
selfjoin <- resource.getBooleanLiteralOrFail[SelfJoin](HasSelfJoinEnabled)
- copyrightAttribution <- resource.getStringLiteral[String](HasCopyrightAttribution)(Right(_))
- license <- resource.getStringLiteral[String](HasLicense)(Right(_))
+ copyrightAttribution <- resource.getStringLiteral[CopyrightAttribution](HasCopyrightAttribution)
+ license <- resource.getStringLiteral[License](HasLicense)
restrictedView <- getRestrictedView
} yield KnoraProject(
id = ProjectIri.unsafeFrom(iri.value),
@@ -145,8 +145,10 @@ object KnoraProjectRepoLive {
pattern.andHas(Vocabulary.KnoraAdmin.projectRestrictedViewWatermark, watermark)
}
- project.copyrightAttribution.foreach(attr => pattern.andHas(Vocabulary.KnoraBase.hasCopyrightAttribution, attr))
- project.license.foreach(license => pattern.andHas(Vocabulary.KnoraBase.hasLicense, license))
+ project.copyrightAttribution.foreach(attr =>
+ pattern.andHas(Vocabulary.KnoraBase.hasCopyrightAttribution, attr.value),
+ )
+ project.license.foreach(license => pattern.andHas(Vocabulary.KnoraBase.hasLicense, license.value))
pattern
}
diff --git a/webapi/src/test/scala/org/knora/webapi/TestDataFactory.scala b/webapi/src/test/scala/org/knora/webapi/TestDataFactory.scala
index 2a026dacfe..982ff13950 100644
--- a/webapi/src/test/scala/org/knora/webapi/TestDataFactory.scala
+++ b/webapi/src/test/scala/org/knora/webapi/TestDataFactory.scala
@@ -99,7 +99,7 @@ object TestDataFactory {
Status.Active,
SelfJoin.CannotJoin,
RestrictedView.default,
- Some("2024, Example Project"),
- Some("CC-BY-4.0"),
+ Some(CopyrightAttribution.unsafeFrom("2024, Example Project")),
+ Some(License.unsafeFrom("CC-BY-4.0")),
)
}
diff --git a/webapi/src/test/scala/org/knora/webapi/slice/admin/domain/service/KnoraProjectServiceSpec.scala b/webapi/src/test/scala/org/knora/webapi/slice/admin/domain/service/KnoraProjectServiceSpec.scala
index f8fb2cf9d4..030da89ce6 100644
--- a/webapi/src/test/scala/org/knora/webapi/slice/admin/domain/service/KnoraProjectServiceSpec.scala
+++ b/webapi/src/test/scala/org/knora/webapi/slice/admin/domain/service/KnoraProjectServiceSpec.scala
@@ -12,6 +12,8 @@ import zio.test.Assertion.*
import org.knora.webapi.TestDataFactory
import org.knora.webapi.messages.StringFormatter
import org.knora.webapi.slice.admin.api.model.ProjectsEndpointsRequestsAndResponses.ProjectUpdateRequest
+import org.knora.webapi.slice.admin.domain.model.KnoraProject.CopyrightAttribution
+import org.knora.webapi.slice.admin.domain.model.KnoraProject.License
import org.knora.webapi.slice.admin.domain.repo.KnoraProjectRepoInMemory
import org.knora.webapi.slice.ontology.repo.service.OntologyRepoInMemory
import org.knora.webapi.slice.resourceinfo.domain.IriConverter
@@ -25,10 +27,18 @@ object KnoraProjectServiceSpec extends ZIOSpecDefault {
test("should update the license and copyright attribution") {
val project = TestDataFactory.someProject
for {
- _ <- repo(_.save(project))
- updateRequest = ProjectUpdateRequest(copyrightAttribution = Some("Foo"), license = Some("bar"))
- actual <- projectService(_.updateProject(project, updateRequest))
- } yield assertTrue(actual == project.copy(copyrightAttribution = Some("Foo"), license = Some("bar")))
+ _ <- repo(_.save(project))
+ updateRequest = ProjectUpdateRequest(
+ copyrightAttribution = Some(CopyrightAttribution.unsafeFrom("Foo")),
+ license = Some(License.unsafeFrom("bar")),
+ )
+ actual <- projectService(_.updateProject(project, updateRequest))
+ } yield assertTrue(
+ actual == project.copy(
+ copyrightAttribution = Some(CopyrightAttribution.unsafeFrom("Foo")),
+ license = Some(License.unsafeFrom("bar")),
+ ),
+ )
},
)
val spec = suite("KnoraProjectService")(updateSuite)
diff --git a/webapi/src/test/scala/org/knora/webapi/slice/admin/repo/service/KnoraProjectRepoLiveSpec.scala b/webapi/src/test/scala/org/knora/webapi/slice/admin/repo/service/KnoraProjectRepoLiveSpec.scala
index 7168f0a2cd..1fd1ed296c 100644
--- a/webapi/src/test/scala/org/knora/webapi/slice/admin/repo/service/KnoraProjectRepoLiveSpec.scala
+++ b/webapi/src/test/scala/org/knora/webapi/slice/admin/repo/service/KnoraProjectRepoLiveSpec.scala
@@ -18,8 +18,10 @@ import zio.test.check
import org.knora.webapi.messages.StringFormatter
import org.knora.webapi.slice.admin.AdminConstants
import org.knora.webapi.slice.admin.domain.model.KnoraProject
+import org.knora.webapi.slice.admin.domain.model.KnoraProject.CopyrightAttribution
import org.knora.webapi.slice.admin.domain.model.KnoraProject.Description
import org.knora.webapi.slice.admin.domain.model.KnoraProject.Keyword
+import org.knora.webapi.slice.admin.domain.model.KnoraProject.License
import org.knora.webapi.slice.admin.domain.model.KnoraProject.Logo
import org.knora.webapi.slice.admin.domain.model.KnoraProject.Longname
import org.knora.webapi.slice.admin.domain.model.KnoraProject.ProjectIri
@@ -45,8 +47,8 @@ object KnoraProjectRepoLiveSpec extends ZIOSpecDefault {
Status.Active,
SelfJoin.CannotJoin,
RestrictedView.default,
- Some("2024, Example Project"),
- Some("Apache-2.0"),
+ Some(CopyrightAttribution.unsafeFrom("2024, Example Project")),
+ Some(License.unsafeFrom("Apache-2.0")),
)
private val someProjectTrig =
From aec743f00bcb8060fbfa3d29f7b89f3409e486be Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20Kleinb=C3=B6lting?=
Date: Fri, 15 Nov 2024 16:38:19 +0100
Subject: [PATCH 08/18] fmt
---
.../admin/responder/IntegrationTestAdminJsonProtocol.scala | 1 +
1 file changed, 1 insertion(+)
diff --git a/integration/src/test/scala/org/knora/webapi/messages/admin/responder/IntegrationTestAdminJsonProtocol.scala b/integration/src/test/scala/org/knora/webapi/messages/admin/responder/IntegrationTestAdminJsonProtocol.scala
index e4382aa8f3..3ce4d8d615 100644
--- a/integration/src/test/scala/org/knora/webapi/messages/admin/responder/IntegrationTestAdminJsonProtocol.scala
+++ b/integration/src/test/scala/org/knora/webapi/messages/admin/responder/IntegrationTestAdminJsonProtocol.scala
@@ -6,6 +6,7 @@
package org.knora.webapi.messages.admin.responder
import spray.json.*
+
import org.knora.webapi.messages.admin.responder.groupsmessages.GroupGetResponseADM
import org.knora.webapi.messages.admin.responder.groupsmessages.GroupsGetResponseADM
import org.knora.webapi.messages.admin.responder.permissionsmessages.AdministrativePermissionADM
From 7947c2dd7325b3f1bf3b63f15534c55f1a36b2a2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20Kleinb=C3=B6lting?=
Date: Fri, 15 Nov 2024 16:40:34 +0100
Subject: [PATCH 09/18] simplify
---
.../knora/webapi/slice/admin/repo/rdf/RdfConversions.scala | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/webapi/src/main/scala/org/knora/webapi/slice/admin/repo/rdf/RdfConversions.scala b/webapi/src/main/scala/org/knora/webapi/slice/admin/repo/rdf/RdfConversions.scala
index 1b04ab0b29..f01da22943 100644
--- a/webapi/src/main/scala/org/knora/webapi/slice/admin/repo/rdf/RdfConversions.scala
+++ b/webapi/src/main/scala/org/knora/webapi/slice/admin/repo/rdf/RdfConversions.scala
@@ -42,9 +42,8 @@ object RdfConversions {
implicit val selfjoinConverter: Boolean => Either[String, SelfJoin] = value => Right(SelfJoin.from(value))
implicit val descriptionConverter: LangString => Either[String, Description] = langString =>
Description.from(StringLiteralV2.from(langString.value, langString.lang))
- implicit val copyrightAttributionConverter: String => Either[String, CopyrightAttribution] = value =>
- CopyrightAttribution.from(value)
- implicit val licenseConverter: String => Either[String, License] = value => License.from(value)
+ implicit val copyrightAttributionConverter: String => Either[String, CopyrightAttribution] = CopyrightAttribution.from
+ implicit val licenseConverter: String => Either[String, License] = License.from
// User properties
implicit val usernameConverter: String => Either[String, Username] = Username.from
From 64ce806fcf539b6eed58ede63a77c9d2ea4e807b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20Kleinb=C3=B6lting?=
Date: Fri, 15 Nov 2024 17:37:52 +0100
Subject: [PATCH 10/18] refactor: Make Project.shortname typed
---
.../IntegrationTestAdminJsonProtocol.scala | 5 +++++
.../admin/ProjectRestServiceSpec.scala | 8 +++----
.../webapi/sharedtestdata/ProjectInfo.scala | 22 +++++++++----------
.../sharedtestdata/SharedTestDataADM.scala | 21 +++++++++---------
.../webapi/slice/admin/api/Examples.scala | 3 ++-
.../admin/api/model/ProjectsMessagesADM.scala | 4 ++--
.../admin/domain/service/ProjectService.scala | 7 +++---
.../domain/service/ProjectServiceSpec.scala | 4 ++--
8 files changed, 40 insertions(+), 34 deletions(-)
diff --git a/integration/src/test/scala/org/knora/webapi/messages/admin/responder/IntegrationTestAdminJsonProtocol.scala b/integration/src/test/scala/org/knora/webapi/messages/admin/responder/IntegrationTestAdminJsonProtocol.scala
index 3ce4d8d615..9294bdda50 100644
--- a/integration/src/test/scala/org/knora/webapi/messages/admin/responder/IntegrationTestAdminJsonProtocol.scala
+++ b/integration/src/test/scala/org/knora/webapi/messages/admin/responder/IntegrationTestAdminJsonProtocol.scala
@@ -47,6 +47,7 @@ import org.knora.webapi.slice.admin.api.model.ProjectOperationResponseADM
import org.knora.webapi.slice.admin.domain.model.Group
import org.knora.webapi.slice.admin.domain.model.KnoraProject.CopyrightAttribution
import org.knora.webapi.slice.admin.domain.model.KnoraProject.License
+import org.knora.webapi.slice.admin.domain.model.KnoraProject.Shortname
import org.knora.webapi.slice.admin.domain.model.User
import org.knora.webapi.slice.common.Value.StringValue
@@ -213,6 +214,10 @@ object IntegrationTestAdminJsonProtocol extends TriplestoreJsonProtocol {
override val from: String => Either[String, License] = License.from
}
+ implicit object ShortnameFormat extends StringValueFormat[Shortname] {
+ override val from: String => Either[String, Shortname] = Shortname.from
+ }
+
implicit val groupFormat: JsonFormat[Group] = jsonFormat6(Group.apply)
implicit val projectAdminMembersGetResponseADMFormat: RootJsonFormat[ProjectAdminMembersGetResponseADM] = rootFormat(
diff --git a/integration/src/test/scala/org/knora/webapi/responders/admin/ProjectRestServiceSpec.scala b/integration/src/test/scala/org/knora/webapi/responders/admin/ProjectRestServiceSpec.scala
index 24db171d85..a64bec8480 100644
--- a/integration/src/test/scala/org/knora/webapi/responders/admin/ProjectRestServiceSpec.scala
+++ b/integration/src/test/scala/org/knora/webapi/responders/admin/ProjectRestServiceSpec.scala
@@ -66,7 +66,7 @@ class ProjectRestServiceSpec extends CoreSpec with ImplicitSender {
"return information about a project identified by shortname" in {
val actual = UnsafeZioRun.runOrThrow(
- ProjectRestService(_.findByShortname(SharedTestDataADM.incunabulaProject.getShortname)),
+ ProjectRestService(_.findByShortname(SharedTestDataADM.incunabulaProject.shortname)),
)
assert(actual == ProjectGetResponse(toExternal(SharedTestDataADM.incunabulaProject)))
}
@@ -106,7 +106,7 @@ class ProjectRestServiceSpec extends CoreSpec with ImplicitSender {
"return restricted view settings using project SHORTNAME" in {
val actual = UnsafeZioRun.runOrThrow(
ProjectRestService(
- _.getProjectRestrictedViewSettingsByShortname(SharedTestDataADM.imagesProject.getShortname),
+ _.getProjectRestrictedViewSettingsByShortname(SharedTestDataADM.imagesProject.shortname),
),
)
actual shouldEqual expectedResult
@@ -451,7 +451,7 @@ class ProjectRestServiceSpec extends CoreSpec with ImplicitSender {
"return all members of a project identified by shortname" in {
val actual = UnsafeZioRun.runOrThrow(
ProjectRestService(
- _.getProjectMembersByShortname(SharedTestDataADM.rootUser, SharedTestDataADM.imagesProject.getShortname),
+ _.getProjectMembersByShortname(SharedTestDataADM.rootUser, SharedTestDataADM.imagesProject.shortname),
),
)
@@ -527,7 +527,7 @@ class ProjectRestServiceSpec extends CoreSpec with ImplicitSender {
ProjectRestService(
_.getProjectAdminMembersByShortname(
SharedTestDataADM.rootUser,
- SharedTestDataADM.imagesProject.getShortname,
+ SharedTestDataADM.imagesProject.shortname,
),
),
)
diff --git a/integration/src/test/scala/org/knora/webapi/sharedtestdata/ProjectInfo.scala b/integration/src/test/scala/org/knora/webapi/sharedtestdata/ProjectInfo.scala
index e52c52700f..49ea177cef 100644
--- a/integration/src/test/scala/org/knora/webapi/sharedtestdata/ProjectInfo.scala
+++ b/integration/src/test/scala/org/knora/webapi/sharedtestdata/ProjectInfo.scala
@@ -35,17 +35,17 @@ case class ProjectInfo(
)
object ProjectInfo {
- def from(projectADM: Project): ProjectInfo =
+ def from(project: Project): ProjectInfo =
ProjectInfo(
- id = projectADM.id,
- shortname = projectADM.shortname,
- shortcode = projectADM.shortcode,
- longname = projectADM.longname,
- description = projectADM.description.headOption.map(_.value),
- keywords = projectADM.keywords.headOption.map(_ => projectADM.keywords.mkString(", ")),
- logo = projectADM.logo,
- ontologies = projectADM.ontologies,
- status = projectADM.status,
- selfjoin = projectADM.selfjoin,
+ id = project.id,
+ shortname = project.shortname.value,
+ shortcode = project.shortcode,
+ longname = project.longname,
+ description = project.description.headOption.map(_.value),
+ keywords = project.keywords.headOption.map(_ => project.keywords.mkString(", ")),
+ logo = project.logo,
+ ontologies = project.ontologies,
+ status = project.status,
+ selfjoin = project.selfjoin,
)
}
diff --git a/integration/src/test/scala/org/knora/webapi/sharedtestdata/SharedTestDataADM.scala b/integration/src/test/scala/org/knora/webapi/sharedtestdata/SharedTestDataADM.scala
index b4e11edcc4..69711de82d 100644
--- a/integration/src/test/scala/org/knora/webapi/sharedtestdata/SharedTestDataADM.scala
+++ b/integration/src/test/scala/org/knora/webapi/sharedtestdata/SharedTestDataADM.scala
@@ -16,6 +16,7 @@ import org.knora.webapi.messages.store.triplestoremessages.StringLiteralV2
import org.knora.webapi.messages.util.KnoraSystemInstances
import org.knora.webapi.slice.admin.api.model.Project
import org.knora.webapi.slice.admin.domain.model.Group
+import org.knora.webapi.slice.admin.domain.model.KnoraProject.Shortname
import org.knora.webapi.slice.admin.domain.model.Permission
import org.knora.webapi.slice.admin.domain.model.User
import org.knora.webapi.slice.admin.domain.service.KnoraGroupRepo
@@ -155,7 +156,7 @@ object SharedTestDataADM {
/* represents the full ProjectADM of the Knora System project */
def systemProject: Project = Project(
id = KnoraProjectRepo.builtIn.SystemProject.id.value,
- shortname = "SystemProject",
+ shortname = Shortname.unsafeFrom("SystemProject"),
shortcode = "FFFF",
longname = Some("Knora System Project"),
description = Seq(StringLiteralV2.from(value = "Knora System Project", language = Some("en"))),
@@ -176,7 +177,7 @@ object SharedTestDataADM {
/* represents the full ProjectADM of the default shared ontologies project */
def defaultSharedOntologiesProject: Project = Project(
id = OntologyConstants.KnoraAdmin.DefaultSharedOntologiesProject,
- shortname = "DefaultSharedOntologiesProject",
+ shortname = Shortname.unsafeFrom("DefaultSharedOntologiesProject"),
shortcode = "0000",
longname = Some("Default Knora Shared Ontologies Project"),
description = Seq(StringLiteralV2.from(value = "Default Knora Shared Ontologies Project", language = Some("en"))),
@@ -290,7 +291,7 @@ object SharedTestDataADM {
/* represents the full ProjectADM of the images project */
def imagesProject: Project = Project(
id = imagesProjectIri,
- shortname = "images",
+ shortname = Shortname.unsafeFrom("images"),
shortcode = "00FF",
longname = Some("Image Collection Demo"),
description = Seq(StringLiteralV2.from(value = "A demo project of a collection of images", language = Some("en"))),
@@ -306,7 +307,7 @@ object SharedTestDataADM {
/* represents the full ProjectADM of the images project in the external format */
def imagesProjectExternal: Project = Project(
id = imagesProjectIri,
- shortname = "images",
+ shortname = Shortname.unsafeFrom("images"),
shortcode = "00FF",
longname = Some("Image Collection Demo"),
description = Seq(StringLiteralV2.from(value = "A demo project of a collection of images", language = Some("en"))),
@@ -450,7 +451,7 @@ object SharedTestDataADM {
/* represents the ProjectADM of the incunabula project */
def incunabulaProject: Project = Project(
id = incunabulaProjectIri,
- shortname = "incunabula",
+ shortname = Shortname.unsafeFrom("incunabula"),
shortcode = "0803",
longname = Some("Bilderfolgen Basler Frühdrucke"),
description = Seq(
@@ -487,7 +488,7 @@ object SharedTestDataADM {
/* represents the ProjectADM of the incunabula project in the external format*/
def incunabulaProjectExternal: Project = Project(
id = incunabulaProjectIri,
- shortname = "incunabula",
+ shortname = Shortname.unsafeFrom("incunabula"),
shortcode = "0803",
longname = Some("Bilderfolgen Basler Frühdrucke"),
description = Seq(
@@ -622,7 +623,7 @@ object SharedTestDataADM {
def anythingProject: Project = Project(
id = anythingProjectIri,
- shortname = "anything",
+ shortname = Shortname.unsafeFrom("anything"),
shortcode = "0001",
longname = Some("Anything Project"),
description = Seq(StringLiteralV2.from(value = "Anything Project", language = None)),
@@ -637,7 +638,7 @@ object SharedTestDataADM {
def anythingProjectExternal: Project = Project(
id = anythingProjectIri,
- shortname = "anything",
+ shortname = Shortname.unsafeFrom("anything"),
shortcode = "0001",
longname = Some("Anything Project"),
description = Seq(StringLiteralV2.from(value = "Anything Project", language = None)),
@@ -674,7 +675,7 @@ object SharedTestDataADM {
def beolProject: Project = Project(
id = beolProjectIri,
- shortname = "beol",
+ shortname = Shortname.unsafeFrom("beol"),
shortcode = "0801",
longname = Some("Bernoulli-Euler Online"),
description = Seq(StringLiteralV2.from(value = "Bernoulli-Euler Online", language = None)),
@@ -730,7 +731,7 @@ object SharedTestDataADM {
def dokubibProject: Project = Project(
id = dokubibProjectIri,
- shortname = "dokubib",
+ shortname = Shortname.unsafeFrom("dokubib"),
shortcode = "0804",
longname = Some("Dokubib"),
description = Seq(StringLiteralV2.from(value = "Dokubib", language = None)),
diff --git a/webapi/src/main/scala/org/knora/webapi/slice/admin/api/Examples.scala b/webapi/src/main/scala/org/knora/webapi/slice/admin/api/Examples.scala
index c76501dd20..10e9834c84 100644
--- a/webapi/src/main/scala/org/knora/webapi/slice/admin/api/Examples.scala
+++ b/webapi/src/main/scala/org/knora/webapi/slice/admin/api/Examples.scala
@@ -26,6 +26,7 @@ import org.knora.webapi.slice.admin.domain.model.GroupStatus
import org.knora.webapi.slice.admin.domain.model.KnoraProject.CopyrightAttribution
import org.knora.webapi.slice.admin.domain.model.KnoraProject.License
import org.knora.webapi.slice.admin.domain.model.KnoraProject.ProjectIri
+import org.knora.webapi.slice.admin.domain.model.KnoraProject.Shortname
import org.knora.webapi.slice.admin.domain.model.User
import org.knora.webapi.slice.admin.domain.model.UserIri
import org.knora.webapi.slice.admin.domain.model.UserStatus
@@ -86,7 +87,7 @@ object Examples {
private val project: Project = Project(
id = ProjectExample.projectIri.value,
- shortname = "example",
+ shortname = Shortname.unsafeFrom("example"),
shortcode = "0001",
longname = Some("Example Project"),
description = Seq(StringLiteralV2.from("An example project", Some("en"))),
diff --git a/webapi/src/main/scala/org/knora/webapi/slice/admin/api/model/ProjectsMessagesADM.scala b/webapi/src/main/scala/org/knora/webapi/slice/admin/api/model/ProjectsMessagesADM.scala
index dcab052e59..69638938ae 100644
--- a/webapi/src/main/scala/org/knora/webapi/slice/admin/api/model/ProjectsMessagesADM.scala
+++ b/webapi/src/main/scala/org/knora/webapi/slice/admin/api/model/ProjectsMessagesADM.scala
@@ -13,6 +13,7 @@ import org.knora.webapi.messages.admin.responder.AdminKnoraResponseADM
import org.knora.webapi.messages.store.triplestoremessages.StringLiteralV2
import org.knora.webapi.slice.admin.api.Codecs.ZioJsonCodec.copyrightAttribution
import org.knora.webapi.slice.admin.api.Codecs.ZioJsonCodec.license
+import org.knora.webapi.slice.admin.api.Codecs.ZioJsonCodec.shortname
import org.knora.webapi.slice.admin.domain.model.KnoraProject.*
import org.knora.webapi.slice.admin.domain.model.RestrictedView
import org.knora.webapi.slice.admin.domain.model.User
@@ -33,7 +34,7 @@ import org.knora.webapi.slice.admin.domain.model.User
*/
case class Project(
id: IRI,
- shortname: String,
+ shortname: Shortname,
shortcode: String,
longname: Option[String],
description: Seq[StringLiteralV2],
@@ -48,7 +49,6 @@ case class Project(
def projectIri: ProjectIri = ProjectIri.unsafeFrom(id)
- def getShortname: Shortname = Shortname.unsafeFrom(shortname)
def getShortcode: Shortcode = Shortcode.unsafeFrom(shortcode)
/**
diff --git a/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/service/ProjectService.scala b/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/service/ProjectService.scala
index e4af95ef9c..bc68cb1ce1 100644
--- a/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/service/ProjectService.scala
+++ b/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/service/ProjectService.scala
@@ -47,7 +47,7 @@ final case class ProjectService(
.map(ontologies =>
Project(
knoraProject.id.value,
- knoraProject.shortname.value,
+ knoraProject.shortname,
knoraProject.shortcode.value,
knoraProject.longname.map(_.value),
knoraProject.description.map(_.value),
@@ -64,7 +64,7 @@ final case class ProjectService(
private def toKnoraProject(project: Project, restrictedView: RestrictedView): KnoraProject =
KnoraProject(
id = ProjectIri.unsafeFrom(project.id),
- shortname = Shortname.unsafeFrom(project.shortname),
+ shortname = project.shortname,
shortcode = Shortcode.unsafeFrom(project.shortcode),
longname = project.longname.map(Longname.unsafeFrom),
description = NonEmptyChunk
@@ -99,8 +99,7 @@ object ProjectService {
*/
def projectDataNamedGraphV2(project: Project): InternalIri = {
val shortcode = Shortcode.unsafeFrom(project.shortcode)
- val shortname = Shortname.unsafeFrom(project.shortname)
- projectDataNamedGraphV2(shortcode, shortname)
+ projectDataNamedGraphV2(shortcode, project.shortname)
}
/**
diff --git a/webapi/src/test/scala/org/knora/webapi/slice/admin/domain/service/ProjectServiceSpec.scala b/webapi/src/test/scala/org/knora/webapi/slice/admin/domain/service/ProjectServiceSpec.scala
index e6f842faa6..61be50aa39 100644
--- a/webapi/src/test/scala/org/knora/webapi/slice/admin/domain/service/ProjectServiceSpec.scala
+++ b/webapi/src/test/scala/org/knora/webapi/slice/admin/domain/service/ProjectServiceSpec.scala
@@ -22,7 +22,7 @@ object ProjectServiceSpec extends ZIOSpecDefault {
val spec: Spec[Any, Nothing] =
suite("projectDataNamedGraphV2 should return the data named graph of a project with shortcode for")(
test("a ProjectADM") {
- val shortname = "someProject"
+ val shortname = Shortname.unsafeFrom("someProject")
val shortcode = "0001"
val p = Project(
id = IriTestConstants.Project.TestProject,
@@ -39,7 +39,7 @@ object ProjectServiceSpec extends ZIOSpecDefault {
license = None,
)
assertTrue(
- ProjectService.projectDataNamedGraphV2(p).value == s"http://www.knora.org/data/$shortcode/$shortname",
+ ProjectService.projectDataNamedGraphV2(p).value == s"http://www.knora.org/data/$shortcode/${shortname.value}",
)
},
test("a KnoraProject") {
From 0ddf7aaf601f326c9c7e3a16f803ffe19a8a5c84 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20Kleinb=C3=B6lting?=
Date: Fri, 15 Nov 2024 17:49:31 +0100
Subject: [PATCH 11/18] refactor: Make Project.shortcode typed
---
.../IntegrationTestAdminJsonProtocol.scala | 6 ++-
.../models/filemodels/FileModelsSpec.scala | 40 +++++++++----------
.../admin/ProjectRestServiceSpec.scala | 6 +--
.../webapi/sharedtestdata/ProjectInfo.scala | 2 +-
.../sharedtestdata/SharedTestDataADM.scala | 22 +++++-----
.../webapi/messages/StringFormatter.scala | 4 +-
.../webapi/responders/v2/ResourceUtilV2.scala | 2 +-
.../webapi/slice/admin/api/Examples.scala | 3 +-
.../admin/api/model/ProjectsMessagesADM.scala | 5 +--
.../admin/domain/service/ProjectService.scala | 10 ++---
.../ApiComplexV2JsonLdRequestParser.scala | 4 +-
.../domain/service/ProjectServiceSpec.scala | 8 ++--
12 files changed, 58 insertions(+), 54 deletions(-)
diff --git a/integration/src/test/scala/org/knora/webapi/messages/admin/responder/IntegrationTestAdminJsonProtocol.scala b/integration/src/test/scala/org/knora/webapi/messages/admin/responder/IntegrationTestAdminJsonProtocol.scala
index 9294bdda50..b95941ae5d 100644
--- a/integration/src/test/scala/org/knora/webapi/messages/admin/responder/IntegrationTestAdminJsonProtocol.scala
+++ b/integration/src/test/scala/org/knora/webapi/messages/admin/responder/IntegrationTestAdminJsonProtocol.scala
@@ -6,7 +6,6 @@
package org.knora.webapi.messages.admin.responder
import spray.json.*
-
import org.knora.webapi.messages.admin.responder.groupsmessages.GroupGetResponseADM
import org.knora.webapi.messages.admin.responder.groupsmessages.GroupsGetResponseADM
import org.knora.webapi.messages.admin.responder.permissionsmessages.AdministrativePermissionADM
@@ -47,6 +46,7 @@ import org.knora.webapi.slice.admin.api.model.ProjectOperationResponseADM
import org.knora.webapi.slice.admin.domain.model.Group
import org.knora.webapi.slice.admin.domain.model.KnoraProject.CopyrightAttribution
import org.knora.webapi.slice.admin.domain.model.KnoraProject.License
+import org.knora.webapi.slice.admin.domain.model.KnoraProject.Shortcode
import org.knora.webapi.slice.admin.domain.model.KnoraProject.Shortname
import org.knora.webapi.slice.admin.domain.model.User
import org.knora.webapi.slice.common.Value.StringValue
@@ -218,6 +218,10 @@ object IntegrationTestAdminJsonProtocol extends TriplestoreJsonProtocol {
override val from: String => Either[String, Shortname] = Shortname.from
}
+ implicit object ShortcodeFormat extends StringValueFormat[Shortcode] {
+ override val from: String => Either[String, Shortcode] = Shortcode.from
+ }
+
implicit val groupFormat: JsonFormat[Group] = jsonFormat6(Group.apply)
implicit val projectAdminMembersGetResponseADMFormat: RootJsonFormat[ProjectAdminMembersGetResponseADM] = rootFormat(
diff --git a/integration/src/test/scala/org/knora/webapi/models/filemodels/FileModelsSpec.scala b/integration/src/test/scala/org/knora/webapi/models/filemodels/FileModelsSpec.scala
index a3424eeda3..5ac6b34b2b 100644
--- a/integration/src/test/scala/org/knora/webapi/models/filemodels/FileModelsSpec.scala
+++ b/integration/src/test/scala/org/knora/webapi/models/filemodels/FileModelsSpec.scala
@@ -10,7 +10,6 @@ import spray.json.DefaultJsonProtocol.*
import java.time.Instant
import java.util.UUID
-
import dsp.errors.AssertionException
import org.knora.webapi.ApiV2Complex
import org.knora.webapi.CoreSpec
@@ -20,6 +19,7 @@ import org.knora.webapi.messages.v2.responder.resourcemessages.CreateValueInNewR
import org.knora.webapi.messages.v2.responder.valuemessages.DocumentFileValueContentV2
import org.knora.webapi.messages.v2.responder.valuemessages.FileValueV2
import org.knora.webapi.sharedtestdata.SharedTestDataADM
+import org.knora.webapi.slice.admin.domain.model.KnoraProject.Shortcode
class FileModelsSpec extends CoreSpec {
implicit val stringFormatter: StringFormatter = StringFormatter.getGeneralInstance
@@ -263,7 +263,7 @@ class FileModelsSpec extends CoreSpec {
.toJsonLd(
className = className,
ontologyName = ontologyName,
- shortcode = shortcode,
+ shortcode = shortcode.value,
ontologyIRI = ontologyIRI,
)
.parseJson
@@ -408,8 +408,8 @@ class FileModelsSpec extends CoreSpec {
"creating a ChangeFileRequest," should {
"create a valid representation of a DocumentRepresentation with default values" in {
- val resourceIRI = stringFormatter.makeRandomResourceIri("0000")
- val valueIRI = stringFormatter.makeRandomResourceIri("0000")
+ val resourceIRI = stringFormatter.makeRandomResourceIri(Shortcode.unsafeFrom("0000"))
+ val valueIRI = stringFormatter.makeRandomResourceIri(Shortcode.unsafeFrom("0000"))
val change = ChangeFileRequest.make(
fileType = FileType.DocumentFile(),
@@ -432,8 +432,8 @@ class FileModelsSpec extends CoreSpec {
}
"create a valid representation of a DocumentRepresentation with custom values" in {
- val resourceIRI = stringFormatter.makeRandomResourceIri("0000")
- val valueIRI = stringFormatter.makeRandomResourceIri("0000")
+ val resourceIRI = stringFormatter.makeRandomResourceIri(Shortcode.unsafeFrom("0000"))
+ val valueIRI = stringFormatter.makeRandomResourceIri(Shortcode.unsafeFrom("0000"))
val pageCount = Some(33)
val dimX = Some(44)
val dimY = Some(55)
@@ -467,8 +467,8 @@ class FileModelsSpec extends CoreSpec {
}
"create a valid representation of a StillImageRepresentation with default values" in {
- val resourceIRI = stringFormatter.makeRandomResourceIri("0000")
- val valueIRI = stringFormatter.makeRandomResourceIri("0000")
+ val resourceIRI = stringFormatter.makeRandomResourceIri(Shortcode.unsafeFrom("0000"))
+ val valueIRI = stringFormatter.makeRandomResourceIri(Shortcode.unsafeFrom("0000"))
val change = ChangeFileRequest.make(
fileType = FileType.StillImageFile(),
@@ -490,8 +490,8 @@ class FileModelsSpec extends CoreSpec {
}
"create a valid representation of a MovingImageRepresentation with default values" in {
- val resourceIRI = stringFormatter.makeRandomResourceIri("0000")
- val valueIRI = stringFormatter.makeRandomResourceIri("0000")
+ val resourceIRI = stringFormatter.makeRandomResourceIri(Shortcode.unsafeFrom("0000"))
+ val valueIRI = stringFormatter.makeRandomResourceIri(Shortcode.unsafeFrom("0000"))
val change = ChangeFileRequest.make(
fileType = FileType.MovingImageFile(),
@@ -513,8 +513,8 @@ class FileModelsSpec extends CoreSpec {
}
"create a valid representation of a AudioRepresentation with default values" in {
- val resourceIRI = stringFormatter.makeRandomResourceIri("0000")
- val valueIRI = stringFormatter.makeRandomResourceIri("0000")
+ val resourceIRI = stringFormatter.makeRandomResourceIri(Shortcode.unsafeFrom("0000"))
+ val valueIRI = stringFormatter.makeRandomResourceIri(Shortcode.unsafeFrom("0000"))
val change = ChangeFileRequest.make(
fileType = FileType.AudioFile,
@@ -531,8 +531,8 @@ class FileModelsSpec extends CoreSpec {
}
"create a valid representation of a TextRepresentation with default values" in {
- val resourceIRI = stringFormatter.makeRandomResourceIri("0000")
- val valueIRI = stringFormatter.makeRandomResourceIri("0000")
+ val resourceIRI = stringFormatter.makeRandomResourceIri(Shortcode.unsafeFrom("0000"))
+ val valueIRI = stringFormatter.makeRandomResourceIri(Shortcode.unsafeFrom("0000"))
val change = ChangeFileRequest.make(
fileType = FileType.TextFile,
@@ -549,8 +549,8 @@ class FileModelsSpec extends CoreSpec {
}
"create a valid representation of a ArchiveRepresentation with default values" in {
- val resourceIRI = stringFormatter.makeRandomResourceIri("0000")
- val valueIRI = stringFormatter.makeRandomResourceIri("0000")
+ val resourceIRI = stringFormatter.makeRandomResourceIri(Shortcode.unsafeFrom("0000"))
+ val valueIRI = stringFormatter.makeRandomResourceIri(Shortcode.unsafeFrom("0000"))
val change = ChangeFileRequest.make(
fileType = FileType.ArchiveFile,
@@ -569,8 +569,8 @@ class FileModelsSpec extends CoreSpec {
"generating a JSON-LD representation of a ChangeFileRequest," should {
"correctly serialize a DocumentRepresentation with default values" in {
- val resourceIRI = stringFormatter.makeRandomResourceIri("7777")
- val valueIRI = stringFormatter.makeRandomResourceIri("7777")
+ val resourceIRI = stringFormatter.makeRandomResourceIri(Shortcode.unsafeFrom("7777"))
+ val valueIRI = stringFormatter.makeRandomResourceIri(Shortcode.unsafeFrom("7777"))
val documentRepresentation = ChangeFileRequest.make(
fileType = FileType.DocumentFile(),
@@ -598,8 +598,8 @@ class FileModelsSpec extends CoreSpec {
}
"correctly serialize a DocumentRepresentation with custom values" in {
- val resourceIRI = stringFormatter.makeRandomResourceIri("7777")
- val valueIRI = stringFormatter.makeRandomResourceIri("7777")
+ val resourceIRI = stringFormatter.makeRandomResourceIri(Shortcode.unsafeFrom("7777"))
+ val valueIRI = stringFormatter.makeRandomResourceIri(Shortcode.unsafeFrom("7777"))
val className = "CustomDocumentRepresentation"
val prefix = "onto"
diff --git a/integration/src/test/scala/org/knora/webapi/responders/admin/ProjectRestServiceSpec.scala b/integration/src/test/scala/org/knora/webapi/responders/admin/ProjectRestServiceSpec.scala
index a64bec8480..f3d2e0101e 100644
--- a/integration/src/test/scala/org/knora/webapi/responders/admin/ProjectRestServiceSpec.scala
+++ b/integration/src/test/scala/org/knora/webapi/responders/admin/ProjectRestServiceSpec.scala
@@ -115,7 +115,7 @@ class ProjectRestServiceSpec extends CoreSpec with ImplicitSender {
"return restricted view settings using project SHORTCODE" in {
val actual = UnsafeZioRun.runOrThrow(
ProjectRestService(
- _.getProjectRestrictedViewSettingsByShortcode(SharedTestDataADM.imagesProject.getShortcode),
+ _.getProjectRestrictedViewSettingsByShortcode(SharedTestDataADM.imagesProject.shortcode),
),
)
actual shouldEqual expectedResult
@@ -468,7 +468,7 @@ class ProjectRestServiceSpec extends CoreSpec with ImplicitSender {
"return all members of a project identified by shortcode" in {
val actual = UnsafeZioRun.runOrThrow(
ProjectRestService(
- _.getProjectMembersByShortcode(SharedTestDataADM.rootUser, SharedTestDataADM.imagesProject.getShortcode),
+ _.getProjectMembersByShortcode(SharedTestDataADM.rootUser, SharedTestDataADM.imagesProject.shortcode),
),
)
@@ -545,7 +545,7 @@ class ProjectRestServiceSpec extends CoreSpec with ImplicitSender {
ProjectRestService(
_.getProjectAdminMembersByShortcode(
SharedTestDataADM.rootUser,
- SharedTestDataADM.imagesProject.getShortcode,
+ SharedTestDataADM.imagesProject.shortcode,
),
),
)
diff --git a/integration/src/test/scala/org/knora/webapi/sharedtestdata/ProjectInfo.scala b/integration/src/test/scala/org/knora/webapi/sharedtestdata/ProjectInfo.scala
index 49ea177cef..e80630d15e 100644
--- a/integration/src/test/scala/org/knora/webapi/sharedtestdata/ProjectInfo.scala
+++ b/integration/src/test/scala/org/knora/webapi/sharedtestdata/ProjectInfo.scala
@@ -39,7 +39,7 @@ object ProjectInfo {
ProjectInfo(
id = project.id,
shortname = project.shortname.value,
- shortcode = project.shortcode,
+ shortcode = project.shortcode.value,
longname = project.longname,
description = project.description.headOption.map(_.value),
keywords = project.keywords.headOption.map(_ => project.keywords.mkString(", ")),
diff --git a/integration/src/test/scala/org/knora/webapi/sharedtestdata/SharedTestDataADM.scala b/integration/src/test/scala/org/knora/webapi/sharedtestdata/SharedTestDataADM.scala
index 69711de82d..de70ae2409 100644
--- a/integration/src/test/scala/org/knora/webapi/sharedtestdata/SharedTestDataADM.scala
+++ b/integration/src/test/scala/org/knora/webapi/sharedtestdata/SharedTestDataADM.scala
@@ -6,7 +6,6 @@
package org.knora.webapi.sharedtestdata
import java.time.Instant
-
import dsp.constants.SalsahGui
import org.knora.webapi.IRI
import org.knora.webapi.messages.OntologyConstants
@@ -16,6 +15,7 @@ import org.knora.webapi.messages.store.triplestoremessages.StringLiteralV2
import org.knora.webapi.messages.util.KnoraSystemInstances
import org.knora.webapi.slice.admin.api.model.Project
import org.knora.webapi.slice.admin.domain.model.Group
+import org.knora.webapi.slice.admin.domain.model.KnoraProject.Shortcode
import org.knora.webapi.slice.admin.domain.model.KnoraProject.Shortname
import org.knora.webapi.slice.admin.domain.model.Permission
import org.knora.webapi.slice.admin.domain.model.User
@@ -157,7 +157,7 @@ object SharedTestDataADM {
def systemProject: Project = Project(
id = KnoraProjectRepo.builtIn.SystemProject.id.value,
shortname = Shortname.unsafeFrom("SystemProject"),
- shortcode = "FFFF",
+ shortcode = Shortcode.unsafeFrom("FFFF"),
longname = Some("Knora System Project"),
description = Seq(StringLiteralV2.from(value = "Knora System Project", language = Some("en"))),
keywords = Seq.empty[String],
@@ -178,7 +178,7 @@ object SharedTestDataADM {
def defaultSharedOntologiesProject: Project = Project(
id = OntologyConstants.KnoraAdmin.DefaultSharedOntologiesProject,
shortname = Shortname.unsafeFrom("DefaultSharedOntologiesProject"),
- shortcode = "0000",
+ shortcode = Shortcode.unsafeFrom("0000"),
longname = Some("Default Knora Shared Ontologies Project"),
description = Seq(StringLiteralV2.from(value = "Default Knora Shared Ontologies Project", language = Some("en"))),
keywords = Seq.empty[String],
@@ -292,7 +292,7 @@ object SharedTestDataADM {
def imagesProject: Project = Project(
id = imagesProjectIri,
shortname = Shortname.unsafeFrom("images"),
- shortcode = "00FF",
+ shortcode = Shortcode.unsafeFrom("00FF"),
longname = Some("Image Collection Demo"),
description = Seq(StringLiteralV2.from(value = "A demo project of a collection of images", language = Some("en"))),
keywords = Seq("images", "collection").sorted,
@@ -308,7 +308,7 @@ object SharedTestDataADM {
def imagesProjectExternal: Project = Project(
id = imagesProjectIri,
shortname = Shortname.unsafeFrom("images"),
- shortcode = "00FF",
+ shortcode = Shortcode.unsafeFrom("00FF"),
longname = Some("Image Collection Demo"),
description = Seq(StringLiteralV2.from(value = "A demo project of a collection of images", language = Some("en"))),
keywords = Seq("images", "collection").sorted,
@@ -452,7 +452,7 @@ object SharedTestDataADM {
def incunabulaProject: Project = Project(
id = incunabulaProjectIri,
shortname = Shortname.unsafeFrom("incunabula"),
- shortcode = "0803",
+ shortcode = Shortcode.unsafeFrom("0803"),
longname = Some("Bilderfolgen Basler Frühdrucke"),
description = Seq(
StringLiteralV2.from(
@@ -489,7 +489,7 @@ object SharedTestDataADM {
def incunabulaProjectExternal: Project = Project(
id = incunabulaProjectIri,
shortname = Shortname.unsafeFrom("incunabula"),
- shortcode = "0803",
+ shortcode = Shortcode.unsafeFrom("0803"),
longname = Some("Bilderfolgen Basler Frühdrucke"),
description = Seq(
StringLiteralV2.from(
@@ -624,7 +624,7 @@ object SharedTestDataADM {
def anythingProject: Project = Project(
id = anythingProjectIri,
shortname = Shortname.unsafeFrom("anything"),
- shortcode = "0001",
+ shortcode = Shortcode.unsafeFrom("0001"),
longname = Some("Anything Project"),
description = Seq(StringLiteralV2.from(value = "Anything Project", language = None)),
keywords = Seq("things", "arbitrary test data").sorted,
@@ -639,7 +639,7 @@ object SharedTestDataADM {
def anythingProjectExternal: Project = Project(
id = anythingProjectIri,
shortname = Shortname.unsafeFrom("anything"),
- shortcode = "0001",
+ shortcode = Shortcode.unsafeFrom("0001"),
longname = Some("Anything Project"),
description = Seq(StringLiteralV2.from(value = "Anything Project", language = None)),
keywords = Seq("things", "arbitrary test data").sorted,
@@ -676,7 +676,7 @@ object SharedTestDataADM {
def beolProject: Project = Project(
id = beolProjectIri,
shortname = Shortname.unsafeFrom("beol"),
- shortcode = "0801",
+ shortcode = Shortcode.unsafeFrom("0801"),
longname = Some("Bernoulli-Euler Online"),
description = Seq(StringLiteralV2.from(value = "Bernoulli-Euler Online", language = None)),
keywords = Seq.empty[String],
@@ -732,7 +732,7 @@ object SharedTestDataADM {
def dokubibProject: Project = Project(
id = dokubibProjectIri,
shortname = Shortname.unsafeFrom("dokubib"),
- shortcode = "0804",
+ shortcode = Shortcode.unsafeFrom("0804"),
longname = Some("Dokubib"),
description = Seq(StringLiteralV2.from(value = "Dokubib", language = None)),
keywords = Seq.empty[String],
diff --git a/webapi/src/main/scala/org/knora/webapi/messages/StringFormatter.scala b/webapi/src/main/scala/org/knora/webapi/messages/StringFormatter.scala
index 45a29961ad..003d11740c 100644
--- a/webapi/src/main/scala/org/knora/webapi/messages/StringFormatter.scala
+++ b/webapi/src/main/scala/org/knora/webapi/messages/StringFormatter.scala
@@ -1589,9 +1589,9 @@ class StringFormatter private (
* @param projectShortcode the project's shortcode.
* @return a new resource IRI.
*/
- def makeRandomResourceIri(projectShortcode: String): IRI = {
+ def makeRandomResourceIri(shortcode: Shortcode): IRI = {
val knoraResourceID = UuidUtil.makeRandomBase64EncodedUuid
- s"http://$IriDomain/$projectShortcode/$knoraResourceID"
+ s"http://$IriDomain/${shortcode.value}/$knoraResourceID"
}
/**
diff --git a/webapi/src/main/scala/org/knora/webapi/responders/v2/ResourceUtilV2.scala b/webapi/src/main/scala/org/knora/webapi/responders/v2/ResourceUtilV2.scala
index 039d676977..6f5053fc20 100644
--- a/webapi/src/main/scala/org/knora/webapi/responders/v2/ResourceUtilV2.scala
+++ b/webapi/src/main/scala/org/knora/webapi/responders/v2/ResourceUtilV2.scala
@@ -228,7 +228,7 @@ final case class ResourceUtilV2Live(triplestore: TriplestoreService, sipiService
sipiService.moveTemporaryFileToPermanentStorage(
MoveTemporaryFileToPermanentStorageRequest(
file.fileValue.internalFilename,
- updateInProject.projectADM.shortcode,
+ updateInProject.projectADM.shortcode.value,
requestingUser,
),
)
diff --git a/webapi/src/main/scala/org/knora/webapi/slice/admin/api/Examples.scala b/webapi/src/main/scala/org/knora/webapi/slice/admin/api/Examples.scala
index 10e9834c84..ffa82ece99 100644
--- a/webapi/src/main/scala/org/knora/webapi/slice/admin/api/Examples.scala
+++ b/webapi/src/main/scala/org/knora/webapi/slice/admin/api/Examples.scala
@@ -26,6 +26,7 @@ import org.knora.webapi.slice.admin.domain.model.GroupStatus
import org.knora.webapi.slice.admin.domain.model.KnoraProject.CopyrightAttribution
import org.knora.webapi.slice.admin.domain.model.KnoraProject.License
import org.knora.webapi.slice.admin.domain.model.KnoraProject.ProjectIri
+import org.knora.webapi.slice.admin.domain.model.KnoraProject.Shortcode
import org.knora.webapi.slice.admin.domain.model.KnoraProject.Shortname
import org.knora.webapi.slice.admin.domain.model.User
import org.knora.webapi.slice.admin.domain.model.UserIri
@@ -88,7 +89,7 @@ object Examples {
private val project: Project = Project(
id = ProjectExample.projectIri.value,
shortname = Shortname.unsafeFrom("example"),
- shortcode = "0001",
+ shortcode = Shortcode.unsafeFrom("0001"),
longname = Some("Example Project"),
description = Seq(StringLiteralV2.from("An example project", Some("en"))),
keywords = Seq("example", "project"),
diff --git a/webapi/src/main/scala/org/knora/webapi/slice/admin/api/model/ProjectsMessagesADM.scala b/webapi/src/main/scala/org/knora/webapi/slice/admin/api/model/ProjectsMessagesADM.scala
index 69638938ae..c57e811fde 100644
--- a/webapi/src/main/scala/org/knora/webapi/slice/admin/api/model/ProjectsMessagesADM.scala
+++ b/webapi/src/main/scala/org/knora/webapi/slice/admin/api/model/ProjectsMessagesADM.scala
@@ -14,6 +14,7 @@ import org.knora.webapi.messages.store.triplestoremessages.StringLiteralV2
import org.knora.webapi.slice.admin.api.Codecs.ZioJsonCodec.copyrightAttribution
import org.knora.webapi.slice.admin.api.Codecs.ZioJsonCodec.license
import org.knora.webapi.slice.admin.api.Codecs.ZioJsonCodec.shortname
+import org.knora.webapi.slice.admin.api.Codecs.ZioJsonCodec.shortcode
import org.knora.webapi.slice.admin.domain.model.KnoraProject.*
import org.knora.webapi.slice.admin.domain.model.RestrictedView
import org.knora.webapi.slice.admin.domain.model.User
@@ -35,7 +36,7 @@ import org.knora.webapi.slice.admin.domain.model.User
case class Project(
id: IRI,
shortname: Shortname,
- shortcode: String,
+ shortcode: Shortcode,
longname: Option[String],
description: Seq[StringLiteralV2],
keywords: Seq[String],
@@ -49,8 +50,6 @@ case class Project(
def projectIri: ProjectIri = ProjectIri.unsafeFrom(id)
- def getShortcode: Shortcode = Shortcode.unsafeFrom(shortcode)
-
/**
* Allows to sort collections of ProjectADM. Sorting is done by the id.
*/
diff --git a/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/service/ProjectService.scala b/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/service/ProjectService.scala
index bc68cb1ce1..c38609a76d 100644
--- a/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/service/ProjectService.scala
+++ b/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/service/ProjectService.scala
@@ -48,7 +48,7 @@ final case class ProjectService(
Project(
knoraProject.id.value,
knoraProject.shortname,
- knoraProject.shortcode.value,
+ knoraProject.shortcode,
knoraProject.longname.map(_.value),
knoraProject.description.map(_.value),
knoraProject.keywords.map(_.value),
@@ -65,7 +65,7 @@ final case class ProjectService(
KnoraProject(
id = ProjectIri.unsafeFrom(project.id),
shortname = project.shortname,
- shortcode = Shortcode.unsafeFrom(project.shortcode),
+ shortcode = project.shortcode,
longname = project.longname.map(Longname.unsafeFrom),
description = NonEmptyChunk
.fromIterable(project.description.head, project.description.tail)
@@ -97,10 +97,8 @@ object ProjectService {
* @param project A [[ProjectADM]].
* @return the [[InternalIri]] of the project's data named graph.
*/
- def projectDataNamedGraphV2(project: Project): InternalIri = {
- val shortcode = Shortcode.unsafeFrom(project.shortcode)
- projectDataNamedGraphV2(shortcode, project.shortname)
- }
+ def projectDataNamedGraphV2(project: Project): InternalIri =
+ projectDataNamedGraphV2(project.shortcode, project.shortname)
/**
* Given the [[KnoraProject]] constructs the project's data named graph.
diff --git a/webapi/src/main/scala/org/knora/webapi/slice/common/ApiComplexV2JsonLdRequestParser.scala b/webapi/src/main/scala/org/knora/webapi/slice/common/ApiComplexV2JsonLdRequestParser.scala
index e1aec3eb14..23f7593ece 100644
--- a/webapi/src/main/scala/org/knora/webapi/slice/common/ApiComplexV2JsonLdRequestParser.scala
+++ b/webapi/src/main/scala/org/knora/webapi/slice/common/ApiComplexV2JsonLdRequestParser.scala
@@ -242,9 +242,9 @@ final case class ApiComplexV2JsonLdRequestParser(
project <- attachedToProject(r.resource)
_ <- ZIO
.fail("Resource IRI and project IRI must reference the same project")
- .when(r.resourceIri.exists(_.shortcode != project.getShortcode))
+ .when(r.resourceIri.exists(_.shortcode != project.shortcode))
attachedToUser <- attachedToUser(r.resource, requestingUser, project.projectIri)
- values <- extractValues(r.resource, project.getShortcode, ingestState)
+ values <- extractValues(r.resource, project.shortcode, ingestState)
} yield CreateResourceRequestV2(
CreateResourceV2(
r.resourceIri.map(_.smartIri),
diff --git a/webapi/src/test/scala/org/knora/webapi/slice/admin/domain/service/ProjectServiceSpec.scala b/webapi/src/test/scala/org/knora/webapi/slice/admin/domain/service/ProjectServiceSpec.scala
index 61be50aa39..c99ef6a836 100644
--- a/webapi/src/test/scala/org/knora/webapi/slice/admin/domain/service/ProjectServiceSpec.scala
+++ b/webapi/src/test/scala/org/knora/webapi/slice/admin/domain/service/ProjectServiceSpec.scala
@@ -20,10 +20,10 @@ import org.knora.webapi.slice.resourceinfo.domain.IriTestConstants
object ProjectServiceSpec extends ZIOSpecDefault {
val spec: Spec[Any, Nothing] =
- suite("projectDataNamedGraphV2 should return the data named graph of a project with shortcode for")(
+ suite("projectDataNamedGraphV2 shouldshortcodefor")(
test("a ProjectADM") {
val shortname = Shortname.unsafeFrom("someProject")
- val shortcode = "0001"
+ val shortcode = Shortcode.unsafeFrom("0001")
val p = Project(
id = IriTestConstants.Project.TestProject,
shortname = shortname,
@@ -39,7 +39,9 @@ object ProjectServiceSpec extends ZIOSpecDefault {
license = None,
)
assertTrue(
- ProjectService.projectDataNamedGraphV2(p).value == s"http://www.knora.org/data/$shortcode/${shortname.value}",
+ ProjectService
+ .projectDataNamedGraphV2(p)
+ .value == s"http://www.knora.org/data/${shortcode.value}/${shortname.value}",
)
},
test("a KnoraProject") {
From 209af475a73fd49b093f97336f28f9b1955debd1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20Kleinb=C3=B6lting?=
Date: Fri, 15 Nov 2024 17:53:46 +0100
Subject: [PATCH 12/18] refactor: Make Project.longname typed
---
.../IntegrationTestAdminJsonProtocol.scala | 5 +++++
.../webapi/sharedtestdata/ProjectInfo.scala | 2 +-
.../sharedtestdata/SharedTestDataADM.scala | 21 ++++++++++---------
.../webapi/slice/admin/api/Examples.scala | 3 ++-
.../admin/api/model/ProjectsMessagesADM.scala | 7 ++-----
.../admin/domain/service/ProjectService.scala | 4 ++--
6 files changed, 23 insertions(+), 19 deletions(-)
diff --git a/integration/src/test/scala/org/knora/webapi/messages/admin/responder/IntegrationTestAdminJsonProtocol.scala b/integration/src/test/scala/org/knora/webapi/messages/admin/responder/IntegrationTestAdminJsonProtocol.scala
index b95941ae5d..928dbd7689 100644
--- a/integration/src/test/scala/org/knora/webapi/messages/admin/responder/IntegrationTestAdminJsonProtocol.scala
+++ b/integration/src/test/scala/org/knora/webapi/messages/admin/responder/IntegrationTestAdminJsonProtocol.scala
@@ -46,6 +46,7 @@ import org.knora.webapi.slice.admin.api.model.ProjectOperationResponseADM
import org.knora.webapi.slice.admin.domain.model.Group
import org.knora.webapi.slice.admin.domain.model.KnoraProject.CopyrightAttribution
import org.knora.webapi.slice.admin.domain.model.KnoraProject.License
+import org.knora.webapi.slice.admin.domain.model.KnoraProject.Longname
import org.knora.webapi.slice.admin.domain.model.KnoraProject.Shortcode
import org.knora.webapi.slice.admin.domain.model.KnoraProject.Shortname
import org.knora.webapi.slice.admin.domain.model.User
@@ -222,6 +223,10 @@ object IntegrationTestAdminJsonProtocol extends TriplestoreJsonProtocol {
override val from: String => Either[String, Shortcode] = Shortcode.from
}
+ implicit object LongnameFormat extends StringValueFormat[Longname] {
+ override val from: String => Either[String, Longname] = Longname.from
+ }
+
implicit val groupFormat: JsonFormat[Group] = jsonFormat6(Group.apply)
implicit val projectAdminMembersGetResponseADMFormat: RootJsonFormat[ProjectAdminMembersGetResponseADM] = rootFormat(
diff --git a/integration/src/test/scala/org/knora/webapi/sharedtestdata/ProjectInfo.scala b/integration/src/test/scala/org/knora/webapi/sharedtestdata/ProjectInfo.scala
index e80630d15e..a9358038c5 100644
--- a/integration/src/test/scala/org/knora/webapi/sharedtestdata/ProjectInfo.scala
+++ b/integration/src/test/scala/org/knora/webapi/sharedtestdata/ProjectInfo.scala
@@ -40,7 +40,7 @@ object ProjectInfo {
id = project.id,
shortname = project.shortname.value,
shortcode = project.shortcode.value,
- longname = project.longname,
+ longname = project.longname.map(_.value),
description = project.description.headOption.map(_.value),
keywords = project.keywords.headOption.map(_ => project.keywords.mkString(", ")),
logo = project.logo,
diff --git a/integration/src/test/scala/org/knora/webapi/sharedtestdata/SharedTestDataADM.scala b/integration/src/test/scala/org/knora/webapi/sharedtestdata/SharedTestDataADM.scala
index de70ae2409..62eb471830 100644
--- a/integration/src/test/scala/org/knora/webapi/sharedtestdata/SharedTestDataADM.scala
+++ b/integration/src/test/scala/org/knora/webapi/sharedtestdata/SharedTestDataADM.scala
@@ -15,6 +15,7 @@ import org.knora.webapi.messages.store.triplestoremessages.StringLiteralV2
import org.knora.webapi.messages.util.KnoraSystemInstances
import org.knora.webapi.slice.admin.api.model.Project
import org.knora.webapi.slice.admin.domain.model.Group
+import org.knora.webapi.slice.admin.domain.model.KnoraProject.Longname
import org.knora.webapi.slice.admin.domain.model.KnoraProject.Shortcode
import org.knora.webapi.slice.admin.domain.model.KnoraProject.Shortname
import org.knora.webapi.slice.admin.domain.model.Permission
@@ -158,7 +159,7 @@ object SharedTestDataADM {
id = KnoraProjectRepo.builtIn.SystemProject.id.value,
shortname = Shortname.unsafeFrom("SystemProject"),
shortcode = Shortcode.unsafeFrom("FFFF"),
- longname = Some("Knora System Project"),
+ longname = Some(Longname.unsafeFrom("Knora System Project")),
description = Seq(StringLiteralV2.from(value = "Knora System Project", language = Some("en"))),
keywords = Seq.empty[String],
logo = None,
@@ -179,7 +180,7 @@ object SharedTestDataADM {
id = OntologyConstants.KnoraAdmin.DefaultSharedOntologiesProject,
shortname = Shortname.unsafeFrom("DefaultSharedOntologiesProject"),
shortcode = Shortcode.unsafeFrom("0000"),
- longname = Some("Default Knora Shared Ontologies Project"),
+ longname = Some(Longname.unsafeFrom("Default Knora Shared Ontologies Project")),
description = Seq(StringLiteralV2.from(value = "Default Knora Shared Ontologies Project", language = Some("en"))),
keywords = Seq.empty[String],
logo = None,
@@ -293,7 +294,7 @@ object SharedTestDataADM {
id = imagesProjectIri,
shortname = Shortname.unsafeFrom("images"),
shortcode = Shortcode.unsafeFrom("00FF"),
- longname = Some("Image Collection Demo"),
+ longname = Some(Longname.unsafeFrom("Image Collection Demo")),
description = Seq(StringLiteralV2.from(value = "A demo project of a collection of images", language = Some("en"))),
keywords = Seq("images", "collection").sorted,
logo = None,
@@ -309,7 +310,7 @@ object SharedTestDataADM {
id = imagesProjectIri,
shortname = Shortname.unsafeFrom("images"),
shortcode = Shortcode.unsafeFrom("00FF"),
- longname = Some("Image Collection Demo"),
+ longname = Some(Longname.unsafeFrom("Image Collection Demo")),
description = Seq(StringLiteralV2.from(value = "A demo project of a collection of images", language = Some("en"))),
keywords = Seq("images", "collection").sorted,
logo = None,
@@ -453,7 +454,7 @@ object SharedTestDataADM {
id = incunabulaProjectIri,
shortname = Shortname.unsafeFrom("incunabula"),
shortcode = Shortcode.unsafeFrom("0803"),
- longname = Some("Bilderfolgen Basler Frühdrucke"),
+ longname = Some(Longname.unsafeFrom("Bilderfolgen Basler Frühdrucke")),
description = Seq(
StringLiteralV2.from(
value =
@@ -490,7 +491,7 @@ object SharedTestDataADM {
id = incunabulaProjectIri,
shortname = Shortname.unsafeFrom("incunabula"),
shortcode = Shortcode.unsafeFrom("0803"),
- longname = Some("Bilderfolgen Basler Frühdrucke"),
+ longname = Some(Longname.unsafeFrom("Bilderfolgen Basler Frühdrucke")),
description = Seq(
StringLiteralV2.from(
value =
@@ -625,7 +626,7 @@ object SharedTestDataADM {
id = anythingProjectIri,
shortname = Shortname.unsafeFrom("anything"),
shortcode = Shortcode.unsafeFrom("0001"),
- longname = Some("Anything Project"),
+ longname = Some(Longname.unsafeFrom("Anything Project")),
description = Seq(StringLiteralV2.from(value = "Anything Project", language = None)),
keywords = Seq("things", "arbitrary test data").sorted,
logo = None,
@@ -640,7 +641,7 @@ object SharedTestDataADM {
id = anythingProjectIri,
shortname = Shortname.unsafeFrom("anything"),
shortcode = Shortcode.unsafeFrom("0001"),
- longname = Some("Anything Project"),
+ longname = Some(Longname.unsafeFrom("Anything Project")),
description = Seq(StringLiteralV2.from(value = "Anything Project", language = None)),
keywords = Seq("things", "arbitrary test data").sorted,
logo = None,
@@ -677,7 +678,7 @@ object SharedTestDataADM {
id = beolProjectIri,
shortname = Shortname.unsafeFrom("beol"),
shortcode = Shortcode.unsafeFrom("0801"),
- longname = Some("Bernoulli-Euler Online"),
+ longname = Some(Longname.unsafeFrom("Bernoulli-Euler Online")),
description = Seq(StringLiteralV2.from(value = "Bernoulli-Euler Online", language = None)),
keywords = Seq.empty[String],
logo = None,
@@ -733,7 +734,7 @@ object SharedTestDataADM {
id = dokubibProjectIri,
shortname = Shortname.unsafeFrom("dokubib"),
shortcode = Shortcode.unsafeFrom("0804"),
- longname = Some("Dokubib"),
+ longname = Some(Longname.unsafeFrom("Dokubib")),
description = Seq(StringLiteralV2.from(value = "Dokubib", language = None)),
keywords = Seq.empty[String],
logo = None,
diff --git a/webapi/src/main/scala/org/knora/webapi/slice/admin/api/Examples.scala b/webapi/src/main/scala/org/knora/webapi/slice/admin/api/Examples.scala
index ffa82ece99..1cccf78209 100644
--- a/webapi/src/main/scala/org/knora/webapi/slice/admin/api/Examples.scala
+++ b/webapi/src/main/scala/org/knora/webapi/slice/admin/api/Examples.scala
@@ -25,6 +25,7 @@ import org.knora.webapi.slice.admin.domain.model.GroupSelfJoin
import org.knora.webapi.slice.admin.domain.model.GroupStatus
import org.knora.webapi.slice.admin.domain.model.KnoraProject.CopyrightAttribution
import org.knora.webapi.slice.admin.domain.model.KnoraProject.License
+import org.knora.webapi.slice.admin.domain.model.KnoraProject.Longname
import org.knora.webapi.slice.admin.domain.model.KnoraProject.ProjectIri
import org.knora.webapi.slice.admin.domain.model.KnoraProject.Shortcode
import org.knora.webapi.slice.admin.domain.model.KnoraProject.Shortname
@@ -90,7 +91,7 @@ object Examples {
id = ProjectExample.projectIri.value,
shortname = Shortname.unsafeFrom("example"),
shortcode = Shortcode.unsafeFrom("0001"),
- longname = Some("Example Project"),
+ longname = Some(Longname.unsafeFrom("Example Project")),
description = Seq(StringLiteralV2.from("An example project", Some("en"))),
keywords = Seq("example", "project"),
logo = None,
diff --git a/webapi/src/main/scala/org/knora/webapi/slice/admin/api/model/ProjectsMessagesADM.scala b/webapi/src/main/scala/org/knora/webapi/slice/admin/api/model/ProjectsMessagesADM.scala
index c57e811fde..b259dd1e4d 100644
--- a/webapi/src/main/scala/org/knora/webapi/slice/admin/api/model/ProjectsMessagesADM.scala
+++ b/webapi/src/main/scala/org/knora/webapi/slice/admin/api/model/ProjectsMessagesADM.scala
@@ -11,10 +11,7 @@ import zio.json.JsonCodec
import org.knora.webapi.IRI
import org.knora.webapi.messages.admin.responder.AdminKnoraResponseADM
import org.knora.webapi.messages.store.triplestoremessages.StringLiteralV2
-import org.knora.webapi.slice.admin.api.Codecs.ZioJsonCodec.copyrightAttribution
-import org.knora.webapi.slice.admin.api.Codecs.ZioJsonCodec.license
-import org.knora.webapi.slice.admin.api.Codecs.ZioJsonCodec.shortname
-import org.knora.webapi.slice.admin.api.Codecs.ZioJsonCodec.shortcode
+import org.knora.webapi.slice.admin.api.Codecs.ZioJsonCodec.*
import org.knora.webapi.slice.admin.domain.model.KnoraProject.*
import org.knora.webapi.slice.admin.domain.model.RestrictedView
import org.knora.webapi.slice.admin.domain.model.User
@@ -37,7 +34,7 @@ case class Project(
id: IRI,
shortname: Shortname,
shortcode: Shortcode,
- longname: Option[String],
+ longname: Option[Longname],
description: Seq[StringLiteralV2],
keywords: Seq[String],
logo: Option[String],
diff --git a/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/service/ProjectService.scala b/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/service/ProjectService.scala
index c38609a76d..da4183a29d 100644
--- a/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/service/ProjectService.scala
+++ b/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/service/ProjectService.scala
@@ -49,7 +49,7 @@ final case class ProjectService(
knoraProject.id.value,
knoraProject.shortname,
knoraProject.shortcode,
- knoraProject.longname.map(_.value),
+ knoraProject.longname,
knoraProject.description.map(_.value),
knoraProject.keywords.map(_.value),
knoraProject.logo.map(_.value),
@@ -66,7 +66,7 @@ final case class ProjectService(
id = ProjectIri.unsafeFrom(project.id),
shortname = project.shortname,
shortcode = project.shortcode,
- longname = project.longname.map(Longname.unsafeFrom),
+ longname = project.longname,
description = NonEmptyChunk
.fromIterable(project.description.head, project.description.tail)
.map(Description.unsafeFrom),
From 3fb6603c7a1c7707324d69f4311fde32a0f9d8aa Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20Kleinb=C3=B6lting?=
Date: Fri, 15 Nov 2024 17:56:08 +0100
Subject: [PATCH 13/18] refactor: Make Project.logo typed
---
.../admin/responder/IntegrationTestAdminJsonProtocol.scala | 5 +++++
.../scala/org/knora/webapi/sharedtestdata/ProjectInfo.scala | 2 +-
.../org/knora/webapi/sharedtestdata/SharedTestDataADM.scala | 5 +++--
.../webapi/slice/admin/api/model/ProjectsMessagesADM.scala | 2 +-
.../webapi/slice/admin/domain/service/ProjectService.scala | 4 ++--
5 files changed, 12 insertions(+), 6 deletions(-)
diff --git a/integration/src/test/scala/org/knora/webapi/messages/admin/responder/IntegrationTestAdminJsonProtocol.scala b/integration/src/test/scala/org/knora/webapi/messages/admin/responder/IntegrationTestAdminJsonProtocol.scala
index 928dbd7689..b62cd3b10c 100644
--- a/integration/src/test/scala/org/knora/webapi/messages/admin/responder/IntegrationTestAdminJsonProtocol.scala
+++ b/integration/src/test/scala/org/knora/webapi/messages/admin/responder/IntegrationTestAdminJsonProtocol.scala
@@ -46,6 +46,7 @@ import org.knora.webapi.slice.admin.api.model.ProjectOperationResponseADM
import org.knora.webapi.slice.admin.domain.model.Group
import org.knora.webapi.slice.admin.domain.model.KnoraProject.CopyrightAttribution
import org.knora.webapi.slice.admin.domain.model.KnoraProject.License
+import org.knora.webapi.slice.admin.domain.model.KnoraProject.Logo
import org.knora.webapi.slice.admin.domain.model.KnoraProject.Longname
import org.knora.webapi.slice.admin.domain.model.KnoraProject.Shortcode
import org.knora.webapi.slice.admin.domain.model.KnoraProject.Shortname
@@ -227,6 +228,10 @@ object IntegrationTestAdminJsonProtocol extends TriplestoreJsonProtocol {
override val from: String => Either[String, Longname] = Longname.from
}
+ implicit object LogoFormat extends StringValueFormat[Logo] {
+ override val from: String => Either[String, Logo] = Logo.from
+ }
+
implicit val groupFormat: JsonFormat[Group] = jsonFormat6(Group.apply)
implicit val projectAdminMembersGetResponseADMFormat: RootJsonFormat[ProjectAdminMembersGetResponseADM] = rootFormat(
diff --git a/integration/src/test/scala/org/knora/webapi/sharedtestdata/ProjectInfo.scala b/integration/src/test/scala/org/knora/webapi/sharedtestdata/ProjectInfo.scala
index a9358038c5..b3aff19c8e 100644
--- a/integration/src/test/scala/org/knora/webapi/sharedtestdata/ProjectInfo.scala
+++ b/integration/src/test/scala/org/knora/webapi/sharedtestdata/ProjectInfo.scala
@@ -43,7 +43,7 @@ object ProjectInfo {
longname = project.longname.map(_.value),
description = project.description.headOption.map(_.value),
keywords = project.keywords.headOption.map(_ => project.keywords.mkString(", ")),
- logo = project.logo,
+ logo = project.logo.map(_.value),
ontologies = project.ontologies,
status = project.status,
selfjoin = project.selfjoin,
diff --git a/integration/src/test/scala/org/knora/webapi/sharedtestdata/SharedTestDataADM.scala b/integration/src/test/scala/org/knora/webapi/sharedtestdata/SharedTestDataADM.scala
index 62eb471830..1f0b5a036e 100644
--- a/integration/src/test/scala/org/knora/webapi/sharedtestdata/SharedTestDataADM.scala
+++ b/integration/src/test/scala/org/knora/webapi/sharedtestdata/SharedTestDataADM.scala
@@ -15,6 +15,7 @@ import org.knora.webapi.messages.store.triplestoremessages.StringLiteralV2
import org.knora.webapi.messages.util.KnoraSystemInstances
import org.knora.webapi.slice.admin.api.model.Project
import org.knora.webapi.slice.admin.domain.model.Group
+import org.knora.webapi.slice.admin.domain.model.KnoraProject.Logo
import org.knora.webapi.slice.admin.domain.model.KnoraProject.Longname
import org.knora.webapi.slice.admin.domain.model.KnoraProject.Shortcode
import org.knora.webapi.slice.admin.domain.model.KnoraProject.Shortname
@@ -478,7 +479,7 @@ object SharedTestDataADM {
"Basel",
"Contectualisation of images",
).sorted,
- logo = Some("incunabula_logo.png"),
+ logo = Some(Logo.unsafeFrom("incunabula_logo.png")),
ontologies = Seq(SharedOntologyTestDataADM.INCUNABULA_ONTOLOGY_IRI),
status = true,
selfjoin = false,
@@ -515,7 +516,7 @@ object SharedTestDataADM {
"Basel",
"Contectualisation of images",
).sorted,
- logo = Some("incunabula_logo.png"),
+ logo = Some(Logo.unsafeFrom("incunabula_logo.png")),
ontologies = Seq(SharedOntologyTestDataADM.INCUNABULA_ONTOLOGY_IRI_LocalHost),
status = true,
selfjoin = false,
diff --git a/webapi/src/main/scala/org/knora/webapi/slice/admin/api/model/ProjectsMessagesADM.scala b/webapi/src/main/scala/org/knora/webapi/slice/admin/api/model/ProjectsMessagesADM.scala
index b259dd1e4d..bc39ef8e28 100644
--- a/webapi/src/main/scala/org/knora/webapi/slice/admin/api/model/ProjectsMessagesADM.scala
+++ b/webapi/src/main/scala/org/knora/webapi/slice/admin/api/model/ProjectsMessagesADM.scala
@@ -37,7 +37,7 @@ case class Project(
longname: Option[Longname],
description: Seq[StringLiteralV2],
keywords: Seq[String],
- logo: Option[String],
+ logo: Option[Logo],
ontologies: Seq[IRI],
status: Boolean,
selfjoin: Boolean,
diff --git a/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/service/ProjectService.scala b/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/service/ProjectService.scala
index da4183a29d..f474b748d5 100644
--- a/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/service/ProjectService.scala
+++ b/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/service/ProjectService.scala
@@ -52,7 +52,7 @@ final case class ProjectService(
knoraProject.longname,
knoraProject.description.map(_.value),
knoraProject.keywords.map(_.value),
- knoraProject.logo.map(_.value),
+ knoraProject.logo,
ontologies,
knoraProject.status.value,
knoraProject.selfjoin.value,
@@ -71,7 +71,7 @@ final case class ProjectService(
.fromIterable(project.description.head, project.description.tail)
.map(Description.unsafeFrom),
keywords = project.keywords.map(Keyword.unsafeFrom).toList,
- logo = project.logo.map(Logo.unsafeFrom),
+ logo = project.logo,
status = Status.from(project.status),
selfjoin = SelfJoin.from(project.selfjoin),
restrictedView,
From 48f6180db20068d45b655ec4b0e55bca745887c2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20Kleinb=C3=B6lting?=
Date: Fri, 15 Nov 2024 18:04:23 +0100
Subject: [PATCH 14/18] refactor: Make Project.selfjoin typed
---
.../webapi/e2e/admin/ProjectsADME2ESpec.scala | 6 ++--
.../IntegrationTestAdminJsonProtocol.scala | 14 +++++++++
.../admin/ProjectRestServiceSpec.scala | 2 +-
.../webapi/sharedtestdata/ProjectInfo.scala | 2 +-
.../sharedtestdata/SharedTestDataADM.scala | 29 ++++++++++---------
.../webapi/slice/admin/api/Examples.scala | 3 +-
.../admin/api/model/ProjectsMessagesADM.scala | 2 +-
.../admin/domain/service/ProjectService.scala | 4 +--
.../domain/service/ProjectServiceSpec.scala | 2 +-
9 files changed, 40 insertions(+), 24 deletions(-)
diff --git a/integration/src/test/scala/org/knora/webapi/e2e/admin/ProjectsADME2ESpec.scala b/integration/src/test/scala/org/knora/webapi/e2e/admin/ProjectsADME2ESpec.scala
index c651e0cff7..dd8db41e8f 100644
--- a/integration/src/test/scala/org/knora/webapi/e2e/admin/ProjectsADME2ESpec.scala
+++ b/integration/src/test/scala/org/knora/webapi/e2e/admin/ProjectsADME2ESpec.scala
@@ -19,7 +19,6 @@ import java.net.URLEncoder
import scala.concurrent.Await
import scala.concurrent.Future
import scala.concurrent.duration.*
-
import org.knora.webapi.E2ESpec
import org.knora.webapi.IRI
import org.knora.webapi.messages.admin.responder.IntegrationTestAdminJsonProtocol.*
@@ -29,6 +28,7 @@ import org.knora.webapi.messages.util.rdf.RdfModel
import org.knora.webapi.sharedtestdata.SharedTestDataADM
import org.knora.webapi.slice.admin.api.model.*
import org.knora.webapi.slice.admin.api.model.ProjectMembersGetResponseADM
+import org.knora.webapi.slice.admin.domain.model.KnoraProject.SelfJoin
import org.knora.webapi.slice.admin.domain.model.User
import org.knora.webapi.util.AkkaHttpUtils
import org.knora.webapi.util.MutableTestIri
@@ -236,7 +236,7 @@ class ProjectsADME2ESpec extends E2ESpec with SprayJsonSupport {
result.keywords should be(Seq("keywords"))
result.logo should be(Some("/fu/bar/baz.jpg"))
result.status should be(true)
- result.selfjoin should be(false)
+ result.selfjoin should be(SelfJoin.CannotJoin)
newProjectIri.set(result.id)
}
@@ -363,7 +363,7 @@ class ProjectsADME2ESpec extends E2ESpec with SprayJsonSupport {
result.keywords.sorted should be(Seq("updated", "keywords").sorted)
result.logo should be(Some("/fu/bar/baz-updated.jpg"))
result.status should be(true)
- result.selfjoin should be(true)
+ result.selfjoin should be(SelfJoin.CanJoin)
}
"UPDATE a project with multi-language description" in {
diff --git a/integration/src/test/scala/org/knora/webapi/messages/admin/responder/IntegrationTestAdminJsonProtocol.scala b/integration/src/test/scala/org/knora/webapi/messages/admin/responder/IntegrationTestAdminJsonProtocol.scala
index b62cd3b10c..991d7faeab 100644
--- a/integration/src/test/scala/org/knora/webapi/messages/admin/responder/IntegrationTestAdminJsonProtocol.scala
+++ b/integration/src/test/scala/org/knora/webapi/messages/admin/responder/IntegrationTestAdminJsonProtocol.scala
@@ -48,9 +48,11 @@ import org.knora.webapi.slice.admin.domain.model.KnoraProject.CopyrightAttributi
import org.knora.webapi.slice.admin.domain.model.KnoraProject.License
import org.knora.webapi.slice.admin.domain.model.KnoraProject.Logo
import org.knora.webapi.slice.admin.domain.model.KnoraProject.Longname
+import org.knora.webapi.slice.admin.domain.model.KnoraProject.SelfJoin
import org.knora.webapi.slice.admin.domain.model.KnoraProject.Shortcode
import org.knora.webapi.slice.admin.domain.model.KnoraProject.Shortname
import org.knora.webapi.slice.admin.domain.model.User
+import org.knora.webapi.slice.common.Value.BooleanValue
import org.knora.webapi.slice.common.Value.StringValue
/**
@@ -232,6 +234,18 @@ object IntegrationTestAdminJsonProtocol extends TriplestoreJsonProtocol {
override val from: String => Either[String, Logo] = Logo.from
}
+ trait BooleanValueFormat[T <: BooleanValue] extends JsonFormat[T] { self =>
+ def from: Boolean => Either[String, T]
+ override def write(v: T): JsValue = JsString(v.value.toString)
+ override def read(json: JsValue): T = json match
+ case JsBoolean(bool) => self.from(bool).fold(err => throw DeserializationException(err), identity)
+ case _ => throw DeserializationException("Must be a json Boolean")
+ }
+
+ implicit object SelfJoinValueFormat extends BooleanValueFormat[SelfJoin] {
+ override val from: Boolean => Either[String, SelfJoin] = b => Right(SelfJoin.from(b))
+ }
+
implicit val groupFormat: JsonFormat[Group] = jsonFormat6(Group.apply)
implicit val projectAdminMembersGetResponseADMFormat: RootJsonFormat[ProjectAdminMembersGetResponseADM] = rootFormat(
diff --git a/integration/src/test/scala/org/knora/webapi/responders/admin/ProjectRestServiceSpec.scala b/integration/src/test/scala/org/knora/webapi/responders/admin/ProjectRestServiceSpec.scala
index f3d2e0101e..81664b9293 100644
--- a/integration/src/test/scala/org/knora/webapi/responders/admin/ProjectRestServiceSpec.scala
+++ b/integration/src/test/scala/org/knora/webapi/responders/admin/ProjectRestServiceSpec.scala
@@ -411,7 +411,7 @@ class ProjectRestServiceSpec extends CoreSpec with ImplicitSender {
received.project.keywords.sorted should be(Seq("updated", "keywords").sorted)
received.project.logo should be(Some("/fu/bar/baz-updated.jpg"))
received.project.status should be(true)
- received.project.selfjoin should be(true)
+ received.project.selfjoin should be(SelfJoin.CanJoin)
}
"return 'NotFound' if a not existing project IRI is submitted during update" in {
diff --git a/integration/src/test/scala/org/knora/webapi/sharedtestdata/ProjectInfo.scala b/integration/src/test/scala/org/knora/webapi/sharedtestdata/ProjectInfo.scala
index b3aff19c8e..26a92aa4de 100644
--- a/integration/src/test/scala/org/knora/webapi/sharedtestdata/ProjectInfo.scala
+++ b/integration/src/test/scala/org/knora/webapi/sharedtestdata/ProjectInfo.scala
@@ -46,6 +46,6 @@ object ProjectInfo {
logo = project.logo.map(_.value),
ontologies = project.ontologies,
status = project.status,
- selfjoin = project.selfjoin,
+ selfjoin = project.selfjoin.value,
)
}
diff --git a/integration/src/test/scala/org/knora/webapi/sharedtestdata/SharedTestDataADM.scala b/integration/src/test/scala/org/knora/webapi/sharedtestdata/SharedTestDataADM.scala
index 1f0b5a036e..a4c47daf80 100644
--- a/integration/src/test/scala/org/knora/webapi/sharedtestdata/SharedTestDataADM.scala
+++ b/integration/src/test/scala/org/knora/webapi/sharedtestdata/SharedTestDataADM.scala
@@ -17,6 +17,7 @@ import org.knora.webapi.slice.admin.api.model.Project
import org.knora.webapi.slice.admin.domain.model.Group
import org.knora.webapi.slice.admin.domain.model.KnoraProject.Logo
import org.knora.webapi.slice.admin.domain.model.KnoraProject.Longname
+import org.knora.webapi.slice.admin.domain.model.KnoraProject.SelfJoin
import org.knora.webapi.slice.admin.domain.model.KnoraProject.Shortcode
import org.knora.webapi.slice.admin.domain.model.KnoraProject.Shortname
import org.knora.webapi.slice.admin.domain.model.Permission
@@ -171,7 +172,7 @@ object SharedTestDataADM {
OntologyConstants.Standoff.StandoffOntologyIri,
),
status = true,
- selfjoin = false,
+ selfjoin = SelfJoin.CannotJoin,
copyrightAttribution = None,
license = None,
)
@@ -187,7 +188,7 @@ object SharedTestDataADM {
logo = None,
ontologies = Seq.empty[IRI],
status = true,
- selfjoin = false,
+ selfjoin = SelfJoin.CannotJoin,
copyrightAttribution = None,
license = None,
)
@@ -301,7 +302,7 @@ object SharedTestDataADM {
logo = None,
ontologies = Seq(SharedOntologyTestDataADM.IMAGES_ONTOLOGY_IRI),
status = true,
- selfjoin = false,
+ selfjoin = SelfJoin.CannotJoin,
copyrightAttribution = None,
license = None,
)
@@ -317,7 +318,7 @@ object SharedTestDataADM {
logo = None,
ontologies = Seq(SharedOntologyTestDataADM.IMAGES_ONTOLOGY_IRI_LocalHost),
status = true,
- selfjoin = false,
+ selfjoin = SelfJoin.CannotJoin,
copyrightAttribution = None,
license = None,
)
@@ -329,7 +330,7 @@ object SharedTestDataADM {
descriptions = Seq(StringLiteralV2.from(value = "Default Project Admin Group", language = Some("en"))),
project = Some(imagesProject),
status = true,
- selfjoin = false,
+ selfjoin = SelfJoin.CannotJoin,
)
/* represents the full GroupADM of the images ProjectMember group */
@@ -339,7 +340,7 @@ object SharedTestDataADM {
descriptions = Seq(StringLiteralV2.from(value = "Default Project Member Group", language = Some("en"))),
project = Some(imagesProject),
status = true,
- selfjoin = false,
+ selfjoin = SelfJoin.CannotJoin,
)
/* represents the full GroupADM of the images project reviewer group */
@@ -349,7 +350,7 @@ object SharedTestDataADM {
descriptions = Seq(StringLiteralV2.from(value = "A group for image reviewers.", language = Some("en"))),
project = Some(imagesProject),
status = true,
- selfjoin = false,
+ selfjoin = SelfJoin.CannotJoin,
)
/* represents the full GroupADM of the images project reviewer group in the external format*/
@@ -359,7 +360,7 @@ object SharedTestDataADM {
descriptions = Seq(StringLiteralV2.from(value = "A group for image reviewers.", language = Some("en"))),
project = Some(imagesProjectExternal),
status = true,
- selfjoin = false,
+ selfjoin = SelfJoin.CannotJoin,
)
/**
@@ -482,7 +483,7 @@ object SharedTestDataADM {
logo = Some(Logo.unsafeFrom("incunabula_logo.png")),
ontologies = Seq(SharedOntologyTestDataADM.INCUNABULA_ONTOLOGY_IRI),
status = true,
- selfjoin = false,
+ selfjoin = SelfJoin.CannotJoin,
copyrightAttribution = None,
license = None,
)
@@ -519,7 +520,7 @@ object SharedTestDataADM {
logo = Some(Logo.unsafeFrom("incunabula_logo.png")),
ontologies = Seq(SharedOntologyTestDataADM.INCUNABULA_ONTOLOGY_IRI_LocalHost),
status = true,
- selfjoin = false,
+ selfjoin = SelfJoin.CannotJoin,
copyrightAttribution = None,
license = None,
)
@@ -633,7 +634,7 @@ object SharedTestDataADM {
logo = None,
ontologies = Seq(SharedOntologyTestDataADM.ANYTHING_ONTOLOGY_IRI, SharedOntologyTestDataADM.SomethingOntologyIri),
status = true,
- selfjoin = false,
+ selfjoin = SelfJoin.CannotJoin,
copyrightAttribution = None,
license = None,
)
@@ -651,7 +652,7 @@ object SharedTestDataADM {
SharedOntologyTestDataADM.SomethingOntologyIriLocalhost,
),
status = true,
- selfjoin = false,
+ selfjoin = SelfJoin.CannotJoin,
copyrightAttribution = None,
license = None,
)
@@ -690,7 +691,7 @@ object SharedTestDataADM {
"http://www.knora.org/ontology/0801/newton",
),
status = true,
- selfjoin = false,
+ selfjoin = SelfJoin.CannotJoin,
copyrightAttribution = None,
license = None,
)
@@ -741,7 +742,7 @@ object SharedTestDataADM {
logo = None,
ontologies = Seq("http://www.knora.org/ontology/0804/dokubib"),
status = false,
- selfjoin = false,
+ selfjoin = SelfJoin.CannotJoin,
copyrightAttribution = None,
license = None,
)
diff --git a/webapi/src/main/scala/org/knora/webapi/slice/admin/api/Examples.scala b/webapi/src/main/scala/org/knora/webapi/slice/admin/api/Examples.scala
index 1cccf78209..2ebf48cc4c 100644
--- a/webapi/src/main/scala/org/knora/webapi/slice/admin/api/Examples.scala
+++ b/webapi/src/main/scala/org/knora/webapi/slice/admin/api/Examples.scala
@@ -27,6 +27,7 @@ import org.knora.webapi.slice.admin.domain.model.KnoraProject.CopyrightAttributi
import org.knora.webapi.slice.admin.domain.model.KnoraProject.License
import org.knora.webapi.slice.admin.domain.model.KnoraProject.Longname
import org.knora.webapi.slice.admin.domain.model.KnoraProject.ProjectIri
+import org.knora.webapi.slice.admin.domain.model.KnoraProject.SelfJoin.CannotJoin
import org.knora.webapi.slice.admin.domain.model.KnoraProject.Shortcode
import org.knora.webapi.slice.admin.domain.model.KnoraProject.Shortname
import org.knora.webapi.slice.admin.domain.model.User
@@ -97,7 +98,7 @@ object Examples {
logo = None,
status = true,
ontologies = Seq.empty,
- selfjoin = false,
+ selfjoin = CannotJoin,
copyrightAttribution = Some(CopyrightAttribution.unsafeFrom("2024, Example Project")),
license = Some(License.unsafeFrom("CC-BY-4.0")),
)
diff --git a/webapi/src/main/scala/org/knora/webapi/slice/admin/api/model/ProjectsMessagesADM.scala b/webapi/src/main/scala/org/knora/webapi/slice/admin/api/model/ProjectsMessagesADM.scala
index bc39ef8e28..e2cc59063e 100644
--- a/webapi/src/main/scala/org/knora/webapi/slice/admin/api/model/ProjectsMessagesADM.scala
+++ b/webapi/src/main/scala/org/knora/webapi/slice/admin/api/model/ProjectsMessagesADM.scala
@@ -40,7 +40,7 @@ case class Project(
logo: Option[Logo],
ontologies: Seq[IRI],
status: Boolean,
- selfjoin: Boolean,
+ selfjoin: SelfJoin,
copyrightAttribution: Option[CopyrightAttribution],
license: Option[License],
) extends Ordered[Project] {
diff --git a/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/service/ProjectService.scala b/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/service/ProjectService.scala
index f474b748d5..2c1741d341 100644
--- a/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/service/ProjectService.scala
+++ b/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/service/ProjectService.scala
@@ -55,7 +55,7 @@ final case class ProjectService(
knoraProject.logo,
ontologies,
knoraProject.status.value,
- knoraProject.selfjoin.value,
+ knoraProject.selfjoin,
knoraProject.copyrightAttribution,
knoraProject.license,
),
@@ -73,7 +73,7 @@ final case class ProjectService(
keywords = project.keywords.map(Keyword.unsafeFrom).toList,
logo = project.logo,
status = Status.from(project.status),
- selfjoin = SelfJoin.from(project.selfjoin),
+ selfjoin = project.selfjoin,
restrictedView,
project.copyrightAttribution,
project.license,
diff --git a/webapi/src/test/scala/org/knora/webapi/slice/admin/domain/service/ProjectServiceSpec.scala b/webapi/src/test/scala/org/knora/webapi/slice/admin/domain/service/ProjectServiceSpec.scala
index c99ef6a836..696586a958 100644
--- a/webapi/src/test/scala/org/knora/webapi/slice/admin/domain/service/ProjectServiceSpec.scala
+++ b/webapi/src/test/scala/org/knora/webapi/slice/admin/domain/service/ProjectServiceSpec.scala
@@ -34,7 +34,7 @@ object ProjectServiceSpec extends ZIOSpecDefault {
logo = None,
ontologies = List.empty,
status = true,
- selfjoin = true,
+ selfjoin = SelfJoin.CanJoin,
copyrightAttribution = None,
license = None,
)
From c564346524afcd1f5e1922ec64702e1d566a2467 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20Kleinb=C3=B6lting?=
Date: Fri, 15 Nov 2024 18:11:33 +0100
Subject: [PATCH 15/18] refactor: Make Project.status typed
---
.../webapi/e2e/admin/ProjectsADME2ESpec.scala | 10 +++----
.../IntegrationTestAdminJsonProtocol.scala | 11 +++++--
.../admin/ProjectRestServiceSpec.scala | 2 +-
.../webapi/sharedtestdata/ProjectInfo.scala | 2 +-
.../sharedtestdata/SharedTestDataADM.scala | 29 ++++++++++---------
.../webapi/slice/admin/api/Examples.scala | 3 +-
.../admin/api/model/ProjectsMessagesADM.scala | 2 +-
.../admin/domain/service/ProjectService.scala | 4 +--
.../domain/service/ProjectServiceSpec.scala | 2 +-
9 files changed, 36 insertions(+), 29 deletions(-)
diff --git a/integration/src/test/scala/org/knora/webapi/e2e/admin/ProjectsADME2ESpec.scala b/integration/src/test/scala/org/knora/webapi/e2e/admin/ProjectsADME2ESpec.scala
index dd8db41e8f..cc47c928cd 100644
--- a/integration/src/test/scala/org/knora/webapi/e2e/admin/ProjectsADME2ESpec.scala
+++ b/integration/src/test/scala/org/knora/webapi/e2e/admin/ProjectsADME2ESpec.scala
@@ -29,6 +29,7 @@ import org.knora.webapi.sharedtestdata.SharedTestDataADM
import org.knora.webapi.slice.admin.api.model.*
import org.knora.webapi.slice.admin.api.model.ProjectMembersGetResponseADM
import org.knora.webapi.slice.admin.domain.model.KnoraProject.SelfJoin
+import org.knora.webapi.slice.admin.domain.model.KnoraProject.Status
import org.knora.webapi.slice.admin.domain.model.User
import org.knora.webapi.util.AkkaHttpUtils
import org.knora.webapi.util.MutableTestIri
@@ -235,7 +236,7 @@ class ProjectsADME2ESpec extends E2ESpec with SprayJsonSupport {
result.description should be(Seq(StringLiteralV2.from(value = "project description", language = Some("en"))))
result.keywords should be(Seq("keywords"))
result.logo should be(Some("/fu/bar/baz.jpg"))
- result.status should be(true)
+ result.status should be(Status.Active)
result.selfjoin should be(SelfJoin.CannotJoin)
newProjectIri.set(result.id)
@@ -362,7 +363,7 @@ class ProjectsADME2ESpec extends E2ESpec with SprayJsonSupport {
)
result.keywords.sorted should be(Seq("updated", "keywords").sorted)
result.logo should be(Some("/fu/bar/baz-updated.jpg"))
- result.status should be(true)
+ result.status should be(Status.Active)
result.selfjoin should be(SelfJoin.CanJoin)
}
@@ -398,7 +399,7 @@ class ProjectsADME2ESpec extends E2ESpec with SprayJsonSupport {
response.status should be(StatusCodes.OK)
val result: Project = AkkaHttpUtils.httpResponseToJson(response).fields("project").convertTo[Project]
- result.status should be(false)
+ result.status should be(Status.Inactive)
}
}
@@ -411,8 +412,7 @@ class ProjectsADME2ESpec extends E2ESpec with SprayJsonSupport {
assert(response.status === StatusCodes.OK)
val jsObject = AkkaHttpUtils.httpResponseToJson(response)
val prjMembersResp = jsonReader[ProjectMembersGetResponseADM].read(jsObject)
-// val prjMembersResp = jsObject.convertTo[ProjectMembersGetResponseADM]
- val members = prjMembersResp.members
+ val members = prjMembersResp.members
members.size should be(4)
}
diff --git a/integration/src/test/scala/org/knora/webapi/messages/admin/responder/IntegrationTestAdminJsonProtocol.scala b/integration/src/test/scala/org/knora/webapi/messages/admin/responder/IntegrationTestAdminJsonProtocol.scala
index 991d7faeab..0a99e53455 100644
--- a/integration/src/test/scala/org/knora/webapi/messages/admin/responder/IntegrationTestAdminJsonProtocol.scala
+++ b/integration/src/test/scala/org/knora/webapi/messages/admin/responder/IntegrationTestAdminJsonProtocol.scala
@@ -51,6 +51,7 @@ import org.knora.webapi.slice.admin.domain.model.KnoraProject.Longname
import org.knora.webapi.slice.admin.domain.model.KnoraProject.SelfJoin
import org.knora.webapi.slice.admin.domain.model.KnoraProject.Shortcode
import org.knora.webapi.slice.admin.domain.model.KnoraProject.Shortname
+import org.knora.webapi.slice.admin.domain.model.KnoraProject.Status
import org.knora.webapi.slice.admin.domain.model.User
import org.knora.webapi.slice.common.Value.BooleanValue
import org.knora.webapi.slice.common.Value.StringValue
@@ -235,15 +236,19 @@ object IntegrationTestAdminJsonProtocol extends TriplestoreJsonProtocol {
}
trait BooleanValueFormat[T <: BooleanValue] extends JsonFormat[T] { self =>
- def from: Boolean => Either[String, T]
+ def from: Boolean => T
override def write(v: T): JsValue = JsString(v.value.toString)
override def read(json: JsValue): T = json match
- case JsBoolean(bool) => self.from(bool).fold(err => throw DeserializationException(err), identity)
+ case JsBoolean(bool) => self.from(bool)
case _ => throw DeserializationException("Must be a json Boolean")
}
implicit object SelfJoinValueFormat extends BooleanValueFormat[SelfJoin] {
- override val from: Boolean => Either[String, SelfJoin] = b => Right(SelfJoin.from(b))
+ override val from: Boolean => SelfJoin = SelfJoin.from
+ }
+
+ implicit object StatusFormat extends BooleanValueFormat[Status] {
+ override val from: Boolean => Status = Status.from
}
implicit val groupFormat: JsonFormat[Group] = jsonFormat6(Group.apply)
diff --git a/integration/src/test/scala/org/knora/webapi/responders/admin/ProjectRestServiceSpec.scala b/integration/src/test/scala/org/knora/webapi/responders/admin/ProjectRestServiceSpec.scala
index 81664b9293..4f4430d0c9 100644
--- a/integration/src/test/scala/org/knora/webapi/responders/admin/ProjectRestServiceSpec.scala
+++ b/integration/src/test/scala/org/knora/webapi/responders/admin/ProjectRestServiceSpec.scala
@@ -410,7 +410,7 @@ class ProjectRestServiceSpec extends CoreSpec with ImplicitSender {
)
received.project.keywords.sorted should be(Seq("updated", "keywords").sorted)
received.project.logo should be(Some("/fu/bar/baz-updated.jpg"))
- received.project.status should be(true)
+ received.project.status should be(Status.Active)
received.project.selfjoin should be(SelfJoin.CanJoin)
}
diff --git a/integration/src/test/scala/org/knora/webapi/sharedtestdata/ProjectInfo.scala b/integration/src/test/scala/org/knora/webapi/sharedtestdata/ProjectInfo.scala
index 26a92aa4de..686a89a398 100644
--- a/integration/src/test/scala/org/knora/webapi/sharedtestdata/ProjectInfo.scala
+++ b/integration/src/test/scala/org/knora/webapi/sharedtestdata/ProjectInfo.scala
@@ -45,7 +45,7 @@ object ProjectInfo {
keywords = project.keywords.headOption.map(_ => project.keywords.mkString(", ")),
logo = project.logo.map(_.value),
ontologies = project.ontologies,
- status = project.status,
+ status = project.status.value,
selfjoin = project.selfjoin.value,
)
}
diff --git a/integration/src/test/scala/org/knora/webapi/sharedtestdata/SharedTestDataADM.scala b/integration/src/test/scala/org/knora/webapi/sharedtestdata/SharedTestDataADM.scala
index a4c47daf80..db866f5097 100644
--- a/integration/src/test/scala/org/knora/webapi/sharedtestdata/SharedTestDataADM.scala
+++ b/integration/src/test/scala/org/knora/webapi/sharedtestdata/SharedTestDataADM.scala
@@ -20,6 +20,7 @@ import org.knora.webapi.slice.admin.domain.model.KnoraProject.Longname
import org.knora.webapi.slice.admin.domain.model.KnoraProject.SelfJoin
import org.knora.webapi.slice.admin.domain.model.KnoraProject.Shortcode
import org.knora.webapi.slice.admin.domain.model.KnoraProject.Shortname
+import org.knora.webapi.slice.admin.domain.model.KnoraProject.Status
import org.knora.webapi.slice.admin.domain.model.Permission
import org.knora.webapi.slice.admin.domain.model.User
import org.knora.webapi.slice.admin.domain.service.KnoraGroupRepo
@@ -171,7 +172,7 @@ object SharedTestDataADM {
SalsahGui.SalsahGuiOntologyIri,
OntologyConstants.Standoff.StandoffOntologyIri,
),
- status = true,
+ status = Status.Active,
selfjoin = SelfJoin.CannotJoin,
copyrightAttribution = None,
license = None,
@@ -187,7 +188,7 @@ object SharedTestDataADM {
keywords = Seq.empty[String],
logo = None,
ontologies = Seq.empty[IRI],
- status = true,
+ status = Status.Active,
selfjoin = SelfJoin.CannotJoin,
copyrightAttribution = None,
license = None,
@@ -301,7 +302,7 @@ object SharedTestDataADM {
keywords = Seq("images", "collection").sorted,
logo = None,
ontologies = Seq(SharedOntologyTestDataADM.IMAGES_ONTOLOGY_IRI),
- status = true,
+ status = Status.Active,
selfjoin = SelfJoin.CannotJoin,
copyrightAttribution = None,
license = None,
@@ -317,7 +318,7 @@ object SharedTestDataADM {
keywords = Seq("images", "collection").sorted,
logo = None,
ontologies = Seq(SharedOntologyTestDataADM.IMAGES_ONTOLOGY_IRI_LocalHost),
- status = true,
+ status = Status.Active,
selfjoin = SelfJoin.CannotJoin,
copyrightAttribution = None,
license = None,
@@ -330,7 +331,7 @@ object SharedTestDataADM {
descriptions = Seq(StringLiteralV2.from(value = "Default Project Admin Group", language = Some("en"))),
project = Some(imagesProject),
status = true,
- selfjoin = SelfJoin.CannotJoin,
+ selfjoin = false,
)
/* represents the full GroupADM of the images ProjectMember group */
@@ -340,7 +341,7 @@ object SharedTestDataADM {
descriptions = Seq(StringLiteralV2.from(value = "Default Project Member Group", language = Some("en"))),
project = Some(imagesProject),
status = true,
- selfjoin = SelfJoin.CannotJoin,
+ selfjoin = false,
)
/* represents the full GroupADM of the images project reviewer group */
@@ -350,7 +351,7 @@ object SharedTestDataADM {
descriptions = Seq(StringLiteralV2.from(value = "A group for image reviewers.", language = Some("en"))),
project = Some(imagesProject),
status = true,
- selfjoin = SelfJoin.CannotJoin,
+ selfjoin = false,
)
/* represents the full GroupADM of the images project reviewer group in the external format*/
@@ -360,7 +361,7 @@ object SharedTestDataADM {
descriptions = Seq(StringLiteralV2.from(value = "A group for image reviewers.", language = Some("en"))),
project = Some(imagesProjectExternal),
status = true,
- selfjoin = SelfJoin.CannotJoin,
+ selfjoin = false,
)
/**
@@ -482,7 +483,7 @@ object SharedTestDataADM {
).sorted,
logo = Some(Logo.unsafeFrom("incunabula_logo.png")),
ontologies = Seq(SharedOntologyTestDataADM.INCUNABULA_ONTOLOGY_IRI),
- status = true,
+ status = Status.Active,
selfjoin = SelfJoin.CannotJoin,
copyrightAttribution = None,
license = None,
@@ -519,7 +520,7 @@ object SharedTestDataADM {
).sorted,
logo = Some(Logo.unsafeFrom("incunabula_logo.png")),
ontologies = Seq(SharedOntologyTestDataADM.INCUNABULA_ONTOLOGY_IRI_LocalHost),
- status = true,
+ status = Status.Active,
selfjoin = SelfJoin.CannotJoin,
copyrightAttribution = None,
license = None,
@@ -633,7 +634,7 @@ object SharedTestDataADM {
keywords = Seq("things", "arbitrary test data").sorted,
logo = None,
ontologies = Seq(SharedOntologyTestDataADM.ANYTHING_ONTOLOGY_IRI, SharedOntologyTestDataADM.SomethingOntologyIri),
- status = true,
+ status = Status.Active,
selfjoin = SelfJoin.CannotJoin,
copyrightAttribution = None,
license = None,
@@ -651,7 +652,7 @@ object SharedTestDataADM {
SharedOntologyTestDataADM.ANYTHING_ONTOLOGY_IRI_LocalHost,
SharedOntologyTestDataADM.SomethingOntologyIriLocalhost,
),
- status = true,
+ status = Status.Active,
selfjoin = SelfJoin.CannotJoin,
copyrightAttribution = None,
license = None,
@@ -690,7 +691,7 @@ object SharedTestDataADM {
"http://www.knora.org/ontology/0801/leibniz",
"http://www.knora.org/ontology/0801/newton",
),
- status = true,
+ status = Status.Active,
selfjoin = SelfJoin.CannotJoin,
copyrightAttribution = None,
license = None,
@@ -741,7 +742,7 @@ object SharedTestDataADM {
keywords = Seq.empty[String],
logo = None,
ontologies = Seq("http://www.knora.org/ontology/0804/dokubib"),
- status = false,
+ status = Status.Inactive,
selfjoin = SelfJoin.CannotJoin,
copyrightAttribution = None,
license = None,
diff --git a/webapi/src/main/scala/org/knora/webapi/slice/admin/api/Examples.scala b/webapi/src/main/scala/org/knora/webapi/slice/admin/api/Examples.scala
index 2ebf48cc4c..50ba4de1e7 100644
--- a/webapi/src/main/scala/org/knora/webapi/slice/admin/api/Examples.scala
+++ b/webapi/src/main/scala/org/knora/webapi/slice/admin/api/Examples.scala
@@ -30,6 +30,7 @@ import org.knora.webapi.slice.admin.domain.model.KnoraProject.ProjectIri
import org.knora.webapi.slice.admin.domain.model.KnoraProject.SelfJoin.CannotJoin
import org.knora.webapi.slice.admin.domain.model.KnoraProject.Shortcode
import org.knora.webapi.slice.admin.domain.model.KnoraProject.Shortname
+import org.knora.webapi.slice.admin.domain.model.KnoraProject.Status.Active
import org.knora.webapi.slice.admin.domain.model.User
import org.knora.webapi.slice.admin.domain.model.UserIri
import org.knora.webapi.slice.admin.domain.model.UserStatus
@@ -96,7 +97,7 @@ object Examples {
description = Seq(StringLiteralV2.from("An example project", Some("en"))),
keywords = Seq("example", "project"),
logo = None,
- status = true,
+ status = Active,
ontologies = Seq.empty,
selfjoin = CannotJoin,
copyrightAttribution = Some(CopyrightAttribution.unsafeFrom("2024, Example Project")),
diff --git a/webapi/src/main/scala/org/knora/webapi/slice/admin/api/model/ProjectsMessagesADM.scala b/webapi/src/main/scala/org/knora/webapi/slice/admin/api/model/ProjectsMessagesADM.scala
index e2cc59063e..feb3f52908 100644
--- a/webapi/src/main/scala/org/knora/webapi/slice/admin/api/model/ProjectsMessagesADM.scala
+++ b/webapi/src/main/scala/org/knora/webapi/slice/admin/api/model/ProjectsMessagesADM.scala
@@ -39,7 +39,7 @@ case class Project(
keywords: Seq[String],
logo: Option[Logo],
ontologies: Seq[IRI],
- status: Boolean,
+ status: Status,
selfjoin: SelfJoin,
copyrightAttribution: Option[CopyrightAttribution],
license: Option[License],
diff --git a/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/service/ProjectService.scala b/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/service/ProjectService.scala
index 2c1741d341..158a21a72a 100644
--- a/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/service/ProjectService.scala
+++ b/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/service/ProjectService.scala
@@ -54,7 +54,7 @@ final case class ProjectService(
knoraProject.keywords.map(_.value),
knoraProject.logo,
ontologies,
- knoraProject.status.value,
+ knoraProject.status,
knoraProject.selfjoin,
knoraProject.copyrightAttribution,
knoraProject.license,
@@ -72,7 +72,7 @@ final case class ProjectService(
.map(Description.unsafeFrom),
keywords = project.keywords.map(Keyword.unsafeFrom).toList,
logo = project.logo,
- status = Status.from(project.status),
+ status = project.status,
selfjoin = project.selfjoin,
restrictedView,
project.copyrightAttribution,
diff --git a/webapi/src/test/scala/org/knora/webapi/slice/admin/domain/service/ProjectServiceSpec.scala b/webapi/src/test/scala/org/knora/webapi/slice/admin/domain/service/ProjectServiceSpec.scala
index 696586a958..ef5f7d1b30 100644
--- a/webapi/src/test/scala/org/knora/webapi/slice/admin/domain/service/ProjectServiceSpec.scala
+++ b/webapi/src/test/scala/org/knora/webapi/slice/admin/domain/service/ProjectServiceSpec.scala
@@ -33,7 +33,7 @@ object ProjectServiceSpec extends ZIOSpecDefault {
keywords = List.empty,
logo = None,
ontologies = List.empty,
- status = true,
+ status = Status.Active,
selfjoin = SelfJoin.CanJoin,
copyrightAttribution = None,
license = None,
From d418c7bb84ae0a6df6825e984e68a56b02783d8e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20Kleinb=C3=B6lting?=
Date: Fri, 15 Nov 2024 19:27:12 +0100
Subject: [PATCH 16/18] refactor: Make Project.id typed
---
.../webapi/e2e/admin/ProjectsADME2ESpec.scala | 17 ++--
.../webapi/e2e/admin/UsersADME2ESpec.scala | 2 +-
.../e2e/v2/OntologyFormatsE2ESpec.scala | 5 +-
.../e2e/v2/ResourcesRouteV2E2ESpec.scala | 2 +-
.../IntegrationTestAdminJsonProtocol.scala | 6 ++
.../PermissionsMessagesADMSpec.scala | 18 ++---
.../models/filemodels/FileModelsSpec.scala | 1 +
.../admin/GroupRestServiceSpec.scala | 5 +-
.../admin/PermissionsResponderSpec.scala | 77 ++++++++-----------
.../admin/ProjectRestServiceSpec.scala | 31 ++++----
.../admin/UserRestServiceSpec.scala | 40 +++++-----
.../v2/OntologyResponderV2Spec.scala | 8 +-
.../responders/v2/SearchResponderV2Spec.scala | 2 +-
.../webapi/sharedtestdata/ProjectInfo.scala | 2 +-
.../sharedtestdata/SharedTestDataADM.scala | 62 +++++++--------
.../webapi/sharedtestdata/UserProfile.scala | 2 +-
.../KnoraUserToUserConverterSpec.scala | 4 +-
.../webapi/messages/OntologyConstants.scala | 4 +-
.../resourcemessages/ResourceMessagesV2.scala | 4 +-
.../admin/PermissionsResponder.scala | 4 +-
.../responders/v2/OntologyResponderV2.scala | 4 +-
.../webapi/responders/v2/ResourceUtilV2.scala | 4 +-
.../responders/v2/ResourcesResponderV2.scala | 2 +-
.../responders/v2/ValuesResponderV2.scala | 4 +-
.../ontology/OntologyTriplestoreHelpers.scala | 2 +-
.../resources/CreateResourceV2Handler.scala | 24 +++---
.../webapi/slice/admin/api/Examples.scala | 2 +-
.../admin/api/model/ProjectsMessagesADM.scala | 6 +-
.../api/service/PermissionRestService.scala | 6 +-
.../api/service/ProjectRestService.scala | 4 +-
.../admin/domain/service/GroupService.scala | 2 +-
.../domain/service/KnoraUserService.scala | 18 ++---
.../admin/domain/service/ProjectService.scala | 4 +-
.../ApiComplexV2JsonLdRequestParser.scala | 2 +-
.../domain/service/ProjectServiceSpec.scala | 2 +-
.../RestCardinalityServiceLiveSpec.scala | 4 +-
.../domain/IriTestConstants.scala | 3 +-
37 files changed, 192 insertions(+), 197 deletions(-)
diff --git a/integration/src/test/scala/org/knora/webapi/e2e/admin/ProjectsADME2ESpec.scala b/integration/src/test/scala/org/knora/webapi/e2e/admin/ProjectsADME2ESpec.scala
index cc47c928cd..7c87fee891 100644
--- a/integration/src/test/scala/org/knora/webapi/e2e/admin/ProjectsADME2ESpec.scala
+++ b/integration/src/test/scala/org/knora/webapi/e2e/admin/ProjectsADME2ESpec.scala
@@ -19,6 +19,7 @@ import java.net.URLEncoder
import scala.concurrent.Await
import scala.concurrent.Future
import scala.concurrent.duration.*
+
import org.knora.webapi.E2ESpec
import org.knora.webapi.IRI
import org.knora.webapi.messages.admin.responder.IntegrationTestAdminJsonProtocol.*
@@ -42,7 +43,7 @@ class ProjectsADME2ESpec extends E2ESpec with SprayJsonSupport {
private val rootEmail = SharedTestDataADM.rootUser.email
private val testPass = SharedTestDataADM.testPass
private val projectIri = SharedTestDataADM.imagesProject.id
- private val projectIriEnc = URLEncoder.encode(projectIri, "utf-8")
+ private val projectIriEnc = URLEncoder.encode(projectIri.value, "utf-8")
private val projectShortname = SharedTestDataADM.imagesProject.shortname
private val projectShortcode = SharedTestDataADM.imagesProject.shortcode
@@ -239,7 +240,7 @@ class ProjectsADME2ESpec extends E2ESpec with SprayJsonSupport {
result.status should be(Status.Active)
result.selfjoin should be(SelfJoin.CannotJoin)
- newProjectIri.set(result.id)
+ newProjectIri.set(result.id.value)
}
"return a 'BadRequest' if the supplied project shortname during creation is not unique" in {
@@ -539,7 +540,7 @@ class ProjectsADME2ESpec extends E2ESpec with SprayJsonSupport {
}
"return all keywords for a single project" in {
- val incunabulaIriEnc = URLEncoder.encode(SharedTestDataADM.incunabulaProject.id, "utf-8")
+ val incunabulaIriEnc = URLEncoder.encode(SharedTestDataADM.incunabulaProject.id.value, "utf-8")
val request = Get(baseApiUrl + s"/admin/projects/iri/$incunabulaIriEnc/Keywords") ~> addCredentials(
BasicHttpCredentials(rootEmail, testPass),
)
@@ -551,7 +552,7 @@ class ProjectsADME2ESpec extends E2ESpec with SprayJsonSupport {
}
"return empty list for a project without keywords" in {
- val dokubibIriEnc = URLEncoder.encode(SharedTestDataADM.dokubibProject.id, "utf-8")
+ val dokubibIriEnc = URLEncoder.encode(SharedTestDataADM.dokubibProject.id.value, "utf-8")
val request = Get(baseApiUrl + s"/admin/projects/iri/$dokubibIriEnc/Keywords") ~> addCredentials(
BasicHttpCredentials(rootEmail, testPass),
)
@@ -574,7 +575,7 @@ class ProjectsADME2ESpec extends E2ESpec with SprayJsonSupport {
"used to dump project data" should {
"return a TriG file containing all data from a project" in {
- val anythingProjectIriEnc = URLEncoder.encode(SharedTestDataADM.anythingProject.id, "utf-8")
+ val anythingProjectIriEnc = URLEncoder.encode(SharedTestDataADM.anythingProject.id.value, "utf-8")
val request = Get(baseApiUrl + s"/admin/projects/iri/$anythingProjectIriEnc/AllData") ~> addCredentials(
BasicHttpCredentials(SharedTestDataADM.anythingAdminUser.email, testPass),
)
@@ -599,7 +600,7 @@ class ProjectsADME2ESpec extends E2ESpec with SprayJsonSupport {
"used to set RestrictedViewSize by project IRI" should {
"return requested value to be set with 200 Response Status" in {
- val encodedIri = URLEncoder.encode(SharedTestDataADM.imagesProject.id, "utf-8")
+ val encodedIri = URLEncoder.encode(SharedTestDataADM.imagesProject.id.value, "utf-8")
val payload = """{"size":"pct:1"}"""
val request =
Post(
@@ -614,7 +615,7 @@ class ProjectsADME2ESpec extends E2ESpec with SprayJsonSupport {
}
"return the `BadRequest` if the size value is invalid" in {
- val encodedIri = URLEncoder.encode(SharedTestDataADM.imagesProject.id, "utf-8")
+ val encodedIri = URLEncoder.encode(SharedTestDataADM.imagesProject.id.value, "utf-8")
val payload = """{"size":"pct:0"}"""
val request =
Post(
@@ -630,7 +631,7 @@ class ProjectsADME2ESpec extends E2ESpec with SprayJsonSupport {
}
"return `Forbidden` for the user who is not a system nor project admin" in {
- val encodedIri = URLEncoder.encode(SharedTestDataADM.imagesProject.id, "utf-8")
+ val encodedIri = URLEncoder.encode(SharedTestDataADM.imagesProject.id.value, "utf-8")
val payload = """{"size":"pct:1"}"""
val request =
Post(
diff --git a/integration/src/test/scala/org/knora/webapi/e2e/admin/UsersADME2ESpec.scala b/integration/src/test/scala/org/knora/webapi/e2e/admin/UsersADME2ESpec.scala
index 1d8565f428..a4ed15b696 100644
--- a/integration/src/test/scala/org/knora/webapi/e2e/admin/UsersADME2ESpec.scala
+++ b/integration/src/test/scala/org/knora/webapi/e2e/admin/UsersADME2ESpec.scala
@@ -50,7 +50,7 @@ class UsersADME2ESpec extends E2ESpec with SprayJsonSupport {
private val multiUserIriEnc = java.net.URLEncoder.encode(multiUserIri, "utf-8")
private val imagesProjectIri = SharedTestDataADM.imagesProject.id
- private val imagesProjectIriEnc = java.net.URLEncoder.encode(imagesProjectIri, "utf-8")
+ private val imagesProjectIriEnc = java.net.URLEncoder.encode(imagesProjectIri.value, "utf-8")
private val imagesReviewerGroupIri = SharedTestDataADM.imagesReviewerGroup.id
private val imagesReviewerGroupIriEnc = java.net.URLEncoder.encode(imagesReviewerGroupIri, "utf-8")
diff --git a/integration/src/test/scala/org/knora/webapi/e2e/v2/OntologyFormatsE2ESpec.scala b/integration/src/test/scala/org/knora/webapi/e2e/v2/OntologyFormatsE2ESpec.scala
index 90acbae336..da0b296900 100644
--- a/integration/src/test/scala/org/knora/webapi/e2e/v2/OntologyFormatsE2ESpec.scala
+++ b/integration/src/test/scala/org/knora/webapi/e2e/v2/OntologyFormatsE2ESpec.scala
@@ -23,6 +23,7 @@ import org.knora.webapi.messages.util.rdf.RdfFormatUtil
import org.knora.webapi.messages.util.rdf.Turtle
import org.knora.webapi.sharedtestdata.SharedOntologyTestDataADM
import org.knora.webapi.sharedtestdata.SharedTestDataADM
+import org.knora.webapi.slice.common.Value.StringValue
import org.knora.webapi.util.*
class OntologyFormatsE2ESpec extends E2ESpec {
@@ -73,8 +74,8 @@ class OntologyFormatsE2ESpec extends E2ESpec {
}
}
- private def urlEncodeIri(iri: IRI): String =
- URLEncoder.encode(iri, "UTF-8")
+ private def urlEncodeIri(iri: StringValue): String = URLEncoder.encode(iri.value, "UTF-8")
+ private def urlEncodeIri(iri: IRI): String = URLEncoder.encode(iri, "UTF-8")
private def checkTestCase(httpGetTest: HttpGetTest) = {
val responseJsonLd = getResponse(httpGetTest.urlPath, RdfMediaTypes.`application/ld+json`)
diff --git a/integration/src/test/scala/org/knora/webapi/e2e/v2/ResourcesRouteV2E2ESpec.scala b/integration/src/test/scala/org/knora/webapi/e2e/v2/ResourcesRouteV2E2ESpec.scala
index d3d49aebf2..5a645fc858 100644
--- a/integration/src/test/scala/org/knora/webapi/e2e/v2/ResourcesRouteV2E2ESpec.scala
+++ b/integration/src/test/scala/org/knora/webapi/e2e/v2/ResourcesRouteV2E2ESpec.scala
@@ -652,7 +652,7 @@ class ResourcesRouteV2E2ESpec extends E2ESpec {
val orderByProperty = URLEncoder.encode("http://0.0.0.0:3333/ontology/0803/incunabula/v2#title", "UTF-8")
val request =
Get(s"$baseApiUrl/v2/resources?resourceClass=$resourceClass&orderByProperty=$orderByProperty&page=0")
- .addHeader(new ProjectHeader(SharedTestDataADM.incunabulaProject.id)) ~> addCredentials(
+ .addHeader(new ProjectHeader(SharedTestDataADM.incunabulaProject.id.value)) ~> addCredentials(
BasicHttpCredentials(SharedTestDataADM.incunabulaProjectAdminUser.email, password),
)
val response: HttpResponse = singleAwaitingRequest(request)
diff --git a/integration/src/test/scala/org/knora/webapi/messages/admin/responder/IntegrationTestAdminJsonProtocol.scala b/integration/src/test/scala/org/knora/webapi/messages/admin/responder/IntegrationTestAdminJsonProtocol.scala
index 0a99e53455..9d2d1385a8 100644
--- a/integration/src/test/scala/org/knora/webapi/messages/admin/responder/IntegrationTestAdminJsonProtocol.scala
+++ b/integration/src/test/scala/org/knora/webapi/messages/admin/responder/IntegrationTestAdminJsonProtocol.scala
@@ -6,6 +6,7 @@
package org.knora.webapi.messages.admin.responder
import spray.json.*
+
import org.knora.webapi.messages.admin.responder.groupsmessages.GroupGetResponseADM
import org.knora.webapi.messages.admin.responder.groupsmessages.GroupsGetResponseADM
import org.knora.webapi.messages.admin.responder.permissionsmessages.AdministrativePermissionADM
@@ -48,6 +49,7 @@ import org.knora.webapi.slice.admin.domain.model.KnoraProject.CopyrightAttributi
import org.knora.webapi.slice.admin.domain.model.KnoraProject.License
import org.knora.webapi.slice.admin.domain.model.KnoraProject.Logo
import org.knora.webapi.slice.admin.domain.model.KnoraProject.Longname
+import org.knora.webapi.slice.admin.domain.model.KnoraProject.ProjectIri
import org.knora.webapi.slice.admin.domain.model.KnoraProject.SelfJoin
import org.knora.webapi.slice.admin.domain.model.KnoraProject.Shortcode
import org.knora.webapi.slice.admin.domain.model.KnoraProject.Shortname
@@ -211,6 +213,10 @@ object IntegrationTestAdminJsonProtocol extends TriplestoreJsonProtocol {
case _ => throw DeserializationException("Must be a json String")
}
+ implicit object ProjectIriFormat extends StringValueFormat[ProjectIri] {
+ override val from: String => Either[String, ProjectIri] = ProjectIri.from
+ }
+
implicit object CopyrightAttributionFormat extends StringValueFormat[CopyrightAttribution] {
override val from: String => Either[String, CopyrightAttribution] = CopyrightAttribution.from
}
diff --git a/integration/src/test/scala/org/knora/webapi/messages/admin/responder/permissionsmessages/PermissionsMessagesADMSpec.scala b/integration/src/test/scala/org/knora/webapi/messages/admin/responder/permissionsmessages/PermissionsMessagesADMSpec.scala
index 8955d36a49..c127f2880c 100644
--- a/integration/src/test/scala/org/knora/webapi/messages/admin/responder/permissionsmessages/PermissionsMessagesADMSpec.scala
+++ b/integration/src/test/scala/org/knora/webapi/messages/admin/responder/permissionsmessages/PermissionsMessagesADMSpec.scala
@@ -45,7 +45,7 @@ class PermissionsMessagesADMSpec extends CoreSpec {
val exit = UnsafeZioRun.run(
PermissionRestService.createAdministrativePermission(
CreateAdministrativePermissionAPIRequestADM(
- forProject = SharedTestDataADM.imagesProjectIri,
+ forProject = SharedTestDataADM.imagesProjectIri.value,
forGroup = groupIri,
hasPermissions = Set(PermissionADM.from(Permission.Administrative.ProjectAdminAll)),
),
@@ -61,7 +61,7 @@ class PermissionsMessagesADMSpec extends CoreSpec {
PermissionRestService.createAdministrativePermission(
CreateAdministrativePermissionAPIRequestADM(
id = Some(permissionIri),
- forProject = SharedTestDataADM.imagesProjectIri,
+ forProject = SharedTestDataADM.imagesProjectIri.value,
forGroup = KnoraGroupRepo.builtIn.ProjectMember.id.value,
hasPermissions = Set(PermissionADM.from(Permission.Administrative.ProjectAdminAll)),
),
@@ -83,7 +83,7 @@ class PermissionsMessagesADMSpec extends CoreSpec {
val exit = UnsafeZioRun.run(
PermissionRestService.createAdministrativePermission(
CreateAdministrativePermissionAPIRequestADM(
- forProject = SharedTestDataADM.imagesProjectIri,
+ forProject = SharedTestDataADM.imagesProjectIri.value,
forGroup = KnoraGroupRepo.builtIn.ProjectMember.id.value,
hasPermissions = hasPermissions,
),
@@ -101,7 +101,7 @@ class PermissionsMessagesADMSpec extends CoreSpec {
val exit = UnsafeZioRun.run(
PermissionRestService.createAdministrativePermission(
CreateAdministrativePermissionAPIRequestADM(
- forProject = SharedTestDataADM.imagesProjectIri,
+ forProject = SharedTestDataADM.imagesProjectIri.value,
forGroup = KnoraGroupRepo.builtIn.ProjectMember.id.value,
hasPermissions = Set.empty[PermissionADM],
),
@@ -115,7 +115,7 @@ class PermissionsMessagesADMSpec extends CoreSpec {
val exit = UnsafeZioRun.run(
PermissionRestService.createAdministrativePermission(
CreateAdministrativePermissionAPIRequestADM(
- forProject = SharedTestDataADM.imagesProjectIri,
+ forProject = SharedTestDataADM.imagesProjectIri.value,
forGroup = KnoraGroupRepo.builtIn.ProjectMember.id.value,
hasPermissions = Set(PermissionADM.from(Permission.Administrative.ProjectAdminAll)),
),
@@ -153,7 +153,7 @@ class PermissionsMessagesADMSpec extends CoreSpec {
val exit = UnsafeZioRun.run(
PermissionRestService.createDefaultObjectAccessPermission(
CreateDefaultObjectAccessPermissionAPIRequestADM(
- forProject = SharedTestDataADM.imagesProjectIri,
+ forProject = SharedTestDataADM.imagesProjectIri.value,
forGroup = Some(groupIri),
hasPermissions = Set(
PermissionADM.from(Permission.ObjectAccess.ChangeRights, KnoraGroupRepo.builtIn.ProjectMember.id.value),
@@ -171,7 +171,7 @@ class PermissionsMessagesADMSpec extends CoreSpec {
PermissionRestService.createDefaultObjectAccessPermission(
CreateDefaultObjectAccessPermissionAPIRequestADM(
id = Some(permissionIri),
- forProject = SharedTestDataADM.imagesProjectIri,
+ forProject = SharedTestDataADM.imagesProjectIri.value,
forGroup = Some(KnoraGroupRepo.builtIn.ProjectMember.id.value),
hasPermissions = Set(
PermissionADM.from(Permission.ObjectAccess.ChangeRights, KnoraGroupRepo.builtIn.ProjectMember.id.value),
@@ -187,7 +187,7 @@ class PermissionsMessagesADMSpec extends CoreSpec {
val exit = UnsafeZioRun.run(
PermissionRestService.createDefaultObjectAccessPermission(
CreateDefaultObjectAccessPermissionAPIRequestADM(
- forProject = SharedTestDataADM.imagesProjectIri,
+ forProject = SharedTestDataADM.imagesProjectIri.value,
forGroup = Some(SharedTestDataADM.thingSearcherGroup.id),
hasPermissions = Set.empty[PermissionADM],
),
@@ -289,7 +289,7 @@ class PermissionsMessagesADMSpec extends CoreSpec {
val exit = UnsafeZioRun.run(
PermissionRestService.createDefaultObjectAccessPermission(
CreateDefaultObjectAccessPermissionAPIRequestADM(
- forProject = SharedTestDataADM.anythingProjectIri,
+ forProject = SharedTestDataADM.anythingProjectIri.value,
forGroup = Some(SharedTestDataADM.thingSearcherGroup.id),
hasPermissions =
Set(PermissionADM.from(Permission.ObjectAccess.RestrictedView, SharedTestDataADM.thingSearcherGroup.id)),
diff --git a/integration/src/test/scala/org/knora/webapi/models/filemodels/FileModelsSpec.scala b/integration/src/test/scala/org/knora/webapi/models/filemodels/FileModelsSpec.scala
index 5ac6b34b2b..7d275c06dd 100644
--- a/integration/src/test/scala/org/knora/webapi/models/filemodels/FileModelsSpec.scala
+++ b/integration/src/test/scala/org/knora/webapi/models/filemodels/FileModelsSpec.scala
@@ -10,6 +10,7 @@ import spray.json.DefaultJsonProtocol.*
import java.time.Instant
import java.util.UUID
+
import dsp.errors.AssertionException
import org.knora.webapi.ApiV2Complex
import org.knora.webapi.CoreSpec
diff --git a/integration/src/test/scala/org/knora/webapi/responders/admin/GroupRestServiceSpec.scala b/integration/src/test/scala/org/knora/webapi/responders/admin/GroupRestServiceSpec.scala
index ac1bb8ed81..c36217ff24 100644
--- a/integration/src/test/scala/org/knora/webapi/responders/admin/GroupRestServiceSpec.scala
+++ b/integration/src/test/scala/org/knora/webapi/responders/admin/GroupRestServiceSpec.scala
@@ -22,7 +22,6 @@ import org.knora.webapi.slice.admin.domain.model.GroupIri
import org.knora.webapi.slice.admin.domain.model.GroupName
import org.knora.webapi.slice.admin.domain.model.GroupSelfJoin
import org.knora.webapi.slice.admin.domain.model.GroupStatus
-import org.knora.webapi.slice.admin.domain.model.KnoraProject.ProjectIri
import org.knora.webapi.slice.admin.domain.service.GroupService
import org.knora.webapi.util.MutableTestIri
import org.knora.webapi.util.ZioScalaTestUtil.assertFailsWithA
@@ -74,7 +73,7 @@ class GroupRestServiceSpec extends CoreSpec {
),
),
),
- project = ProjectIri.unsafeFrom(imagesProjectIri),
+ project = imagesProjectIri,
status = GroupStatus.active,
selfjoin = GroupSelfJoin.disabled,
),
@@ -106,7 +105,7 @@ class GroupRestServiceSpec extends CoreSpec {
name = groupName,
descriptions = GroupDescriptions
.unsafeFrom(Seq(StringLiteralV2.from(value = "NewGroupDescription", language = Some("en")))),
- project = ProjectIri.unsafeFrom(imagesProjectIri),
+ project = imagesProjectIri,
status = GroupStatus.active,
selfjoin = GroupSelfJoin.disabled,
),
diff --git a/integration/src/test/scala/org/knora/webapi/responders/admin/PermissionsResponderSpec.scala b/integration/src/test/scala/org/knora/webapi/responders/admin/PermissionsResponderSpec.scala
index 2043a7cd65..b285b922ca 100644
--- a/integration/src/test/scala/org/knora/webapi/responders/admin/PermissionsResponderSpec.scala
+++ b/integration/src/test/scala/org/knora/webapi/responders/admin/PermissionsResponderSpec.scala
@@ -33,7 +33,6 @@ import org.knora.webapi.sharedtestdata.SharedTestDataADM.normalUser
import org.knora.webapi.sharedtestdata.SharedTestDataADM2
import org.knora.webapi.slice.admin.api.service.PermissionRestService
import org.knora.webapi.slice.admin.domain.model.GroupIri
-import org.knora.webapi.slice.admin.domain.model.KnoraProject.ProjectIri
import org.knora.webapi.slice.admin.domain.model.Permission
import org.knora.webapi.slice.admin.domain.model.PermissionIri
import org.knora.webapi.slice.admin.domain.service.KnoraGroupRepo
@@ -80,7 +79,7 @@ class PermissionsResponderSpec extends CoreSpec with ImplicitSender {
val result = UnsafeZioRun.runOrThrow(
permissionRestService(
_.getPermissionsApByProjectAndGroupIri(
- ProjectIri.unsafeFrom(imagesProjectIri),
+ imagesProjectIri,
KnoraGroupRepo.builtIn.ProjectMember.id,
rootUser,
),
@@ -96,7 +95,7 @@ class PermissionsResponderSpec extends CoreSpec with ImplicitSender {
permissionsResponder(
_.createAdministrativePermission(
CreateAdministrativePermissionAPIRequestADM(
- forProject = imagesProjectIri,
+ forProject = imagesProjectIri.value,
forGroup = KnoraGroupRepo.builtIn.ProjectMember.id.value,
hasPermissions = Set(PermissionADM.from(Permission.Administrative.ProjectResourceCreateAll)),
),
@@ -121,7 +120,7 @@ class PermissionsResponderSpec extends CoreSpec with ImplicitSender {
_.createAdministrativePermission(
CreateAdministrativePermissionAPIRequestADM(
id = Some(customIri),
- forProject = SharedTestDataADM.anythingProjectIri,
+ forProject = SharedTestDataADM.anythingProjectIri.value,
forGroup = SharedTestDataADM.thingSearcherGroup.id,
hasPermissions = Set(PermissionADM.from(Permission.Administrative.ProjectResourceCreateAll)),
),
@@ -131,7 +130,7 @@ class PermissionsResponderSpec extends CoreSpec with ImplicitSender {
),
)
assert(actual.administrativePermission.iri == customIri)
- assert(actual.administrativePermission.forProject == SharedTestDataADM.anythingProjectIri)
+ assert(actual.administrativePermission.forProject == SharedTestDataADM.anythingProjectIri.value)
assert(actual.administrativePermission.forGroup == SharedTestDataADM.thingSearcherGroup.id)
}
@@ -150,7 +149,7 @@ class PermissionsResponderSpec extends CoreSpec with ImplicitSender {
_.createAdministrativePermission(
CreateAdministrativePermissionAPIRequestADM(
id = Some(customIri),
- forProject = SharedTestDataADM.anythingProjectIri,
+ forProject = SharedTestDataADM.anythingProjectIri.value,
forGroup = KnoraGroupRepo.builtIn.KnownUser.id.value,
hasPermissions = hasPermissions,
),
@@ -161,7 +160,7 @@ class PermissionsResponderSpec extends CoreSpec with ImplicitSender {
)
assert(actual.administrativePermission.iri == customIri)
assert(actual.administrativePermission.forGroup == KnoraGroupRepo.builtIn.KnownUser.id.value)
- assert(actual.administrativePermission.forProject == SharedTestDataADM.anythingProjectIri)
+ assert(actual.administrativePermission.forProject == SharedTestDataADM.anythingProjectIri.value)
assert(actual.administrativePermission.hasPermissions.equals(expectedHasPermissions))
}
}
@@ -169,13 +168,7 @@ class PermissionsResponderSpec extends CoreSpec with ImplicitSender {
"ask to query about default object access permissions " should {
"return all DefaultObjectAccessPermissions for project" in {
- val actual = UnsafeZioRun.runOrThrow(
- permissionsResponder(
- _.getPermissionsDaopByProjectIri(
- ProjectIri.unsafeFrom(imagesProjectIri),
- ),
- ),
- )
+ val actual = UnsafeZioRun.runOrThrow(permissionsResponder(_.getPermissionsDaopByProjectIri(imagesProjectIri)))
actual shouldEqual DefaultObjectAccessPermissionsForProjectGetResponseADM(
Seq(perm002_d2.p, perm0003_a4.p, perm002_d1.p),
)
@@ -189,7 +182,7 @@ class PermissionsResponderSpec extends CoreSpec with ImplicitSender {
permissionsResponder(
_.createDefaultObjectAccessPermission(
CreateDefaultObjectAccessPermissionAPIRequestADM(
- forProject = SharedTestDataADM.anythingProjectIri,
+ forProject = SharedTestDataADM.anythingProjectIri.value,
forGroup = Some(SharedTestDataADM.thingSearcherGroup.id),
hasPermissions = Set(
PermissionADM.from(Permission.ObjectAccess.RestrictedView, SharedTestDataADM.thingSearcherGroup.id),
@@ -200,7 +193,7 @@ class PermissionsResponderSpec extends CoreSpec with ImplicitSender {
),
)
- assert(actual.defaultObjectAccessPermission.forProject == SharedTestDataADM.anythingProjectIri)
+ assert(actual.defaultObjectAccessPermission.forProject == SharedTestDataADM.anythingProjectIri.value)
assert(actual.defaultObjectAccessPermission.forGroup.contains(SharedTestDataADM.thingSearcherGroup.id))
assert(
actual.defaultObjectAccessPermission.hasPermissions.contains(
@@ -216,7 +209,7 @@ class PermissionsResponderSpec extends CoreSpec with ImplicitSender {
_.createDefaultObjectAccessPermission(
createRequest = CreateDefaultObjectAccessPermissionAPIRequestADM(
id = Some(customIri),
- forProject = SharedTestDataADM.anythingProjectIri,
+ forProject = SharedTestDataADM.anythingProjectIri.value,
forGroup = Some(KnoraGroupRepo.builtIn.UnknownUser.id.value),
hasPermissions = Set(
PermissionADM
@@ -229,7 +222,7 @@ class PermissionsResponderSpec extends CoreSpec with ImplicitSender {
)
assert(received.defaultObjectAccessPermission.iri == customIri)
assert(received.defaultObjectAccessPermission.forGroup.contains(KnoraGroupRepo.builtIn.UnknownUser.id.value))
- assert(received.defaultObjectAccessPermission.forProject == SharedTestDataADM.anythingProjectIri)
+ assert(received.defaultObjectAccessPermission.forProject == SharedTestDataADM.anythingProjectIri.value)
assert(
received.defaultObjectAccessPermission.hasPermissions
.contains(
@@ -243,7 +236,7 @@ class PermissionsResponderSpec extends CoreSpec with ImplicitSender {
permissionsResponder(
_.createDefaultObjectAccessPermission(
CreateDefaultObjectAccessPermissionAPIRequestADM(
- forProject = imagesProjectIri,
+ forProject = imagesProjectIri.value,
forResourceClass = Some(SharedOntologyTestDataADM.IMAGES_BILD_RESOURCE_CLASS),
hasPermissions =
Set(PermissionADM.from(Permission.ObjectAccess.Modify, KnoraGroupRepo.builtIn.KnownUser.id.value)),
@@ -252,7 +245,7 @@ class PermissionsResponderSpec extends CoreSpec with ImplicitSender {
),
),
)
- assert(actual.defaultObjectAccessPermission.forProject == imagesProjectIri)
+ assert(actual.defaultObjectAccessPermission.forProject == imagesProjectIri.value)
assert(
actual.defaultObjectAccessPermission.forResourceClass
.contains(SharedOntologyTestDataADM.IMAGES_BILD_RESOURCE_CLASS),
@@ -268,7 +261,7 @@ class PermissionsResponderSpec extends CoreSpec with ImplicitSender {
permissionsResponder(
_.createDefaultObjectAccessPermission(
CreateDefaultObjectAccessPermissionAPIRequestADM(
- forProject = imagesProjectIri,
+ forProject = imagesProjectIri.value,
forProperty = Some(SharedOntologyTestDataADM.IMAGES_TITEL_PROPERTY),
hasPermissions = Set(
PermissionADM.from(Permission.ObjectAccess.ChangeRights, KnoraGroupRepo.builtIn.Creator.id.value),
@@ -278,7 +271,7 @@ class PermissionsResponderSpec extends CoreSpec with ImplicitSender {
),
),
)
- assert(actual.defaultObjectAccessPermission.forProject == imagesProjectIri)
+ assert(actual.defaultObjectAccessPermission.forProject == imagesProjectIri.value)
assert(
actual.defaultObjectAccessPermission.forProperty
.contains(SharedOntologyTestDataADM.IMAGES_TITEL_PROPERTY),
@@ -406,7 +399,7 @@ class PermissionsResponderSpec extends CoreSpec with ImplicitSender {
permissionsResponder(
_.createDefaultObjectAccessPermission(
CreateDefaultObjectAccessPermissionAPIRequestADM(
- forProject = imagesProjectIri,
+ forProject = imagesProjectIri.value,
forGroup = Some(KnoraGroupRepo.builtIn.UnknownUser.id.value),
hasPermissions = hasPermissions,
),
@@ -414,7 +407,7 @@ class PermissionsResponderSpec extends CoreSpec with ImplicitSender {
),
),
)
- assert(actual.defaultObjectAccessPermission.forProject == imagesProjectIri)
+ assert(actual.defaultObjectAccessPermission.forProject == imagesProjectIri.value)
assert(actual.defaultObjectAccessPermission.forGroup.contains(KnoraGroupRepo.builtIn.UnknownUser.id.value))
assert(
actual.defaultObjectAccessPermission.hasPermissions.contains(
@@ -442,7 +435,7 @@ class PermissionsResponderSpec extends CoreSpec with ImplicitSender {
permissionsResponder(
_.createDefaultObjectAccessPermission(
CreateDefaultObjectAccessPermissionAPIRequestADM(
- forProject = imagesProjectIri,
+ forProject = imagesProjectIri.value,
forGroup = Some(KnoraGroupRepo.builtIn.ProjectAdmin.id.value),
hasPermissions = hasPermissions,
),
@@ -450,7 +443,7 @@ class PermissionsResponderSpec extends CoreSpec with ImplicitSender {
),
),
)
- assert(actual.defaultObjectAccessPermission.forProject == imagesProjectIri)
+ assert(actual.defaultObjectAccessPermission.forProject == imagesProjectIri.value)
assert(actual.defaultObjectAccessPermission.forGroup.contains(KnoraGroupRepo.builtIn.ProjectAdmin.id.value))
assert(actual.defaultObjectAccessPermission.hasPermissions.equals(expectedPermissions))
}
@@ -459,21 +452,13 @@ class PermissionsResponderSpec extends CoreSpec with ImplicitSender {
"ask to get all permissions" should {
"return all permissions for 'image' project" in {
- val actual = UnsafeZioRun.runOrThrow(
- permissionsResponder(
- _.getPermissionsByProjectIri(ProjectIri.unsafeFrom(imagesProjectIri)),
- ),
- )
+ val actual = UnsafeZioRun.runOrThrow(permissionsResponder(_.getPermissionsByProjectIri(imagesProjectIri)))
actual.permissions.size should be(10)
}
"return all permissions for 'incunabula' project" in {
val actual = UnsafeZioRun.runOrThrow(
- permissionsResponder(
- _.getPermissionsByProjectIri(
- ProjectIri.unsafeFrom(SharedTestDataADM.incunabulaProjectIri),
- ),
- ),
+ permissionsResponder(_.getPermissionsByProjectIri(SharedTestDataADM.incunabulaProjectIri)),
)
actual shouldEqual
PermissionsForProjectGetResponseADM(permissions =
@@ -517,7 +502,7 @@ class PermissionsResponderSpec extends CoreSpec with ImplicitSender {
val actual = UnsafeZioRun.runOrThrow(
permissionsResponder(
_.newResourceDefaultObjectAccessPermissions(
- ProjectIri.unsafeFrom(SharedTestDataADM.incunabulaProjectIri),
+ SharedTestDataADM.incunabulaProjectIri,
SharedOntologyTestDataADM.INCUNABULA_BOOK_RESOURCE_CLASS.toSmartIri,
SharedTestDataADM.incunabulaProjectAdminUser,
),
@@ -534,7 +519,7 @@ class PermissionsResponderSpec extends CoreSpec with ImplicitSender {
val actual = UnsafeZioRun.runOrThrow(
permissionsResponder(
_.newResourceDefaultObjectAccessPermissions(
- ProjectIri.unsafeFrom(SharedTestDataADM.incunabulaProjectIri),
+ SharedTestDataADM.incunabulaProjectIri,
SharedOntologyTestDataADM.INCUNABULA_PAGE_RESOURCE_CLASS.toSmartIri,
SharedTestDataADM.incunabulaProjectAdminUser,
),
@@ -551,7 +536,7 @@ class PermissionsResponderSpec extends CoreSpec with ImplicitSender {
val actual = UnsafeZioRun.runOrThrow(
permissionsResponder(
_.newValueDefaultObjectAccessPermissions(
- ProjectIri.unsafeFrom(SharedTestDataADM.anythingProjectIri),
+ SharedTestDataADM.anythingProjectIri,
stringFormatter.toSmartIri("http://www.knora.org/ontology/0001/anything#Thing"),
stringFormatter.toSmartIri("http://www.knora.org/ontology/0001/anything#hasInterval"),
SharedTestDataADM.anythingUser2,
@@ -570,7 +555,7 @@ class PermissionsResponderSpec extends CoreSpec with ImplicitSender {
val actual = UnsafeZioRun.runOrThrow(
permissionsResponder(
_.newResourceDefaultObjectAccessPermissions(
- ProjectIri.unsafeFrom(SharedTestDataADM.anythingProjectIri),
+ SharedTestDataADM.anythingProjectIri,
"http://www.knora.org/ontology/0001/anything#Thing".toSmartIri,
SharedTestDataADM.anythingUser2,
),
@@ -588,7 +573,7 @@ class PermissionsResponderSpec extends CoreSpec with ImplicitSender {
.runOrThrow(
permissionsResponder(
_.newValueDefaultObjectAccessPermissions(
- projectIri = ProjectIri.unsafeFrom(SharedTestDataADM.anythingProjectIri),
+ projectIri = SharedTestDataADM.anythingProjectIri,
resourceClassIri = stringFormatter.toSmartIri("http://www.knora.org/ontology/0001/anything#Thing"),
propertyIri = stringFormatter.toSmartIri("http://www.knora.org/ontology/0001/anything#hasText"),
targetUser = SharedTestDataADM.anythingUser1,
@@ -603,7 +588,7 @@ class PermissionsResponderSpec extends CoreSpec with ImplicitSender {
.runOrThrow(
permissionsResponder(
_.newValueDefaultObjectAccessPermissions(
- ProjectIri.unsafeFrom(SharedTestDataADM.anythingProjectIri),
+ SharedTestDataADM.anythingProjectIri,
stringFormatter.toSmartIri(s"${SharedOntologyTestDataADM.IMAGES_ONTOLOGY_IRI}#bild"),
stringFormatter.toSmartIri("http://www.knora.org/ontology/0001/anything#hasText"),
SharedTestDataADM.anythingUser2,
@@ -623,7 +608,7 @@ class PermissionsResponderSpec extends CoreSpec with ImplicitSender {
.run(
permissionsResponder(
_.newValueDefaultObjectAccessPermissions(
- ProjectIri.unsafeFrom(SharedTestDataADM.imagesProjectIri),
+ SharedTestDataADM.imagesProjectIri,
stringFormatter.toSmartIri(SharedTestDataADM.customResourceIRI),
stringFormatter.toSmartIri(SharedOntologyTestDataADM.IMAGES_TITEL_PROPERTY),
SharedTestDataADM.imagesReviewerUser,
@@ -640,7 +625,7 @@ class PermissionsResponderSpec extends CoreSpec with ImplicitSender {
val exit = UnsafeZioRun.run(
permissionsResponder(
_.newValueDefaultObjectAccessPermissions(
- ProjectIri.unsafeFrom(SharedTestDataADM.imagesProjectIri),
+ SharedTestDataADM.imagesProjectIri,
stringFormatter.toSmartIri(SharedOntologyTestDataADM.IMAGES_BILD_RESOURCE_CLASS),
stringFormatter.toSmartIri(SharedTestDataADM.customValueIRI),
SharedTestDataADM.imagesReviewerUser,
@@ -654,7 +639,7 @@ class PermissionsResponderSpec extends CoreSpec with ImplicitSender {
val exit = UnsafeZioRun.run(
permissionsResponder(
_.newValueDefaultObjectAccessPermissions(
- ProjectIri.unsafeFrom(SharedTestDataADM.imagesProjectIri),
+ SharedTestDataADM.imagesProjectIri,
stringFormatter.toSmartIri(SharedOntologyTestDataADM.IMAGES_BILD_RESOURCE_CLASS),
stringFormatter.toSmartIri(SharedOntologyTestDataADM.IMAGES_TITEL_PROPERTY),
SharedTestDataADM.anonymousUser,
@@ -668,7 +653,7 @@ class PermissionsResponderSpec extends CoreSpec with ImplicitSender {
val actual = UnsafeZioRun.runOrThrow(
permissionsResponder(
_.newResourceDefaultObjectAccessPermissions(
- ProjectIri.unsafeFrom(SharedTestDataADM.anythingProjectIri),
+ SharedTestDataADM.anythingProjectIri,
"http://www.knora.org/ontology/0001/anything#Thing".toSmartIri,
SharedTestDataADM.rootUser,
),
diff --git a/integration/src/test/scala/org/knora/webapi/responders/admin/ProjectRestServiceSpec.scala b/integration/src/test/scala/org/knora/webapi/responders/admin/ProjectRestServiceSpec.scala
index 4f4430d0c9..38b3268a04 100644
--- a/integration/src/test/scala/org/knora/webapi/responders/admin/ProjectRestServiceSpec.scala
+++ b/integration/src/test/scala/org/knora/webapi/responders/admin/ProjectRestServiceSpec.scala
@@ -59,7 +59,7 @@ class ProjectRestServiceSpec extends CoreSpec with ImplicitSender {
"return information about a project identified by IRI" in {
val actual = UnsafeZioRun.runOrThrow(
- ProjectRestService(_.findById(SharedTestDataADM.incunabulaProject.projectIri)),
+ ProjectRestService(_.findById(SharedTestDataADM.incunabulaProject.id)),
)
assert(actual == ProjectGetResponse(toExternal(SharedTestDataADM.incunabulaProject)))
}
@@ -97,7 +97,7 @@ class ProjectRestServiceSpec extends CoreSpec with ImplicitSender {
"return restricted view settings using project IRI" in {
val actual = UnsafeZioRun.runOrThrow(
ProjectRestService(
- _.getProjectRestrictedViewSettingsById(SharedTestDataADM.imagesProject.projectIri),
+ _.getProjectRestrictedViewSettingsById(SharedTestDataADM.imagesProject.id),
),
)
actual shouldEqual expectedResult
@@ -179,17 +179,16 @@ class ProjectRestServiceSpec extends CoreSpec with ImplicitSender {
received.project.copyrightAttribution should be(Some(CopyrightAttribution.unsafeFrom("2024, Example Project")))
received.project.license should be(Some(License.unsafeFrom("CC-BY-4.0")))
- newProjectIri.set(received.project.id)
+ newProjectIri.set(received.project.id.value)
// Check Administrative Permissions
- val receivedApAdmin =
- UnsafeZioRun.runOrThrow(
- ZIO.serviceWithZIO[PermissionsResponder](_.getPermissionsApByProjectIri(received.project.id)),
- )
+ val receivedApAdmin = UnsafeZioRun.runOrThrow(
+ ZIO.serviceWithZIO[PermissionsResponder](_.getPermissionsApByProjectIri(received.project.id)),
+ )
val hasAPForProjectAdmin = receivedApAdmin.administrativePermissions.filter {
(ap: AdministrativePermissionADM) =>
- ap.forProject == received.project.id && ap.forGroup == KnoraGroupRepo.builtIn.ProjectAdmin.id.value &&
+ ap.forProject == received.project.id.value && ap.forGroup == KnoraGroupRepo.builtIn.ProjectAdmin.id.value &&
ap.hasPermissions.equals(
Set(
PermissionADM.from(Permission.Administrative.ProjectAdminAll),
@@ -203,7 +202,7 @@ class ProjectRestServiceSpec extends CoreSpec with ImplicitSender {
// Check Administrative Permission of ProjectMember
val hasAPForProjectMember = receivedApAdmin.administrativePermissions.filter {
(ap: AdministrativePermissionADM) =>
- ap.forProject == received.project.id && ap.forGroup == KnoraGroupRepo.builtIn.ProjectMember.id.value &&
+ ap.forProject == received.project.id.value && ap.forGroup == KnoraGroupRepo.builtIn.ProjectMember.id.value &&
ap.hasPermissions.equals(Set(PermissionADM.from(Permission.Administrative.ProjectResourceCreateAll)))
}
hasAPForProjectMember.size shouldBe 1
@@ -211,14 +210,14 @@ class ProjectRestServiceSpec extends CoreSpec with ImplicitSender {
// Check Default Object Access permissions
val receivedDoaps = UnsafeZioRun.runOrThrow(
ZIO.serviceWithZIO[PermissionsResponder](
- _.getPermissionsDaopByProjectIri(ProjectIri.unsafeFrom(received.project.id)),
+ _.getPermissionsDaopByProjectIri(received.project.id),
),
)
// Check Default Object Access permission of ProjectAdmin
val hasDOAPForProjectAdmin = receivedDoaps.defaultObjectAccessPermissions.filter {
(doap: DefaultObjectAccessPermissionADM) =>
- doap.forProject == received.project.id && doap.forGroup.contains(
+ doap.forProject == received.project.id.value && doap.forGroup.contains(
KnoraGroupRepo.builtIn.ProjectAdmin.id.value,
) &&
doap.hasPermissions.equals(
@@ -233,7 +232,7 @@ class ProjectRestServiceSpec extends CoreSpec with ImplicitSender {
// Check Default Object Access permission of ProjectMember
val hasDOAPForProjectMember = receivedDoaps.defaultObjectAccessPermissions.filter {
(doap: DefaultObjectAccessPermissionADM) =>
- doap.forProject == received.project.id && doap.forGroup.contains(
+ doap.forProject == received.project.id.value && doap.forGroup.contains(
KnoraGroupRepo.builtIn.ProjectMember.id.value,
) &&
doap.hasPermissions.equals(
@@ -434,7 +433,7 @@ class ProjectRestServiceSpec extends CoreSpec with ImplicitSender {
"return all members of a project identified by IRI" in {
val actual = UnsafeZioRun.runOrThrow(
ProjectRestService(
- _.getProjectMembersById(SharedTestDataADM.rootUser, SharedTestDataADM.imagesProject.projectIri),
+ _.getProjectMembersById(SharedTestDataADM.rootUser, SharedTestDataADM.imagesProject.id),
),
)
@@ -510,7 +509,7 @@ class ProjectRestServiceSpec extends CoreSpec with ImplicitSender {
"return all project admin members of a project identified by IRI" in {
val received = UnsafeZioRun.runOrThrow(
ProjectRestService(
- _.getProjectAdminMembersById(SharedTestDataADM.rootUser, SharedTestDataADM.imagesProject.projectIri),
+ _.getProjectAdminMembersById(SharedTestDataADM.rootUser, SharedTestDataADM.imagesProject.id),
),
)
@@ -593,7 +592,7 @@ class ProjectRestServiceSpec extends CoreSpec with ImplicitSender {
"return all keywords for a single project" in {
val received = UnsafeZioRun.runOrThrow(
ProjectRestService(
- _.getKeywordsByProjectIri(SharedTestDataADM.incunabulaProject.projectIri),
+ _.getKeywordsByProjectIri(SharedTestDataADM.incunabulaProject.id),
),
)
received.keywords should be(SharedTestDataADM.incunabulaProject.keywords)
@@ -601,7 +600,7 @@ class ProjectRestServiceSpec extends CoreSpec with ImplicitSender {
"return empty list for a project without keywords" in {
val received = UnsafeZioRun.runOrThrow(
- ProjectRestService(_.getKeywordsByProjectIri(SharedTestDataADM.dokubibProject.projectIri)),
+ ProjectRestService(_.getKeywordsByProjectIri(SharedTestDataADM.dokubibProject.id)),
)
received.keywords should be(Seq.empty[String])
}
diff --git a/integration/src/test/scala/org/knora/webapi/responders/admin/UserRestServiceSpec.scala b/integration/src/test/scala/org/knora/webapi/responders/admin/UserRestServiceSpec.scala
index 437284f63c..e130cfef1d 100644
--- a/integration/src/test/scala/org/knora/webapi/responders/admin/UserRestServiceSpec.scala
+++ b/integration/src/test/scala/org/knora/webapi/responders/admin/UserRestServiceSpec.scala
@@ -366,7 +366,7 @@ class UserRestServiceSpec extends CoreSpec with ImplicitSender {
// add user to images project (00FF)
UnsafeZioRun.runOrThrow(
- userRestService(_.addUserToProject(rootUser, normalUser.userIri, imagesProject.projectIri)),
+ userRestService(_.addUserToProject(rootUser, normalUser.userIri, imagesProject.id)),
)
val membershipsAfterUpdate =
@@ -375,7 +375,7 @@ class UserRestServiceSpec extends CoreSpec with ImplicitSender {
val received = UnsafeZioRun.runOrThrow(
projectRestService(
- _.getProjectMembersById(KnoraSystemInstances.Users.SystemUser, imagesProject.projectIri),
+ _.getProjectMembersById(KnoraSystemInstances.Users.SystemUser, imagesProject.id),
),
)
received.members.map(_.id) should contain(normalUser.id)
@@ -385,22 +385,22 @@ class UserRestServiceSpec extends CoreSpec with ImplicitSender {
// get current project memberships
val membershipsBeforeUpdate =
UnsafeZioRun.runOrThrow(userRestService(_.getProjectMemberShipsByUserIri(normalUser.userIri)))
- membershipsBeforeUpdate.projects.map(_.id).sorted should equal(Seq(imagesProject.id).sorted)
+ membershipsBeforeUpdate.projects.map(_.id).sortBy(_.value) should equal(Seq(imagesProject.id).sortBy(_.value))
// add user to images project (00FF)
UnsafeZioRun.runOrThrow(
- userRestService(_.addUserToProject(rootUser, normalUser.userIri, incunabulaProject.projectIri)),
+ userRestService(_.addUserToProject(rootUser, normalUser.userIri, incunabulaProject.id)),
)
val membershipsAfterUpdate =
UnsafeZioRun.runOrThrow(userRestService(_.getProjectMemberShipsByUserIri(normalUser.userIri)))
- membershipsAfterUpdate.projects.map(_.id).sorted should equal(
- Seq(imagesProject.id, incunabulaProject.id).sorted,
+ membershipsAfterUpdate.projects.map(_.id).sortBy(_.value) should equal(
+ Seq(imagesProject.id, incunabulaProject.id).sortBy(_.value),
)
val received = UnsafeZioRun.runOrThrow(
projectRestService(
- _.getProjectMembersById(KnoraSystemInstances.Users.SystemUser, incunabulaProject.projectIri),
+ _.getProjectMembersById(KnoraSystemInstances.Users.SystemUser, incunabulaProject.id),
),
)
received.members.map(_.id) should contain(normalUser.id)
@@ -410,23 +410,25 @@ class UserRestServiceSpec extends CoreSpec with ImplicitSender {
// check project memberships (user should be member of images and incunabula projects)
val membershipsBeforeUpdate =
UnsafeZioRun.runOrThrow(userRestService(_.getProjectMemberShipsByUserIri(normalUser.userIri)))
- membershipsBeforeUpdate.projects.map(_.id).sorted should equal(
- Seq(imagesProject.id, incunabulaProject.id).sorted,
+ membershipsBeforeUpdate.projects.map(_.id).sortBy(_.value) should equal(
+ Seq(imagesProject.id, incunabulaProject.id).sortBy(_.value),
)
// add user as project admin to images project
UnsafeZioRun.runOrThrow(
- userRestService(_.addUserToProjectAsAdmin(rootUser, normalUser.userIri, imagesProject.projectIri)),
+ userRestService(_.addUserToProjectAsAdmin(rootUser, normalUser.userIri, imagesProject.id)),
)
// verify that the user has been added as project admin to the images project
val projectAdminMembershipsBeforeUpdate =
UnsafeZioRun.runOrThrow(userRestService(_.getProjectAdminMemberShipsByUserIri(normalUser.userIri)))
- projectAdminMembershipsBeforeUpdate.projects.map(_.id).sorted should equal(Seq(imagesProject.id).sorted)
+ projectAdminMembershipsBeforeUpdate.projects.map(_.id).sortBy(_.value) should equal(
+ Seq(imagesProject.id).sortBy(_.value),
+ )
// remove the user as member of the images project
UnsafeZioRun.runOrThrow(
- userRestService(_.removeUserFromProject(rootUser, normalUser.userIri, imagesProject.projectIri)),
+ userRestService(_.removeUserFromProject(rootUser, normalUser.userIri, imagesProject.id)),
)
// verify that the user has been removed as project member of the images project
@@ -441,7 +443,7 @@ class UserRestServiceSpec extends CoreSpec with ImplicitSender {
// also check that the user has been removed from the project's list of users
val received = UnsafeZioRun.runOrThrow(
- projectRestService(_.getProjectMembersById(rootUser, imagesProject.projectIri)),
+ projectRestService(_.getProjectMembersById(rootUser, imagesProject.id)),
)
received.members should not contain normalUser.ofType(UserInformationType.Restricted)
}
@@ -456,7 +458,7 @@ class UserRestServiceSpec extends CoreSpec with ImplicitSender {
// try to add user as project admin to images project (expected to fail because he is not a member of the project)
val exit = UnsafeZioRun.run(
- userRestService(_.addUserToProjectAsAdmin(rootUser, normalUser.userIri, imagesProject.projectIri)),
+ userRestService(_.addUserToProjectAsAdmin(rootUser, normalUser.userIri, imagesProject.id)),
)
assertFailsWithA[BadRequestException](
exit,
@@ -472,12 +474,12 @@ class UserRestServiceSpec extends CoreSpec with ImplicitSender {
// add user as project member to images project
UnsafeZioRun.runOrThrow(
- userRestService(_.addUserToProject(rootUser, normalUser.userIri, imagesProject.projectIri)),
+ userRestService(_.addUserToProject(rootUser, normalUser.userIri, imagesProject.id)),
)
// add user as project admin to images project
UnsafeZioRun.runOrThrow(
- userRestService(_.addUserToProjectAsAdmin(rootUser, normalUser.userIri, imagesProject.projectIri)),
+ userRestService(_.addUserToProjectAsAdmin(rootUser, normalUser.userIri, imagesProject.id)),
)
// get the updated project admin memberships (should contain images project)
@@ -487,7 +489,7 @@ class UserRestServiceSpec extends CoreSpec with ImplicitSender {
// get project admins for images project (should contain normal user)
val received = UnsafeZioRun.runOrThrow(
- projectRestService(_.getProjectAdminMembersById(rootUser, imagesProject.projectIri)),
+ projectRestService(_.getProjectAdminMembersById(rootUser, imagesProject.id)),
)
received.members.map(_.id) should contain(normalUser.id)
}
@@ -498,7 +500,7 @@ class UserRestServiceSpec extends CoreSpec with ImplicitSender {
membershipsBeforeUpdate.projects.map(_.id) should equal(Seq(imagesProject.id))
UnsafeZioRun.runOrThrow(
- userRestService(_.removeUserFromProjectAsAdmin(rootUser, normalUser.userIri, imagesProject.projectIri)),
+ userRestService(_.removeUserFromProjectAsAdmin(rootUser, normalUser.userIri, imagesProject.id)),
)
val membershipsAfterUpdate =
@@ -506,7 +508,7 @@ class UserRestServiceSpec extends CoreSpec with ImplicitSender {
membershipsAfterUpdate.projects should equal(Seq())
val received = UnsafeZioRun.runOrThrow(
- projectRestService(_.getProjectAdminMembersById(rootUser, imagesProject.projectIri)),
+ projectRestService(_.getProjectAdminMembersById(rootUser, imagesProject.id)),
)
received.members should not contain normalUser.ofType(UserInformationType.Restricted)
}
diff --git a/integration/src/test/scala/org/knora/webapi/responders/v2/OntologyResponderV2Spec.scala b/integration/src/test/scala/org/knora/webapi/responders/v2/OntologyResponderV2Spec.scala
index 0b454597e4..0b214b4ab1 100644
--- a/integration/src/test/scala/org/knora/webapi/responders/v2/OntologyResponderV2Spec.scala
+++ b/integration/src/test/scala/org/knora/webapi/responders/v2/OntologyResponderV2Spec.scala
@@ -51,10 +51,10 @@ class OntologyResponderV2Spec extends CoreSpec with ImplicitSender {
private implicit val stringFormatter: StringFormatter = StringFormatter.getGeneralInstance
private val imagesUser = SharedTestDataADM.imagesUser01
- private val imagesProjectIri = SharedTestDataADM.imagesProjectIri.toSmartIri
+ private val imagesProjectIri = SharedTestDataADM.imagesProjectIri.value.toSmartIri
private val anythingAdminUser = SharedTestDataADM.anythingAdminUser
private val anythingNonAdminUser = SharedTestDataADM.anythingUser1
- private val anythingProjectIri = SharedTestDataADM.anythingProjectIri.toSmartIri
+ private val anythingProjectIri = SharedTestDataADM.anythingProjectIri.value.toSmartIri
private val ontologyResponder = ZIO.serviceWithZIO[OntologyResponderV2]
private val triplestoreService = ZIO.serviceWithZIO[TriplestoreService]
@@ -636,7 +636,7 @@ class OntologyResponderV2Spec extends CoreSpec with ImplicitSender {
"not create a non-shared ontology in the shared ontologies project" in {
appActor ! CreateOntologyRequestV2(
ontologyName = "misplaced",
- projectIri = OntologyConstants.KnoraAdmin.DefaultSharedOntologiesProject.toSmartIri,
+ projectIri = OntologyConstants.KnoraAdmin.DefaultSharedOntologiesProject.value.toSmartIri,
label = "The invalid non-shared ontology",
apiRequestID = UUID.randomUUID,
requestingUser = SharedTestDataADM.superUser,
@@ -650,7 +650,7 @@ class OntologyResponderV2Spec extends CoreSpec with ImplicitSender {
"create a shared ontology" in {
appActor ! CreateOntologyRequestV2(
ontologyName = "chair",
- projectIri = OntologyConstants.KnoraAdmin.DefaultSharedOntologiesProject.toSmartIri,
+ projectIri = OntologyConstants.KnoraAdmin.DefaultSharedOntologiesProject.value.toSmartIri,
isShared = true,
label = "a chaired ontology",
apiRequestID = UUID.randomUUID,
diff --git a/integration/src/test/scala/org/knora/webapi/responders/v2/SearchResponderV2Spec.scala b/integration/src/test/scala/org/knora/webapi/responders/v2/SearchResponderV2Spec.scala
index b8fa79b87b..aaca388590 100644
--- a/integration/src/test/scala/org/knora/webapi/responders/v2/SearchResponderV2Spec.scala
+++ b/integration/src/test/scala/org/knora/webapi/responders/v2/SearchResponderV2Spec.scala
@@ -303,7 +303,7 @@ class SearchResponderV2Spec extends CoreSpec {
"search by project and resource class" in {
val result = UnsafeZioRun.runOrThrow(
searchResourcesByProjectAndClassV2(
- projectIri = SharedTestDataADM.incunabulaProject.id.toSmartIri,
+ projectIri = SharedTestDataADM.incunabulaProject.id.value.toSmartIri,
resourceClass = "http://0.0.0.0:3333/ontology/0803/incunabula/v2#book".toSmartIri,
orderByProperty = Some("http://0.0.0.0:3333/ontology/0803/incunabula/v2#title".toSmartIri),
page = 0,
diff --git a/integration/src/test/scala/org/knora/webapi/sharedtestdata/ProjectInfo.scala b/integration/src/test/scala/org/knora/webapi/sharedtestdata/ProjectInfo.scala
index 686a89a398..466f842d84 100644
--- a/integration/src/test/scala/org/knora/webapi/sharedtestdata/ProjectInfo.scala
+++ b/integration/src/test/scala/org/knora/webapi/sharedtestdata/ProjectInfo.scala
@@ -37,7 +37,7 @@ case class ProjectInfo(
object ProjectInfo {
def from(project: Project): ProjectInfo =
ProjectInfo(
- id = project.id,
+ id = project.id.value,
shortname = project.shortname.value,
shortcode = project.shortcode.value,
longname = project.longname.map(_.value),
diff --git a/integration/src/test/scala/org/knora/webapi/sharedtestdata/SharedTestDataADM.scala b/integration/src/test/scala/org/knora/webapi/sharedtestdata/SharedTestDataADM.scala
index db866f5097..797c38886d 100644
--- a/integration/src/test/scala/org/knora/webapi/sharedtestdata/SharedTestDataADM.scala
+++ b/integration/src/test/scala/org/knora/webapi/sharedtestdata/SharedTestDataADM.scala
@@ -6,6 +6,7 @@
package org.knora.webapi.sharedtestdata
import java.time.Instant
+
import dsp.constants.SalsahGui
import org.knora.webapi.IRI
import org.knora.webapi.messages.OntologyConstants
@@ -17,6 +18,7 @@ import org.knora.webapi.slice.admin.api.model.Project
import org.knora.webapi.slice.admin.domain.model.Group
import org.knora.webapi.slice.admin.domain.model.KnoraProject.Logo
import org.knora.webapi.slice.admin.domain.model.KnoraProject.Longname
+import org.knora.webapi.slice.admin.domain.model.KnoraProject.ProjectIri
import org.knora.webapi.slice.admin.domain.model.KnoraProject.SelfJoin
import org.knora.webapi.slice.admin.domain.model.KnoraProject.Shortcode
import org.knora.webapi.slice.admin.domain.model.KnoraProject.Shortname
@@ -134,22 +136,22 @@ object SharedTestDataADM {
projects = Seq(incunabulaProject, imagesProject),
permissions = PermissionsDataADM(
groupsPerProject = Map(
- incunabulaProjectIri -> List(
+ incunabulaProjectIri.value -> List(
KnoraGroupRepo.builtIn.ProjectMember.id.value,
KnoraGroupRepo.builtIn.ProjectAdmin.id.value,
),
- imagesProjectIri -> List(
+ imagesProjectIri.value -> List(
"http://rdfh.ch/groups/00FF/images-reviewer",
KnoraGroupRepo.builtIn.ProjectMember.id.value,
KnoraGroupRepo.builtIn.ProjectAdmin.id.value,
),
),
administrativePermissionsPerProject = Map(
- incunabulaProjectIri -> Set(
+ incunabulaProjectIri.value -> Set(
PermissionADM.from(Permission.Administrative.ProjectAdminAll),
PermissionADM.from(Permission.Administrative.ProjectResourceCreateAll),
),
- imagesProjectIri -> Set(
+ imagesProjectIri.value -> Set(
PermissionADM.from(Permission.Administrative.ProjectAdminAll),
PermissionADM.from(Permission.Administrative.ProjectResourceCreateAll),
),
@@ -159,7 +161,7 @@ object SharedTestDataADM {
/* represents the full ProjectADM of the Knora System project */
def systemProject: Project = Project(
- id = KnoraProjectRepo.builtIn.SystemProject.id.value,
+ id = KnoraProjectRepo.builtIn.SystemProject.id,
shortname = Shortname.unsafeFrom("SystemProject"),
shortcode = Shortcode.unsafeFrom("FFFF"),
longname = Some(Longname.unsafeFrom("Knora System Project")),
@@ -201,7 +203,7 @@ object SharedTestDataADM {
/**
* **********************************
*/
- val imagesProjectIri = "http://rdfh.ch/projects/00FF"
+ val imagesProjectIri: ProjectIri = ProjectIri.unsafeFrom("http://rdfh.ch/projects/00FF")
/* represents 'user01' as found in admin-data.ttl */
def imagesUser01: User =
@@ -218,13 +220,13 @@ object SharedTestDataADM {
projects = Seq(imagesProject),
permissions = PermissionsDataADM(
groupsPerProject = Map(
- imagesProjectIri -> List(
+ imagesProjectIri.value -> List(
KnoraGroupRepo.builtIn.ProjectMember.id.value,
KnoraGroupRepo.builtIn.ProjectAdmin.id.value,
),
),
administrativePermissionsPerProject = Map(
- imagesProjectIri -> Set(
+ imagesProjectIri.value -> Set(
PermissionADM.from(Permission.Administrative.ProjectAdminAll),
PermissionADM.from(Permission.Administrative.ProjectResourceCreateAll),
),
@@ -247,10 +249,10 @@ object SharedTestDataADM {
projects = Seq(imagesProject),
permissions = PermissionsDataADM(
groupsPerProject = Map(
- imagesProjectIri -> List(KnoraGroupRepo.builtIn.ProjectMember.id.value),
+ imagesProjectIri.value -> List(KnoraGroupRepo.builtIn.ProjectMember.id.value),
),
administrativePermissionsPerProject = Map(
- imagesProjectIri -> Set(
+ imagesProjectIri.value -> Set(
PermissionADM.from(Permission.Administrative.ProjectResourceCreateAll),
),
),
@@ -272,13 +274,13 @@ object SharedTestDataADM {
projects = Seq(imagesProject),
permissions = PermissionsDataADM(
groupsPerProject = Map(
- imagesProjectIri -> List(
+ imagesProjectIri.value -> List(
"http://rdfh.ch/groups/00FF/images-reviewer",
KnoraGroupRepo.builtIn.ProjectMember.id.value,
),
),
administrativePermissionsPerProject = Map(
- imagesProjectIri -> Set(
+ imagesProjectIri.value -> Set(
PermissionADM.from(
Permission.Administrative.ProjectResourceCreateRestricted,
s"${SharedOntologyTestDataADM.IMAGES_ONTOLOGY_IRI}#bild",
@@ -371,7 +373,7 @@ object SharedTestDataADM {
/**
* **********************************
*/
- val incunabulaProjectIri = "http://rdfh.ch/projects/0803"
+ val incunabulaProjectIri: ProjectIri = ProjectIri.unsafeFrom("http://rdfh.ch/projects/0803")
/* represents 'testuser' (Incunabula ProjectAdmin) as found in admin-data.ttl */
def incunabulaProjectAdminUser: User =
@@ -388,13 +390,13 @@ object SharedTestDataADM {
projects = Seq(incunabulaProject),
permissions = PermissionsDataADM(
groupsPerProject = Map(
- incunabulaProjectIri -> List(
+ incunabulaProjectIri.value -> List(
KnoraGroupRepo.builtIn.ProjectMember.id.value,
KnoraGroupRepo.builtIn.ProjectAdmin.id.value,
),
),
administrativePermissionsPerProject = Map(
- incunabulaProjectIri -> Set(
+ incunabulaProjectIri.value -> Set(
PermissionADM.from(Permission.Administrative.ProjectAdminAll),
PermissionADM.from(Permission.Administrative.ProjectResourceCreateAll),
),
@@ -417,10 +419,10 @@ object SharedTestDataADM {
projects = Seq(incunabulaProject),
permissions = PermissionsDataADM(
groupsPerProject = Map(
- incunabulaProjectIri -> List(KnoraGroupRepo.builtIn.ProjectMember.id.value),
+ incunabulaProjectIri.value -> List(KnoraGroupRepo.builtIn.ProjectMember.id.value),
),
administrativePermissionsPerProject = Map(
- incunabulaProjectIri -> Set(
+ incunabulaProjectIri.value -> Set(
PermissionADM.from(Permission.Administrative.ProjectResourceCreateAll),
),
),
@@ -442,10 +444,10 @@ object SharedTestDataADM {
projects = Seq(incunabulaProject),
permissions = PermissionsDataADM(
groupsPerProject = Map(
- incunabulaProjectIri -> List(KnoraGroupRepo.builtIn.ProjectMember.id.value),
+ incunabulaProjectIri.value -> List(KnoraGroupRepo.builtIn.ProjectMember.id.value),
),
administrativePermissionsPerProject = Map(
- incunabulaProjectIri -> Set(
+ incunabulaProjectIri.value -> Set(
PermissionADM.from(Permission.Administrative.ProjectResourceCreateAll),
),
),
@@ -533,7 +535,7 @@ object SharedTestDataADM {
/**
* *********************************
*/
- val anythingProjectIri = "http://rdfh.ch/projects/0001"
+ val anythingProjectIri: ProjectIri = ProjectIri.unsafeFrom("http://rdfh.ch/projects/0001")
val customResourceIRI: IRI = "http://rdfh.ch/0001/rYAMw7wSTbGw3boYHefByg"
val customResourceIRI_resourceWithValues: IRI = "http://rdfh.ch/0001/4PnSvolsTEa86KJ2EG76SQ"
@@ -560,13 +562,13 @@ object SharedTestDataADM {
projects = Seq(anythingProject),
permissions = PermissionsDataADM(
groupsPerProject = Map(
- anythingProjectIri -> List(
+ anythingProjectIri.value -> List(
KnoraGroupRepo.builtIn.ProjectMember.id.value,
KnoraGroupRepo.builtIn.ProjectAdmin.id.value,
),
),
administrativePermissionsPerProject = Map(
- anythingProjectIri -> Set(
+ anythingProjectIri.value -> Set(
PermissionADM.from(Permission.Administrative.ProjectAdminAll),
PermissionADM.from(Permission.Administrative.ProjectResourceCreateAll),
),
@@ -588,13 +590,13 @@ object SharedTestDataADM {
projects = Seq(anythingProject),
permissions = PermissionsDataADM(
groupsPerProject = Map(
- anythingProjectIri -> List(
+ anythingProjectIri.value -> List(
KnoraGroupRepo.builtIn.ProjectMember.id.value,
"http://rdfh.ch/groups/0001/thing-searcher",
),
),
administrativePermissionsPerProject = Map(
- anythingProjectIri -> Set(
+ anythingProjectIri.value -> Set(
PermissionADM.from(Permission.Administrative.ProjectResourceCreateAll),
),
),
@@ -615,10 +617,10 @@ object SharedTestDataADM {
projects = Seq(anythingProject),
permissions = PermissionsDataADM(
groupsPerProject = Map(
- anythingProjectIri -> List(KnoraGroupRepo.builtIn.ProjectMember.id.value),
+ anythingProjectIri.value -> List(KnoraGroupRepo.builtIn.ProjectMember.id.value),
),
administrativePermissionsPerProject = Map(
- anythingProjectIri -> Set(
+ anythingProjectIri.value -> Set(
PermissionADM.from(Permission.Administrative.ProjectResourceCreateAll),
),
),
@@ -675,7 +677,7 @@ object SharedTestDataADM {
/**
* *********************************
*/
- val beolProjectIri = "http://rdfh.ch/projects/yTerZGyxjZVqFMNNKXCDPF"
+ val beolProjectIri: ProjectIri = ProjectIri.unsafeFrom("http://rdfh.ch/projects/yTerZGyxjZVqFMNNKXCDPF")
def beolProject: Project = Project(
id = beolProjectIri,
@@ -711,13 +713,13 @@ object SharedTestDataADM {
projects = Seq(beolProject),
permissions = PermissionsDataADM(
groupsPerProject = Map(
- beolProjectIri -> List(
+ beolProjectIri.value -> List(
KnoraGroupRepo.builtIn.ProjectMember.id.value,
KnoraGroupRepo.builtIn.ProjectAdmin.id.value,
),
),
administrativePermissionsPerProject = Map(
- beolProjectIri -> Set(
+ beolProjectIri.value -> Set(
PermissionADM.from(Permission.Administrative.ProjectAdminAll),
),
),
@@ -731,7 +733,7 @@ object SharedTestDataADM {
/**
* *********************************
*/
- val dokubibProjectIri = "http://rdfh.ch/projects/0804"
+ val dokubibProjectIri: ProjectIri = ProjectIri.unsafeFrom("http://rdfh.ch/projects/0804")
def dokubibProject: Project = Project(
id = dokubibProjectIri,
diff --git a/integration/src/test/scala/org/knora/webapi/sharedtestdata/UserProfile.scala b/integration/src/test/scala/org/knora/webapi/sharedtestdata/UserProfile.scala
index ca663afa12..34dba78e98 100644
--- a/integration/src/test/scala/org/knora/webapi/sharedtestdata/UserProfile.scala
+++ b/integration/src/test/scala/org/knora/webapi/sharedtestdata/UserProfile.scala
@@ -35,7 +35,7 @@ object UserProfile {
val v1Groups: Seq[IRI] = userADM.groups.map(_.id)
val projectsWithoutBuiltinProjects = userADM.projects
- .filter(_.id != KnoraProjectRepo.builtIn.SystemProject.id.value)
+ .filter(_.id != KnoraProjectRepo.builtIn.SystemProject.id)
.filter(_.id != OntologyConstants.KnoraAdmin.DefaultSharedOntologiesProject)
val projectInfosV1 = projectsWithoutBuiltinProjects.map(ProjectInfo.from)
val projects_info_v1: Map[IRI, ProjectInfo] =
diff --git a/integration/src/test/scala/org/knora/webapi/slice/admin/domain/service/KnoraUserToUserConverterSpec.scala b/integration/src/test/scala/org/knora/webapi/slice/admin/domain/service/KnoraUserToUserConverterSpec.scala
index a6c10f6623..6e6d1e3cfa 100644
--- a/integration/src/test/scala/org/knora/webapi/slice/admin/domain/service/KnoraUserToUserConverterSpec.scala
+++ b/integration/src/test/scala/org/knora/webapi/slice/admin/domain/service/KnoraUserToUserConverterSpec.scala
@@ -34,7 +34,7 @@ object KnoraUserToUserConverterSpec extends E2EZSpec {
isInProject: Iterable[IRI],
isInGroup: Iterable[IRI],
systemAdmin: SystemAdmin,
- isInProjectAdminGroup: Iterable[IRI],
+ isInProjectAdminGroup: Iterable[ProjectIri],
) = KnoraUser(
UserIri.unsafeFrom("http://rdfh.ch/users/dummy"),
Username.unsafeFrom("dummy"),
@@ -47,7 +47,7 @@ object KnoraUserToUserConverterSpec extends E2EZSpec {
isInProject.map(ProjectIri.unsafeFrom).toChunk,
isInGroup.map(GroupIri.unsafeFrom).toChunk,
systemAdmin,
- isInProjectAdminGroup.map(ProjectIri.unsafeFrom).toChunk,
+ isInProjectAdminGroup.toChunk,
)
private val knoraUserToUserConverter = ZIO.serviceWithZIO[KnoraUserToUserConverter]
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 ed6fc1db1e..b94d6a91c7 100644
--- a/webapi/src/main/scala/org/knora/webapi/messages/OntologyConstants.scala
+++ b/webapi/src/main/scala/org/knora/webapi/messages/OntologyConstants.scala
@@ -7,6 +7,7 @@ package org.knora.webapi
package messages
import dsp.constants.SalsahGui
+import org.knora.webapi.slice.admin.domain.model.KnoraProject.ProjectIri
/**
* Contains string constants for IRIs from ontologies used by the application.
@@ -495,7 +496,8 @@ object OntologyConstants {
HasDefaultChangeRightsPermission,
)
- val DefaultSharedOntologiesProject: IRI = KnoraAdminPrefixExpansion + "DefaultSharedOntologiesProject"
+ val DefaultSharedOntologiesProject: ProjectIri =
+ ProjectIri.unsafeFrom(KnoraAdminPrefixExpansion + "DefaultSharedOntologiesProject")
}
object Standoff {
diff --git a/webapi/src/main/scala/org/knora/webapi/messages/v2/responder/resourcemessages/ResourceMessagesV2.scala b/webapi/src/main/scala/org/knora/webapi/messages/v2/responder/resourcemessages/ResourceMessagesV2.scala
index 43a2623aed..950bd172e6 100644
--- a/webapi/src/main/scala/org/knora/webapi/messages/v2/responder/resourcemessages/ResourceMessagesV2.scala
+++ b/webapi/src/main/scala/org/knora/webapi/messages/v2/responder/resourcemessages/ResourceMessagesV2.scala
@@ -435,7 +435,7 @@ case class ReadResourceV2(
val metadataForComplexSchema: Map[IRI, JsonLDValue] = if (targetSchema == ApiV2Complex) {
val requiredMetadataForComplexSchema: Map[IRI, JsonLDValue] = Map(
KnoraApiV2Complex.AttachedToUser -> JsonLDUtil.iriToJsonLDObject(attachedToUser),
- KnoraApiV2Complex.AttachedToProject -> JsonLDUtil.iriToJsonLDObject(projectADM.id),
+ KnoraApiV2Complex.AttachedToProject -> JsonLDUtil.iriToJsonLDObject(projectADM.id.value),
KnoraApiV2Complex.HasPermissions -> JsonLDString(permissions),
KnoraApiV2Complex.UserHasPermission -> JsonLDString(userPermission.toString),
KnoraApiV2Complex.CreationDate -> JsonLDUtil.datatypeValueToJsonLDObject(
@@ -1193,7 +1193,7 @@ case class ResourceEventBody(
Map(
KnoraApiV2Complex.ResourceIri -> JsonLDString(resourceIri),
KnoraApiV2Complex.ResourceClassIri -> JsonLDString(resourceClassIri.toString),
- KnoraApiV2Complex.AttachedToProject -> JsonLDUtil.iriToJsonLDObject(projectADM.id),
+ KnoraApiV2Complex.AttachedToProject -> JsonLDUtil.iriToJsonLDObject(projectADM.id.value),
) ++ resourceLabel ++ creationDateAsJsonLD ++ propertiesAndValuesAsJsonLD ++ lastModificationDateAsJsonLD
++ deletionInfoAsJsonLD ++ permissionAsJsonLD,
)
diff --git a/webapi/src/main/scala/org/knora/webapi/responders/admin/PermissionsResponder.scala b/webapi/src/main/scala/org/knora/webapi/responders/admin/PermissionsResponder.scala
index e9b7e8adf4..c71bc1eafe 100644
--- a/webapi/src/main/scala/org/knora/webapi/responders/admin/PermissionsResponder.scala
+++ b/webapi/src/main/scala/org/knora/webapi/responders/admin/PermissionsResponder.scala
@@ -75,11 +75,11 @@ final case class PermissionsResponder(
case Property
}
- def getPermissionsApByProjectIri(projectIRI: IRI): Task[AdministrativePermissionsForProjectGetResponseADM] =
+ def getPermissionsApByProjectIri(projectIri: ProjectIri): Task[AdministrativePermissionsForProjectGetResponseADM] =
for {
permissionsQueryResponseRows <-
triplestore
- .query(Select(sparql.admin.txt.getAdministrativePermissionsForProject(projectIRI)))
+ .query(Select(sparql.admin.txt.getAdministrativePermissionsForProject(projectIri.value)))
.map(_.results.bindings)
permissionsWithProperties =
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..325dc8e3e7 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
@@ -436,7 +436,7 @@ final case class OntologyResponderV2(
// If this is a shared ontology, make sure it's in the default shared ontologies project.
_ <-
ZIO.when(
- createOntologyRequest.isShared && createOntologyRequest.projectIri.toString != OntologyConstants.KnoraAdmin.DefaultSharedOntologiesProject,
+ createOntologyRequest.isShared && createOntologyRequest.projectIri.toString != OntologyConstants.KnoraAdmin.DefaultSharedOntologiesProject.value,
) {
val msg =
s"Shared ontologies must be created in project <${OntologyConstants.KnoraAdmin.DefaultSharedOntologiesProject}>"
@@ -446,7 +446,7 @@ final case class OntologyResponderV2(
// If it's in the default shared ontologies project, make sure it's a shared ontology.
_ <-
ZIO.when(
- createOntologyRequest.projectIri.toString == OntologyConstants.KnoraAdmin.DefaultSharedOntologiesProject && !createOntologyRequest.isShared,
+ createOntologyRequest.projectIri.toString == OntologyConstants.KnoraAdmin.DefaultSharedOntologiesProject.value && !createOntologyRequest.isShared,
) {
val msg =
s"Ontologies created in project <${OntologyConstants.KnoraAdmin.DefaultSharedOntologiesProject}> must be shared"
diff --git a/webapi/src/main/scala/org/knora/webapi/responders/v2/ResourceUtilV2.scala b/webapi/src/main/scala/org/knora/webapi/responders/v2/ResourceUtilV2.scala
index 6f5053fc20..9e439d5149 100644
--- a/webapi/src/main/scala/org/knora/webapi/responders/v2/ResourceUtilV2.scala
+++ b/webapi/src/main/scala/org/knora/webapi/responders/v2/ResourceUtilV2.scala
@@ -122,7 +122,7 @@ final case class ResourceUtilV2Live(triplestore: TriplestoreService, sipiService
): IO[ForbiddenException, Unit] = {
val maybeUserPermission: Option[Permission.ObjectAccess] = PermissionUtilADM.getUserPermissionADM(
entityCreator = resourceInfo.attachedToUser,
- entityProject = resourceInfo.projectADM.id,
+ entityProject = resourceInfo.projectADM.id.value,
entityPermissionLiteral = resourceInfo.permissions,
requestingUser = requestingUser,
)
@@ -155,7 +155,7 @@ final case class ResourceUtilV2Live(triplestore: TriplestoreService, sipiService
): IO[ForbiddenException, Unit] = {
val maybeUserPermission: Option[Permission.ObjectAccess] = PermissionUtilADM.getUserPermissionADM(
entityCreator = valueInfo.attachedToUser,
- entityProject = resourceInfo.projectADM.id,
+ entityProject = resourceInfo.projectADM.id.value,
entityPermissionLiteral = valueInfo.permissions,
requestingUser = requestingUser,
)
diff --git a/webapi/src/main/scala/org/knora/webapi/responders/v2/ResourcesResponderV2.scala b/webapi/src/main/scala/org/knora/webapi/responders/v2/ResourcesResponderV2.scala
index e3ae11382c..e46ae77cfd 100644
--- a/webapi/src/main/scala/org/knora/webapi/responders/v2/ResourcesResponderV2.scala
+++ b/webapi/src/main/scala/org/knora/webapi/responders/v2/ResourcesResponderV2.scala
@@ -455,7 +455,7 @@ final case class ResourcesResponderV2(
// Ensure that the requesting user is a system admin, or an admin of this project.
_ <- ZIO.when(
- !(eraseResourceV2.requestingUser.permissions.isProjectAdmin(resource.projectADM.id) ||
+ !(eraseResourceV2.requestingUser.permissions.isProjectAdmin(resource.projectADM.id.value) ||
eraseResourceV2.requestingUser.permissions.isSystemAdmin),
) {
ZIO.fail(ForbiddenException(s"Only a system admin or project admin can erase a resource"))
diff --git a/webapi/src/main/scala/org/knora/webapi/responders/v2/ValuesResponderV2.scala b/webapi/src/main/scala/org/knora/webapi/responders/v2/ValuesResponderV2.scala
index e2895a263b..833e4b4eef 100644
--- a/webapi/src/main/scala/org/knora/webapi/responders/v2/ValuesResponderV2.scala
+++ b/webapi/src/main/scala/org/knora/webapi/responders/v2/ValuesResponderV2.scala
@@ -241,7 +241,7 @@ final case class ValuesResponderV2(
// Get the default permissions for the new value.
defaultValuePermissions <- permissionsResponder.newValueDefaultObjectAccessPermissions(
- resourceInfo.projectADM.projectIri,
+ resourceInfo.projectADM.id,
resourceInfo.resourceClassIri,
submittedInternalPropertyIri,
requestingUser,
@@ -262,7 +262,7 @@ final case class ValuesResponderV2(
// No. Make sure they don't give themselves higher permissions than they would get from the default permissions.
val permissionComparisonResult: PermissionComparisonResult =
PermissionUtilADM.comparePermissionsADM(
- entityProject = resourceInfo.projectADM.id,
+ entityProject = resourceInfo.projectADM.id.value,
permissionLiteralA = validatedCustomPermissions,
permissionLiteralB = defaultValuePermissions.permissionLiteral,
requestingUser = requestingUser,
diff --git a/webapi/src/main/scala/org/knora/webapi/responders/v2/ontology/OntologyTriplestoreHelpers.scala b/webapi/src/main/scala/org/knora/webapi/responders/v2/ontology/OntologyTriplestoreHelpers.scala
index 5661b16475..d6d3f383f3 100644
--- a/webapi/src/main/scala/org/knora/webapi/responders/v2/ontology/OntologyTriplestoreHelpers.scala
+++ b/webapi/src/main/scala/org/knora/webapi/responders/v2/ontology/OntologyTriplestoreHelpers.scala
@@ -152,7 +152,7 @@ final case class OntologyTriplestoreHelpersLive(
}
if (
- internalOntologyIri.isKnoraSharedDefinitionIri && projectIri.toString != OntologyConstants.KnoraAdmin.DefaultSharedOntologiesProject
+ internalOntologyIri.isKnoraSharedDefinitionIri && projectIri != OntologyConstants.KnoraAdmin.DefaultSharedOntologiesProject
) {
throw InconsistentRepositoryDataException(
s"Shared ontology $internalOntologyIri must be in project ${OntologyConstants.KnoraAdmin.DefaultSharedOntologiesProject}",
diff --git a/webapi/src/main/scala/org/knora/webapi/responders/v2/resources/CreateResourceV2Handler.scala b/webapi/src/main/scala/org/knora/webapi/responders/v2/resources/CreateResourceV2Handler.scala
index 66f509f084..e2a64a6c20 100644
--- a/webapi/src/main/scala/org/knora/webapi/responders/v2/resources/CreateResourceV2Handler.scala
+++ b/webapi/src/main/scala/org/knora/webapi/responders/v2/resources/CreateResourceV2Handler.scala
@@ -96,7 +96,7 @@ final case class CreateResourceV2Handler(
for {
_ <- ensureNotAnonymousUser(createResourceRequestV2.requestingUser)
_ <- ensureClassBelongsToProjectOntology(createResourceRequestV2)
- projectIri = createResourceRequestV2.createResource.projectADM.id
+ projectIri = createResourceRequestV2.createResource.projectADM.id.value
_ <- ensureUserHasPermission(createResourceRequestV2, projectIri)
resourceIri <-
@@ -119,10 +119,10 @@ final case class CreateResourceV2Handler(
private def ensureClassBelongsToProjectOntology(createResourceRequestV2: CreateResourceRequestV2): Task[Unit] = for {
projectIri <- ZIO.succeed(createResourceRequestV2.createResource.projectADM.id)
isSystemOrSharedProject =
- projectIri == KnoraProjectRepo.builtIn.SystemProject.id.value ||
+ projectIri == KnoraProjectRepo.builtIn.SystemProject.id ||
projectIri == OntologyConstants.KnoraAdmin.DefaultSharedOntologiesProject
_ <- ZIO.when(isSystemOrSharedProject)(
- ZIO.fail(BadRequestException(s"Resources cannot be created in project <$projectIri>")),
+ ZIO.fail(BadRequestException(s"Resources cannot be created in project <${projectIri.value}>")),
)
resourceClassOntologyIri =
@@ -136,11 +136,11 @@ final case class CreateResourceV2Handler(
ZIO
.fail(
BadRequestException(
- s"Cannot create a resource in project <$projectIri> with resource class <${createResourceRequestV2.createResource.resourceClassIri}>, which is defined in a non-shared ontology in another project",
+ s"Cannot create a resource in project <${projectIri.value}> with resource class <${createResourceRequestV2.createResource.resourceClassIri}>, which is defined in a non-shared ontology in another project",
),
)
.unless(
- projectIri == resourceClassProjectIri || OntologyServiceLive.isBuiltInOrSharedOntology(
+ projectIri.value == resourceClassProjectIri || OntologyServiceLive.isBuiltInOrSharedOntology(
resourceClassOntologyIri,
),
)
@@ -221,14 +221,14 @@ final case class CreateResourceV2Handler(
// Get the default permissions of the resource class.
defaultResourcePermissions <- permissionsResponder.newResourceDefaultObjectAccessPermissions(
- createResourceRequestV2.createResource.projectADM.projectIri,
+ createResourceRequestV2.createResource.projectADM.id,
internalCreateResource.resourceClassIri,
createResourceRequestV2.requestingUser,
)
// Get the default permissions of each property used.
defaultPropertyPermissionsMap <- permissionsResponder.newValueDefaultObjectAccessPermissions(
- createResourceRequestV2.createResource.projectADM.projectIri,
+ createResourceRequestV2.createResource.projectADM.id,
internalCreateResource.resourceClassIri,
internalCreateResource.values.keySet,
createResourceRequestV2.requestingUser,
@@ -254,7 +254,7 @@ final case class CreateResourceV2Handler(
_ <- resourcesRepo.createNewResource(
dataGraphIri = dataNamedGraph,
resource = resourceReadyToCreate,
- projectIri = InternalIri(createResourceRequestV2.createResource.projectADM.id),
+ projectIri = InternalIri(createResourceRequestV2.createResource.projectADM.id.value),
userIri = InternalIri(createResourceRequestV2.requestingUser.id),
)
@@ -382,13 +382,13 @@ final case class CreateResourceV2Handler(
validatedCustomPermissions <- permissionUtilADM.validatePermissions(permissionStr)
_ <- ZIO.when {
- !(requestingUser.permissions.isProjectAdmin(internalCreateResource.projectADM.id) &&
+ !(requestingUser.permissions.isProjectAdmin(internalCreateResource.projectADM.id.value) &&
!requestingUser.permissions.isSystemAdmin)
} {
// Make sure they don't give themselves higher permissions than they would get from the default permissions.
val permissionComparisonResult: PermissionComparisonResult =
PermissionUtilADM.comparePermissionsADM(
- internalCreateResource.projectADM.id,
+ internalCreateResource.projectADM.id.value,
validatedCustomPermissions,
defaultResourcePermissions,
requestingUser,
@@ -844,14 +844,14 @@ final case class CreateResourceV2Handler(
// Is the requesting user a system admin, or an admin of this project?
_ <- ZIO.when(
!(requestingUser.permissions
- .isProjectAdmin(project.id) || requestingUser.permissions.isSystemAdmin),
+ .isProjectAdmin(project.id.value) || requestingUser.permissions.isSystemAdmin),
) {
// No. Make sure they don't give themselves higher permissions than they would get from the default permissions.
val permissionComparisonResult: PermissionComparisonResult =
PermissionUtilADM.comparePermissionsADM(
- entityProject = project.id,
+ entityProject = project.id.value,
permissionLiteralA = validatedCustomPermissions,
permissionLiteralB = defaultPropertyPermissions(propertyIri),
requestingUser = requestingUser,
diff --git a/webapi/src/main/scala/org/knora/webapi/slice/admin/api/Examples.scala b/webapi/src/main/scala/org/knora/webapi/slice/admin/api/Examples.scala
index 50ba4de1e7..2d3895e0d9 100644
--- a/webapi/src/main/scala/org/knora/webapi/slice/admin/api/Examples.scala
+++ b/webapi/src/main/scala/org/knora/webapi/slice/admin/api/Examples.scala
@@ -90,7 +90,7 @@ object Examples {
)
private val project: Project = Project(
- id = ProjectExample.projectIri.value,
+ id = ProjectExample.projectIri,
shortname = Shortname.unsafeFrom("example"),
shortcode = Shortcode.unsafeFrom("0001"),
longname = Some(Longname.unsafeFrom("Example Project")),
diff --git a/webapi/src/main/scala/org/knora/webapi/slice/admin/api/model/ProjectsMessagesADM.scala b/webapi/src/main/scala/org/knora/webapi/slice/admin/api/model/ProjectsMessagesADM.scala
index feb3f52908..65692df527 100644
--- a/webapi/src/main/scala/org/knora/webapi/slice/admin/api/model/ProjectsMessagesADM.scala
+++ b/webapi/src/main/scala/org/knora/webapi/slice/admin/api/model/ProjectsMessagesADM.scala
@@ -31,7 +31,7 @@ import org.knora.webapi.slice.admin.domain.model.User
* @param selfjoin The project's self-join status.
*/
case class Project(
- id: IRI,
+ id: ProjectIri,
shortname: Shortname,
shortcode: Shortcode,
longname: Option[Longname],
@@ -45,12 +45,10 @@ case class Project(
license: Option[License],
) extends Ordered[Project] {
- def projectIri: ProjectIri = ProjectIri.unsafeFrom(id)
-
/**
* Allows to sort collections of ProjectADM. Sorting is done by the id.
*/
- def compare(that: Project): Int = this.id.compareTo(that.id)
+ def compare(that: Project): Int = this.id.value.compareTo(that.id.value)
}
object Project {
implicit val projectCodec: JsonCodec[Project] = DeriveJsonCodec.gen[Project]
diff --git a/webapi/src/main/scala/org/knora/webapi/slice/admin/api/service/PermissionRestService.scala b/webapi/src/main/scala/org/knora/webapi/slice/admin/api/service/PermissionRestService.scala
index c08c31cd16..5a253d9b73 100644
--- a/webapi/src/main/scala/org/knora/webapi/slice/admin/api/service/PermissionRestService.scala
+++ b/webapi/src/main/scala/org/knora/webapi/slice/admin/api/service/PermissionRestService.scala
@@ -70,12 +70,12 @@ final case class PermissionRestService(
.tap(auth.ensureSystemAdminOrProjectAdmin(user, _))
def getPermissionsApByProjectIri(
- value: ProjectIri,
+ projectIri: ProjectIri,
user: User,
): Task[AdministrativePermissionsForProjectGetResponseADM] =
for {
- _ <- ensureProjectIriExistsAndUserHasAccess(value, user)
- result <- responder.getPermissionsApByProjectIri(value.value)
+ _ <- ensureProjectIriExistsAndUserHasAccess(projectIri, user)
+ result <- responder.getPermissionsApByProjectIri(projectIri)
ext <- format.toExternal(result)
} yield ext
diff --git a/webapi/src/main/scala/org/knora/webapi/slice/admin/api/service/ProjectRestService.scala b/webapi/src/main/scala/org/knora/webapi/slice/admin/api/service/ProjectRestService.scala
index a95e882321..227143f2ab 100644
--- a/webapi/src/main/scala/org/knora/webapi/slice/admin/api/service/ProjectRestService.scala
+++ b/webapi/src/main/scala/org/knora/webapi/slice/admin/api/service/ProjectRestService.scala
@@ -62,7 +62,7 @@ final case class ProjectRestService(
*/
def listAllProjects(): Task[ProjectsGetResponse] = for {
internal <- projectService.findAllRegularProjects
- projects = internal.filter(_.projectIri.isRegularProjectIri)
+ projects = internal.filter(_.id.isRegularProjectIri)
external <- format.toExternal(ProjectsGetResponse(projects))
} yield external
@@ -107,7 +107,7 @@ final case class ProjectRestService(
},
)
internal <- projectService.createProject(createReq).map(ProjectOperationResponseADM.apply)
- _ <- permissionResponder.createPermissionsForAdminsAndMembersOfNewProject(internal.project.projectIri)
+ _ <- permissionResponder.createPermissionsForAdminsAndMembersOfNewProject(internal.project.id)
external <- format.toExternal(internal)
} yield external
diff --git a/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/service/GroupService.scala b/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/service/GroupService.scala
index 1266efa4b9..9b1103a512 100644
--- a/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/service/GroupService.scala
+++ b/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/service/GroupService.scala
@@ -51,7 +51,7 @@ final case class GroupService(
groupName = GroupName.unsafeFrom(group.name),
groupDescriptions = GroupDescriptions.unsafeFrom(group.descriptions),
status = GroupStatus.from(group.status),
- belongsToProject = group.project.map(it => ProjectIri.unsafeFrom(it.id)),
+ belongsToProject = group.project.map(_.id),
hasSelfJoinEnabled = GroupSelfJoin.from(group.selfjoin),
)
diff --git a/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/service/KnoraUserService.scala b/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/service/KnoraUserService.scala
index 2f4b7af7ba..e370cd54c3 100644
--- a/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/service/KnoraUserService.scala
+++ b/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/service/KnoraUserService.scala
@@ -161,8 +161,8 @@ case class KnoraUserService(
userRepo.save(user.copy(isInGroup = user.isInGroup.filterNot(_ == groupIri))).orDie
def addUserToProject(user: KnoraUser, project: Project): IO[IsProjectMember, KnoraUser] = for {
- _ <- ZIO.fail(IsProjectMember(user.id, project.projectIri)).when(user.isInProject.contains(project.projectIri))
- user <- addUserToProject(user, project.projectIri)
+ _ <- ZIO.fail(IsProjectMember(user.id, project.id)).when(user.isInProject.contains(project.id))
+ user <- addUserToProject(user, project.id)
} yield user
def addUserToProject(user: KnoraUser, project: KnoraProject): UIO[KnoraUser] = addUserToProject(user, project.id)
@@ -179,7 +179,7 @@ case class KnoraUserService(
* @return The updated user. If the user is not a member of the project, an error is returned.
*/
def removeUserFromProject(user: KnoraUser, project: Project): IO[NotProjectMember, KnoraUser] =
- removeUserFromProject(user, project.projectIri)
+ removeUserFromProject(user, project.id)
def removeUsersFromProject(users: Seq[KnoraUser], project: KnoraProject): UIO[Unit] =
ZIO.foreachDiscard(users)(removeUserFromProject(_, project.id).ignore)
@@ -203,14 +203,12 @@ case class KnoraUserService(
def addUserToProjectAsAdmin(
user: KnoraUser,
project: Project,
- ): IO[IsProjectAdminMember | NotProjectMember, KnoraUser] = {
- val projectIri = project.projectIri
+ ): IO[IsProjectAdminMember | NotProjectMember, KnoraUser] =
for {
- _ <- ZIO.fail(IsProjectAdminMember(user.id, projectIri)).when(user.isInProjectAdminGroup.contains(projectIri))
- _ <- ZIO.fail(NotProjectMember(user.id, projectIri)).unless(user.isInProject.contains(projectIri))
- _ <- addUserToProjectAsAdmin(user, projectIri)
+ _ <- ZIO.fail(IsProjectAdminMember(user.id, project.id)).when(user.isInProjectAdminGroup.contains(project.id))
+ _ <- ZIO.fail(NotProjectMember(user.id, project.id)).unless(user.isInProject.contains(project.id))
+ _ <- addUserToProjectAsAdmin(user, project.id)
} yield user
- }
def addUserToProjectAsAdmin(user: KnoraUser, project: KnoraProject): UIO[KnoraUser] =
addUserToProjectAsAdmin(user, project.id)
@@ -227,7 +225,7 @@ case class KnoraUserService(
* @return The updated user. If the user is not an admin member of the project, an error is returned.
*/
def removeUserFromProjectAsAdmin(user: KnoraUser, project: Project): IO[NotProjectAdminMember, KnoraUser] =
- removeUserFromProjectIriAsAdmin(user, project.projectIri)
+ removeUserFromProjectIriAsAdmin(user, project.id)
def removeUsersFromProjectAsAdmin(users: Seq[KnoraUser], project: KnoraProject): IO[NotProjectAdminMember, Unit] =
ZIO.foreachDiscard(users)(removeUserFromProjectIriAsAdmin(_, project.id))
diff --git a/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/service/ProjectService.scala b/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/service/ProjectService.scala
index 158a21a72a..46f18ea4b9 100644
--- a/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/service/ProjectService.scala
+++ b/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/service/ProjectService.scala
@@ -46,7 +46,7 @@ final case class ProjectService(
.map(_.map(_.ontologyMetadata.ontologyIri.toIri))
.map(ontologies =>
Project(
- knoraProject.id.value,
+ knoraProject.id,
knoraProject.shortname,
knoraProject.shortcode,
knoraProject.longname,
@@ -63,7 +63,7 @@ final case class ProjectService(
private def toKnoraProject(project: Project, restrictedView: RestrictedView): KnoraProject =
KnoraProject(
- id = ProjectIri.unsafeFrom(project.id),
+ id = project.id,
shortname = project.shortname,
shortcode = project.shortcode,
longname = project.longname,
diff --git a/webapi/src/main/scala/org/knora/webapi/slice/common/ApiComplexV2JsonLdRequestParser.scala b/webapi/src/main/scala/org/knora/webapi/slice/common/ApiComplexV2JsonLdRequestParser.scala
index 23f7593ece..d009a2b412 100644
--- a/webapi/src/main/scala/org/knora/webapi/slice/common/ApiComplexV2JsonLdRequestParser.scala
+++ b/webapi/src/main/scala/org/knora/webapi/slice/common/ApiComplexV2JsonLdRequestParser.scala
@@ -243,7 +243,7 @@ final case class ApiComplexV2JsonLdRequestParser(
_ <- ZIO
.fail("Resource IRI and project IRI must reference the same project")
.when(r.resourceIri.exists(_.shortcode != project.shortcode))
- attachedToUser <- attachedToUser(r.resource, requestingUser, project.projectIri)
+ attachedToUser <- attachedToUser(r.resource, requestingUser, project.id)
values <- extractValues(r.resource, project.shortcode, ingestState)
} yield CreateResourceRequestV2(
CreateResourceV2(
diff --git a/webapi/src/test/scala/org/knora/webapi/slice/admin/domain/service/ProjectServiceSpec.scala b/webapi/src/test/scala/org/knora/webapi/slice/admin/domain/service/ProjectServiceSpec.scala
index ef5f7d1b30..f7badf15e1 100644
--- a/webapi/src/test/scala/org/knora/webapi/slice/admin/domain/service/ProjectServiceSpec.scala
+++ b/webapi/src/test/scala/org/knora/webapi/slice/admin/domain/service/ProjectServiceSpec.scala
@@ -48,7 +48,7 @@ object ProjectServiceSpec extends ZIOSpecDefault {
val shortcode = "0002"
val shortname = "someOtherProject"
val p: KnoraProject = KnoraProject(
- id = ProjectIri.unsafeFrom(IriTestConstants.Project.TestProject),
+ id = IriTestConstants.Project.TestProject,
shortname = Shortname.unsafeFrom(shortname),
shortcode = Shortcode.unsafeFrom(shortcode),
longname = None,
diff --git a/webapi/src/test/scala/org/knora/webapi/slice/ontology/api/service/RestCardinalityServiceLiveSpec.scala b/webapi/src/test/scala/org/knora/webapi/slice/ontology/api/service/RestCardinalityServiceLiveSpec.scala
index f8cafb8dc1..16f2c919e0 100644
--- a/webapi/src/test/scala/org/knora/webapi/slice/ontology/api/service/RestCardinalityServiceLiveSpec.scala
+++ b/webapi/src/test/scala/org/knora/webapi/slice/ontology/api/service/RestCardinalityServiceLiveSpec.scala
@@ -36,10 +36,10 @@ object RestCardinalityServiceLiveSpec extends ZIOSpecDefault {
.addOntology(
ReadOntologyV2Builder
.builder(IriTestConstants.Biblio.Ontology)
- .assignToProject(IriTestConstants.Project.TestProject),
+ .assignToProject(IriTestConstants.Project.TestProject.value),
)
.build
- private val projectIri: IRI = IriTestConstants.Project.TestProject
+ private val projectIri: IRI = IriTestConstants.Project.TestProject.value
private val classIri: IRI = IriTestConstants.Biblio.Class.Article.value
private val propertyIri: IRI = IriTestConstants.Biblio.Property.hasTitle.value
private val userWithAccess: User =
diff --git a/webapi/src/test/scala/org/knora/webapi/slice/resourceinfo/domain/IriTestConstants.scala b/webapi/src/test/scala/org/knora/webapi/slice/resourceinfo/domain/IriTestConstants.scala
index 26feb8a413..38e9d9e5e7 100644
--- a/webapi/src/test/scala/org/knora/webapi/slice/resourceinfo/domain/IriTestConstants.scala
+++ b/webapi/src/test/scala/org/knora/webapi/slice/resourceinfo/domain/IriTestConstants.scala
@@ -5,10 +5,11 @@
package org.knora.webapi.slice.resourceinfo.domain
import org.knora.webapi.IRI
+import org.knora.webapi.slice.admin.domain.model.KnoraProject.ProjectIri
object IriTestConstants {
object Project {
- val TestProject: IRI = "http://rdfh.ch/projects/0000"
+ val TestProject: ProjectIri = ProjectIri.unsafeFrom("http://rdfh.ch/projects/0000")
}
private def makeEntity(ontologyIri: InternalIri, entityName: String) =
InternalIri(s"${ontologyIri.value}#$entityName")
From 804e35a22f91d7754b9cff564efc4730a14aee23 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20Kleinb=C3=B6lting?=
Date: Fri, 15 Nov 2024 19:35:26 +0100
Subject: [PATCH 17/18] refactor: Make Project.keywords typed
---
.../webapi/e2e/admin/ProjectsADME2ESpec.scala | 2 +-
.../IntegrationTestAdminJsonProtocol.scala | 5 ++++
.../admin/ProjectRestServiceSpec.scala | 2 +-
.../sharedtestdata/SharedTestDataADM.scala | 25 ++++++++++---------
.../webapi/slice/admin/api/Examples.scala | 3 ++-
.../admin/api/model/ProjectsMessagesADM.scala | 2 +-
.../admin/domain/service/ProjectService.scala | 4 +--
7 files changed, 25 insertions(+), 18 deletions(-)
diff --git a/integration/src/test/scala/org/knora/webapi/e2e/admin/ProjectsADME2ESpec.scala b/integration/src/test/scala/org/knora/webapi/e2e/admin/ProjectsADME2ESpec.scala
index 7c87fee891..e3794abe63 100644
--- a/integration/src/test/scala/org/knora/webapi/e2e/admin/ProjectsADME2ESpec.scala
+++ b/integration/src/test/scala/org/knora/webapi/e2e/admin/ProjectsADME2ESpec.scala
@@ -362,7 +362,7 @@ class ProjectsADME2ESpec extends E2ESpec with SprayJsonSupport {
result.description should be(
Seq(StringLiteralV2.from(value = "updated project description", language = Some("en"))),
)
- result.keywords.sorted should be(Seq("updated", "keywords").sorted)
+ result.keywords.map(_.value).sorted should be(Seq("updated", "keywords").sorted)
result.logo should be(Some("/fu/bar/baz-updated.jpg"))
result.status should be(Status.Active)
result.selfjoin should be(SelfJoin.CanJoin)
diff --git a/integration/src/test/scala/org/knora/webapi/messages/admin/responder/IntegrationTestAdminJsonProtocol.scala b/integration/src/test/scala/org/knora/webapi/messages/admin/responder/IntegrationTestAdminJsonProtocol.scala
index 9d2d1385a8..da2ff2d18a 100644
--- a/integration/src/test/scala/org/knora/webapi/messages/admin/responder/IntegrationTestAdminJsonProtocol.scala
+++ b/integration/src/test/scala/org/knora/webapi/messages/admin/responder/IntegrationTestAdminJsonProtocol.scala
@@ -46,6 +46,7 @@ import org.knora.webapi.slice.admin.api.model.ProjectMembersGetResponseADM
import org.knora.webapi.slice.admin.api.model.ProjectOperationResponseADM
import org.knora.webapi.slice.admin.domain.model.Group
import org.knora.webapi.slice.admin.domain.model.KnoraProject.CopyrightAttribution
+import org.knora.webapi.slice.admin.domain.model.KnoraProject.Keyword
import org.knora.webapi.slice.admin.domain.model.KnoraProject.License
import org.knora.webapi.slice.admin.domain.model.KnoraProject.Logo
import org.knora.webapi.slice.admin.domain.model.KnoraProject.Longname
@@ -241,6 +242,10 @@ object IntegrationTestAdminJsonProtocol extends TriplestoreJsonProtocol {
override val from: String => Either[String, Logo] = Logo.from
}
+ implicit object KeywordFormat extends StringValueFormat[Keyword] {
+ override val from: String => Either[String, Keyword] = Keyword.from
+ }
+
trait BooleanValueFormat[T <: BooleanValue] extends JsonFormat[T] { self =>
def from: Boolean => T
override def write(v: T): JsValue = JsString(v.value.toString)
diff --git a/integration/src/test/scala/org/knora/webapi/responders/admin/ProjectRestServiceSpec.scala b/integration/src/test/scala/org/knora/webapi/responders/admin/ProjectRestServiceSpec.scala
index 38b3268a04..a8c9a827f0 100644
--- a/integration/src/test/scala/org/knora/webapi/responders/admin/ProjectRestServiceSpec.scala
+++ b/integration/src/test/scala/org/knora/webapi/responders/admin/ProjectRestServiceSpec.scala
@@ -407,7 +407,7 @@ class ProjectRestServiceSpec extends CoreSpec with ImplicitSender {
),
),
)
- received.project.keywords.sorted should be(Seq("updated", "keywords").sorted)
+ received.project.keywords.map(_.value).sorted should be(List("updated", "keywords").sorted)
received.project.logo should be(Some("/fu/bar/baz-updated.jpg"))
received.project.status should be(Status.Active)
received.project.selfjoin should be(SelfJoin.CanJoin)
diff --git a/integration/src/test/scala/org/knora/webapi/sharedtestdata/SharedTestDataADM.scala b/integration/src/test/scala/org/knora/webapi/sharedtestdata/SharedTestDataADM.scala
index 797c38886d..aef55eb351 100644
--- a/integration/src/test/scala/org/knora/webapi/sharedtestdata/SharedTestDataADM.scala
+++ b/integration/src/test/scala/org/knora/webapi/sharedtestdata/SharedTestDataADM.scala
@@ -16,6 +16,7 @@ import org.knora.webapi.messages.store.triplestoremessages.StringLiteralV2
import org.knora.webapi.messages.util.KnoraSystemInstances
import org.knora.webapi.slice.admin.api.model.Project
import org.knora.webapi.slice.admin.domain.model.Group
+import org.knora.webapi.slice.admin.domain.model.KnoraProject.Keyword
import org.knora.webapi.slice.admin.domain.model.KnoraProject.Logo
import org.knora.webapi.slice.admin.domain.model.KnoraProject.Longname
import org.knora.webapi.slice.admin.domain.model.KnoraProject.ProjectIri
@@ -166,7 +167,7 @@ object SharedTestDataADM {
shortcode = Shortcode.unsafeFrom("FFFF"),
longname = Some(Longname.unsafeFrom("Knora System Project")),
description = Seq(StringLiteralV2.from(value = "Knora System Project", language = Some("en"))),
- keywords = Seq.empty[String],
+ keywords = List.empty,
logo = None,
ontologies = Seq(
OntologyConstants.KnoraBase.KnoraBaseOntologyIri,
@@ -187,7 +188,7 @@ object SharedTestDataADM {
shortcode = Shortcode.unsafeFrom("0000"),
longname = Some(Longname.unsafeFrom("Default Knora Shared Ontologies Project")),
description = Seq(StringLiteralV2.from(value = "Default Knora Shared Ontologies Project", language = Some("en"))),
- keywords = Seq.empty[String],
+ keywords = List.empty,
logo = None,
ontologies = Seq.empty[IRI],
status = Status.Active,
@@ -301,7 +302,7 @@ object SharedTestDataADM {
shortcode = Shortcode.unsafeFrom("00FF"),
longname = Some(Longname.unsafeFrom("Image Collection Demo")),
description = Seq(StringLiteralV2.from(value = "A demo project of a collection of images", language = Some("en"))),
- keywords = Seq("images", "collection").sorted,
+ keywords = List("images", "collection").map(Keyword.unsafeFrom),
logo = None,
ontologies = Seq(SharedOntologyTestDataADM.IMAGES_ONTOLOGY_IRI),
status = Status.Active,
@@ -317,7 +318,7 @@ object SharedTestDataADM {
shortcode = Shortcode.unsafeFrom("00FF"),
longname = Some(Longname.unsafeFrom("Image Collection Demo")),
description = Seq(StringLiteralV2.from(value = "A demo project of a collection of images", language = Some("en"))),
- keywords = Seq("images", "collection").sorted,
+ keywords = List("images", "collection").map(Keyword.unsafeFrom),
logo = None,
ontologies = Seq(SharedOntologyTestDataADM.IMAGES_ONTOLOGY_IRI_LocalHost),
status = Status.Active,
@@ -467,7 +468,7 @@ object SharedTestDataADM {
language = None,
),
),
- keywords = Seq(
+ keywords = List(
"Basler Frühdrucke",
"Inkunabel",
"Narrenschiff",
@@ -482,7 +483,7 @@ object SharedTestDataADM {
"Letterpress Printing",
"Basel",
"Contectualisation of images",
- ).sorted,
+ ).map(Keyword.unsafeFrom),
logo = Some(Logo.unsafeFrom("incunabula_logo.png")),
ontologies = Seq(SharedOntologyTestDataADM.INCUNABULA_ONTOLOGY_IRI),
status = Status.Active,
@@ -504,7 +505,7 @@ object SharedTestDataADM {
language = None,
),
),
- keywords = Seq(
+ keywords = List(
"Basler Frühdrucke",
"Inkunabel",
"Narrenschiff",
@@ -519,7 +520,7 @@ object SharedTestDataADM {
"Letterpress Printing",
"Basel",
"Contectualisation of images",
- ).sorted,
+ ).map(Keyword.unsafeFrom),
logo = Some(Logo.unsafeFrom("incunabula_logo.png")),
ontologies = Seq(SharedOntologyTestDataADM.INCUNABULA_ONTOLOGY_IRI_LocalHost),
status = Status.Active,
@@ -633,7 +634,7 @@ object SharedTestDataADM {
shortcode = Shortcode.unsafeFrom("0001"),
longname = Some(Longname.unsafeFrom("Anything Project")),
description = Seq(StringLiteralV2.from(value = "Anything Project", language = None)),
- keywords = Seq("things", "arbitrary test data").sorted,
+ keywords = List("things", "arbitrary test data").map(Keyword.unsafeFrom),
logo = None,
ontologies = Seq(SharedOntologyTestDataADM.ANYTHING_ONTOLOGY_IRI, SharedOntologyTestDataADM.SomethingOntologyIri),
status = Status.Active,
@@ -648,7 +649,7 @@ object SharedTestDataADM {
shortcode = Shortcode.unsafeFrom("0001"),
longname = Some(Longname.unsafeFrom("Anything Project")),
description = Seq(StringLiteralV2.from(value = "Anything Project", language = None)),
- keywords = Seq("things", "arbitrary test data").sorted,
+ keywords = List("things", "arbitrary test data").map(Keyword.unsafeFrom),
logo = None,
ontologies = Seq(
SharedOntologyTestDataADM.ANYTHING_ONTOLOGY_IRI_LocalHost,
@@ -685,7 +686,7 @@ object SharedTestDataADM {
shortcode = Shortcode.unsafeFrom("0801"),
longname = Some(Longname.unsafeFrom("Bernoulli-Euler Online")),
description = Seq(StringLiteralV2.from(value = "Bernoulli-Euler Online", language = None)),
- keywords = Seq.empty[String],
+ keywords = List.empty,
logo = None,
ontologies = Seq(
"http://www.knora.org/ontology/0801/beol",
@@ -741,7 +742,7 @@ object SharedTestDataADM {
shortcode = Shortcode.unsafeFrom("0804"),
longname = Some(Longname.unsafeFrom("Dokubib")),
description = Seq(StringLiteralV2.from(value = "Dokubib", language = None)),
- keywords = Seq.empty[String],
+ keywords = List.empty,
logo = None,
ontologies = Seq("http://www.knora.org/ontology/0804/dokubib"),
status = Status.Inactive,
diff --git a/webapi/src/main/scala/org/knora/webapi/slice/admin/api/Examples.scala b/webapi/src/main/scala/org/knora/webapi/slice/admin/api/Examples.scala
index 2d3895e0d9..0abc38efac 100644
--- a/webapi/src/main/scala/org/knora/webapi/slice/admin/api/Examples.scala
+++ b/webapi/src/main/scala/org/knora/webapi/slice/admin/api/Examples.scala
@@ -24,6 +24,7 @@ import org.knora.webapi.slice.admin.domain.model.GroupName
import org.knora.webapi.slice.admin.domain.model.GroupSelfJoin
import org.knora.webapi.slice.admin.domain.model.GroupStatus
import org.knora.webapi.slice.admin.domain.model.KnoraProject.CopyrightAttribution
+import org.knora.webapi.slice.admin.domain.model.KnoraProject.Keyword
import org.knora.webapi.slice.admin.domain.model.KnoraProject.License
import org.knora.webapi.slice.admin.domain.model.KnoraProject.Longname
import org.knora.webapi.slice.admin.domain.model.KnoraProject.ProjectIri
@@ -95,7 +96,7 @@ object Examples {
shortcode = Shortcode.unsafeFrom("0001"),
longname = Some(Longname.unsafeFrom("Example Project")),
description = Seq(StringLiteralV2.from("An example project", Some("en"))),
- keywords = Seq("example", "project"),
+ keywords = List("example", "project").map(Keyword.unsafeFrom),
logo = None,
status = Active,
ontologies = Seq.empty,
diff --git a/webapi/src/main/scala/org/knora/webapi/slice/admin/api/model/ProjectsMessagesADM.scala b/webapi/src/main/scala/org/knora/webapi/slice/admin/api/model/ProjectsMessagesADM.scala
index 65692df527..ba5dc64f96 100644
--- a/webapi/src/main/scala/org/knora/webapi/slice/admin/api/model/ProjectsMessagesADM.scala
+++ b/webapi/src/main/scala/org/knora/webapi/slice/admin/api/model/ProjectsMessagesADM.scala
@@ -36,7 +36,7 @@ case class Project(
shortcode: Shortcode,
longname: Option[Longname],
description: Seq[StringLiteralV2],
- keywords: Seq[String],
+ keywords: List[Keyword],
logo: Option[Logo],
ontologies: Seq[IRI],
status: Status,
diff --git a/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/service/ProjectService.scala b/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/service/ProjectService.scala
index 46f18ea4b9..84922ee815 100644
--- a/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/service/ProjectService.scala
+++ b/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/service/ProjectService.scala
@@ -51,7 +51,7 @@ final case class ProjectService(
knoraProject.shortcode,
knoraProject.longname,
knoraProject.description.map(_.value),
- knoraProject.keywords.map(_.value),
+ knoraProject.keywords,
knoraProject.logo,
ontologies,
knoraProject.status,
@@ -70,7 +70,7 @@ final case class ProjectService(
description = NonEmptyChunk
.fromIterable(project.description.head, project.description.tail)
.map(Description.unsafeFrom),
- keywords = project.keywords.map(Keyword.unsafeFrom).toList,
+ keywords = project.keywords,
logo = project.logo,
status = project.status,
selfjoin = project.selfjoin,
From 02f828c5b5248c0860e44a937c96cad58bff4f1c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20Kleinb=C3=B6lting?=
Date: Fri, 15 Nov 2024 19:48:54 +0100
Subject: [PATCH 18/18] refactor: Make Project.description typed
---
.../IntegrationTestAdminJsonProtocol.scala | 9 ++++++
.../webapi/sharedtestdata/ProjectInfo.scala | 2 +-
.../sharedtestdata/SharedTestDataADM.scala | 30 +++++++++++--------
.../webapi/slice/admin/api/Examples.scala | 3 +-
.../admin/api/model/ProjectsMessagesADM.scala | 3 +-
.../admin/domain/service/ProjectService.scala | 6 ++--
.../domain/service/ProjectServiceSpec.scala | 2 +-
7 files changed, 34 insertions(+), 21 deletions(-)
diff --git a/integration/src/test/scala/org/knora/webapi/messages/admin/responder/IntegrationTestAdminJsonProtocol.scala b/integration/src/test/scala/org/knora/webapi/messages/admin/responder/IntegrationTestAdminJsonProtocol.scala
index da2ff2d18a..b98d07e61e 100644
--- a/integration/src/test/scala/org/knora/webapi/messages/admin/responder/IntegrationTestAdminJsonProtocol.scala
+++ b/integration/src/test/scala/org/knora/webapi/messages/admin/responder/IntegrationTestAdminJsonProtocol.scala
@@ -39,6 +39,7 @@ import org.knora.webapi.messages.admin.responder.usersmessages.UserProjectAdminM
import org.knora.webapi.messages.admin.responder.usersmessages.UserProjectMembershipsGetResponseADM
import org.knora.webapi.messages.admin.responder.usersmessages.UserResponseADM
import org.knora.webapi.messages.admin.responder.usersmessages.UsersGetResponseADM
+import org.knora.webapi.messages.store.triplestoremessages.StringLiteralV2
import org.knora.webapi.messages.store.triplestoremessages.TriplestoreJsonProtocol
import org.knora.webapi.slice.admin.api.model.Project
import org.knora.webapi.slice.admin.api.model.ProjectAdminMembersGetResponseADM
@@ -46,6 +47,7 @@ import org.knora.webapi.slice.admin.api.model.ProjectMembersGetResponseADM
import org.knora.webapi.slice.admin.api.model.ProjectOperationResponseADM
import org.knora.webapi.slice.admin.domain.model.Group
import org.knora.webapi.slice.admin.domain.model.KnoraProject.CopyrightAttribution
+import org.knora.webapi.slice.admin.domain.model.KnoraProject.Description
import org.knora.webapi.slice.admin.domain.model.KnoraProject.Keyword
import org.knora.webapi.slice.admin.domain.model.KnoraProject.License
import org.knora.webapi.slice.admin.domain.model.KnoraProject.Logo
@@ -206,6 +208,13 @@ object IntegrationTestAdminJsonProtocol extends TriplestoreJsonProtocol {
),
)
+ implicit object DescriptionFormat extends JsonFormat[Description] with TriplestoreJsonProtocol {
+ val lit = implicitly[JsonFormat[StringLiteralV2]]
+ override def write(obj: Description): JsValue = lit.write(obj.value)
+ override def read(json: JsValue): Description = Description
+ .from(lit.read(json))
+ .fold(err => throw DeserializationException(err), identity)
+ }
trait StringValueFormat[T <: StringValue] extends JsonFormat[T] { self =>
def from: String => Either[String, T]
override def write(v: T): JsValue = JsString(v.value)
diff --git a/integration/src/test/scala/org/knora/webapi/sharedtestdata/ProjectInfo.scala b/integration/src/test/scala/org/knora/webapi/sharedtestdata/ProjectInfo.scala
index 466f842d84..bc3b5ba924 100644
--- a/integration/src/test/scala/org/knora/webapi/sharedtestdata/ProjectInfo.scala
+++ b/integration/src/test/scala/org/knora/webapi/sharedtestdata/ProjectInfo.scala
@@ -41,7 +41,7 @@ object ProjectInfo {
shortname = project.shortname.value,
shortcode = project.shortcode.value,
longname = project.longname.map(_.value),
- description = project.description.headOption.map(_.value),
+ description = project.description.map(_.value).headOption.map(_.value),
keywords = project.keywords.headOption.map(_ => project.keywords.mkString(", ")),
logo = project.logo.map(_.value),
ontologies = project.ontologies,
diff --git a/integration/src/test/scala/org/knora/webapi/sharedtestdata/SharedTestDataADM.scala b/integration/src/test/scala/org/knora/webapi/sharedtestdata/SharedTestDataADM.scala
index aef55eb351..ef5cee5ee3 100644
--- a/integration/src/test/scala/org/knora/webapi/sharedtestdata/SharedTestDataADM.scala
+++ b/integration/src/test/scala/org/knora/webapi/sharedtestdata/SharedTestDataADM.scala
@@ -16,6 +16,7 @@ import org.knora.webapi.messages.store.triplestoremessages.StringLiteralV2
import org.knora.webapi.messages.util.KnoraSystemInstances
import org.knora.webapi.slice.admin.api.model.Project
import org.knora.webapi.slice.admin.domain.model.Group
+import org.knora.webapi.slice.admin.domain.model.KnoraProject.Description
import org.knora.webapi.slice.admin.domain.model.KnoraProject.Keyword
import org.knora.webapi.slice.admin.domain.model.KnoraProject.Logo
import org.knora.webapi.slice.admin.domain.model.KnoraProject.Longname
@@ -166,7 +167,8 @@ object SharedTestDataADM {
shortname = Shortname.unsafeFrom("SystemProject"),
shortcode = Shortcode.unsafeFrom("FFFF"),
longname = Some(Longname.unsafeFrom("Knora System Project")),
- description = Seq(StringLiteralV2.from(value = "Knora System Project", language = Some("en"))),
+ description =
+ List(StringLiteralV2.from(value = "Knora System Project", language = Some("en"))).map(Description.unsafeFrom),
keywords = List.empty,
logo = None,
ontologies = Seq(
@@ -187,7 +189,8 @@ object SharedTestDataADM {
shortname = Shortname.unsafeFrom("DefaultSharedOntologiesProject"),
shortcode = Shortcode.unsafeFrom("0000"),
longname = Some(Longname.unsafeFrom("Default Knora Shared Ontologies Project")),
- description = Seq(StringLiteralV2.from(value = "Default Knora Shared Ontologies Project", language = Some("en"))),
+ description = List(StringLiteralV2.from(value = "Default Knora Shared Ontologies Project", language = Some("en")))
+ .map(Description.unsafeFrom),
keywords = List.empty,
logo = None,
ontologies = Seq.empty[IRI],
@@ -301,7 +304,8 @@ object SharedTestDataADM {
shortname = Shortname.unsafeFrom("images"),
shortcode = Shortcode.unsafeFrom("00FF"),
longname = Some(Longname.unsafeFrom("Image Collection Demo")),
- description = Seq(StringLiteralV2.from(value = "A demo project of a collection of images", language = Some("en"))),
+ description = List(StringLiteralV2.from(value = "A demo project of a collection of images", language = Some("en")))
+ .map(Description.unsafeFrom),
keywords = List("images", "collection").map(Keyword.unsafeFrom),
logo = None,
ontologies = Seq(SharedOntologyTestDataADM.IMAGES_ONTOLOGY_IRI),
@@ -317,7 +321,8 @@ object SharedTestDataADM {
shortname = Shortname.unsafeFrom("images"),
shortcode = Shortcode.unsafeFrom("00FF"),
longname = Some(Longname.unsafeFrom("Image Collection Demo")),
- description = Seq(StringLiteralV2.from(value = "A demo project of a collection of images", language = Some("en"))),
+ description = List(StringLiteralV2.from(value = "A demo project of a collection of images", language = Some("en")))
+ .map(Description.unsafeFrom),
keywords = List("images", "collection").map(Keyword.unsafeFrom),
logo = None,
ontologies = Seq(SharedOntologyTestDataADM.IMAGES_ONTOLOGY_IRI_LocalHost),
@@ -461,13 +466,13 @@ object SharedTestDataADM {
shortname = Shortname.unsafeFrom("incunabula"),
shortcode = Shortcode.unsafeFrom("0803"),
longname = Some(Longname.unsafeFrom("Bilderfolgen Basler Frühdrucke")),
- description = Seq(
+ description = List(
StringLiteralV2.from(
value =
"Das interdisziplinäre Forschungsprojekt \"Die Bilderfolgen der Basler Frühdrucke: Spätmittelalterliche Didaxe als Bild-Text-Lektüre\" verbindet eine umfassende kunstwissenschaftliche Analyse der Bezüge zwischen den Bildern und Texten in den illustrierten Basler Inkunabeln mit der Digitalisierung der Bestände der Universitätsbibliothek und der Entwicklung einer elektronischen Edition in der Form einer neuartigen Web-0.2-Applikation.\n
\nDas Projekt wird durchgeführt vom Kunsthistorischen Seminar der Universität Basel (Prof. B. Schellewald) und dem Digital Humanities Lab der Universität Basel (PD Dr. L. Rosenthaler).\n
\n\nDas Kernstück der digitalen Edition besteht aus rund zwanzig reich bebilderten Frühdrucken aus vier verschiedenen Basler Offizinen. Viele davon sind bereits vor 1500 in mehreren Ausgaben erschienen, einige fast gleichzeitig auf Deutsch und Lateinisch. Es handelt sich um eine ausserordentlich vielfältige Produktion; neben dem Heilsspiegel finden sich ein Roman, die Melusine, die Reisebeschreibungen des Jean de Mandeville, einige Gebets- und Erbauungsbüchlein, theologische Schriften, Fastenpredigten, die Leben der Heiligen Fridolin und Meinrad, das berühmte Narrenschiff sowie die Exempelsammlung des Ritters vom Thurn.\n
\nDie Internetpublikation macht das digitalisierte Korpus dieser Frühdrucke durch die Möglichkeiten nichtlinearer Verknüpfung und Kommentierung der Bilder und Texte, für die wissenschaftliche Edition sowie für die Erforschung der Bilder und Texte nutzbar machen. Auch können bereits bestehende und entstehende Online-Editionen damit verknüpft werden , wodurch die Nutzung von Datenbanken anderer Institutionen im Hinblick auf unser Corpus optimiert wird.\n
",
language = None,
),
- ),
+ ).map(Description.unsafeFrom),
keywords = List(
"Basler Frühdrucke",
"Inkunabel",
@@ -498,13 +503,13 @@ object SharedTestDataADM {
shortname = Shortname.unsafeFrom("incunabula"),
shortcode = Shortcode.unsafeFrom("0803"),
longname = Some(Longname.unsafeFrom("Bilderfolgen Basler Frühdrucke")),
- description = Seq(
+ description = List(
StringLiteralV2.from(
value =
"Das interdisziplinäre Forschungsprojekt \"Die Bilderfolgen der Basler Frühdrucke: Spätmittelalterliche Didaxe als Bild-Text-Lektüre\" verbindet eine umfassende kunstwissenschaftliche Analyse der Bezüge zwischen den Bildern und Texten in den illustrierten Basler Inkunabeln mit der Digitalisierung der Bestände der Universitätsbibliothek und der Entwicklung einer elektronischen Edition in der Form einer neuartigen Web-0.2-Applikation.\n
\nDas Projekt wird durchgeführt vom Kunsthistorischen Seminar der Universität Basel (Prof. B. Schellewald) und dem Digital Humanities Lab der Universität Basel (PD Dr. L. Rosenthaler).\n
\n\nDas Kernstück der digitalen Edition besteht aus rund zwanzig reich bebilderten Frühdrucken aus vier verschiedenen Basler Offizinen. Viele davon sind bereits vor 1500 in mehreren Ausgaben erschienen, einige fast gleichzeitig auf Deutsch und Lateinisch. Es handelt sich um eine ausserordentlich vielfältige Produktion; neben dem Heilsspiegel finden sich ein Roman, die Melusine, die Reisebeschreibungen des Jean de Mandeville, einige Gebets- und Erbauungsbüchlein, theologische Schriften, Fastenpredigten, die Leben der Heiligen Fridolin und Meinrad, das berühmte Narrenschiff sowie die Exempelsammlung des Ritters vom Thurn.\n
\nDie Internetpublikation macht das digitalisierte Korpus dieser Frühdrucke durch die Möglichkeiten nichtlinearer Verknüpfung und Kommentierung der Bilder und Texte, für die wissenschaftliche Edition sowie für die Erforschung der Bilder und Texte nutzbar machen. Auch können bereits bestehende und entstehende Online-Editionen damit verknüpft werden , wodurch die Nutzung von Datenbanken anderer Institutionen im Hinblick auf unser Corpus optimiert wird.\n",
language = None,
),
- ),
+ ).map(Description.unsafeFrom),
keywords = List(
"Basler Frühdrucke",
"Inkunabel",
@@ -633,7 +638,7 @@ object SharedTestDataADM {
shortname = Shortname.unsafeFrom("anything"),
shortcode = Shortcode.unsafeFrom("0001"),
longname = Some(Longname.unsafeFrom("Anything Project")),
- description = Seq(StringLiteralV2.from(value = "Anything Project", language = None)),
+ description = List(StringLiteralV2.from(value = "Anything Project", language = None)).map(Description.unsafeFrom),
keywords = List("things", "arbitrary test data").map(Keyword.unsafeFrom),
logo = None,
ontologies = Seq(SharedOntologyTestDataADM.ANYTHING_ONTOLOGY_IRI, SharedOntologyTestDataADM.SomethingOntologyIri),
@@ -648,7 +653,7 @@ object SharedTestDataADM {
shortname = Shortname.unsafeFrom("anything"),
shortcode = Shortcode.unsafeFrom("0001"),
longname = Some(Longname.unsafeFrom("Anything Project")),
- description = Seq(StringLiteralV2.from(value = "Anything Project", language = None)),
+ description = List(StringLiteralV2.from(value = "Anything Project", language = None)).map(Description.unsafeFrom),
keywords = List("things", "arbitrary test data").map(Keyword.unsafeFrom),
logo = None,
ontologies = Seq(
@@ -685,7 +690,8 @@ object SharedTestDataADM {
shortname = Shortname.unsafeFrom("beol"),
shortcode = Shortcode.unsafeFrom("0801"),
longname = Some(Longname.unsafeFrom("Bernoulli-Euler Online")),
- description = Seq(StringLiteralV2.from(value = "Bernoulli-Euler Online", language = None)),
+ description =
+ List(StringLiteralV2.from(value = "Bernoulli-Euler Online", language = None)).map(Description.unsafeFrom),
keywords = List.empty,
logo = None,
ontologies = Seq(
@@ -741,7 +747,7 @@ object SharedTestDataADM {
shortname = Shortname.unsafeFrom("dokubib"),
shortcode = Shortcode.unsafeFrom("0804"),
longname = Some(Longname.unsafeFrom("Dokubib")),
- description = Seq(StringLiteralV2.from(value = "Dokubib", language = None)),
+ description = List(StringLiteralV2.from(value = "Dokubib", language = None)).map(Description.unsafeFrom),
keywords = List.empty,
logo = None,
ontologies = Seq("http://www.knora.org/ontology/0804/dokubib"),
diff --git a/webapi/src/main/scala/org/knora/webapi/slice/admin/api/Examples.scala b/webapi/src/main/scala/org/knora/webapi/slice/admin/api/Examples.scala
index 0abc38efac..fc0135555e 100644
--- a/webapi/src/main/scala/org/knora/webapi/slice/admin/api/Examples.scala
+++ b/webapi/src/main/scala/org/knora/webapi/slice/admin/api/Examples.scala
@@ -24,6 +24,7 @@ import org.knora.webapi.slice.admin.domain.model.GroupName
import org.knora.webapi.slice.admin.domain.model.GroupSelfJoin
import org.knora.webapi.slice.admin.domain.model.GroupStatus
import org.knora.webapi.slice.admin.domain.model.KnoraProject.CopyrightAttribution
+import org.knora.webapi.slice.admin.domain.model.KnoraProject.Description
import org.knora.webapi.slice.admin.domain.model.KnoraProject.Keyword
import org.knora.webapi.slice.admin.domain.model.KnoraProject.License
import org.knora.webapi.slice.admin.domain.model.KnoraProject.Longname
@@ -95,7 +96,7 @@ object Examples {
shortname = Shortname.unsafeFrom("example"),
shortcode = Shortcode.unsafeFrom("0001"),
longname = Some(Longname.unsafeFrom("Example Project")),
- description = Seq(StringLiteralV2.from("An example project", Some("en"))),
+ description = List(StringLiteralV2.from("An example project", Some("en"))).map(Description.unsafeFrom),
keywords = List("example", "project").map(Keyword.unsafeFrom),
logo = None,
status = Active,
diff --git a/webapi/src/main/scala/org/knora/webapi/slice/admin/api/model/ProjectsMessagesADM.scala b/webapi/src/main/scala/org/knora/webapi/slice/admin/api/model/ProjectsMessagesADM.scala
index ba5dc64f96..f7f3d60535 100644
--- a/webapi/src/main/scala/org/knora/webapi/slice/admin/api/model/ProjectsMessagesADM.scala
+++ b/webapi/src/main/scala/org/knora/webapi/slice/admin/api/model/ProjectsMessagesADM.scala
@@ -10,7 +10,6 @@ import zio.json.JsonCodec
import org.knora.webapi.IRI
import org.knora.webapi.messages.admin.responder.AdminKnoraResponseADM
-import org.knora.webapi.messages.store.triplestoremessages.StringLiteralV2
import org.knora.webapi.slice.admin.api.Codecs.ZioJsonCodec.*
import org.knora.webapi.slice.admin.domain.model.KnoraProject.*
import org.knora.webapi.slice.admin.domain.model.RestrictedView
@@ -35,7 +34,7 @@ case class Project(
shortname: Shortname,
shortcode: Shortcode,
longname: Option[Longname],
- description: Seq[StringLiteralV2],
+ description: List[Description],
keywords: List[Keyword],
logo: Option[Logo],
ontologies: Seq[IRI],
diff --git a/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/service/ProjectService.scala b/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/service/ProjectService.scala
index 84922ee815..142b0b73eb 100644
--- a/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/service/ProjectService.scala
+++ b/webapi/src/main/scala/org/knora/webapi/slice/admin/domain/service/ProjectService.scala
@@ -50,7 +50,7 @@ final case class ProjectService(
knoraProject.shortname,
knoraProject.shortcode,
knoraProject.longname,
- knoraProject.description.map(_.value),
+ knoraProject.description.toList,
knoraProject.keywords,
knoraProject.logo,
ontologies,
@@ -67,9 +67,7 @@ final case class ProjectService(
shortname = project.shortname,
shortcode = project.shortcode,
longname = project.longname,
- description = NonEmptyChunk
- .fromIterable(project.description.head, project.description.tail)
- .map(Description.unsafeFrom),
+ description = NonEmptyChunk.fromIterable(project.description.head, project.description.tail),
keywords = project.keywords,
logo = project.logo,
status = project.status,
diff --git a/webapi/src/test/scala/org/knora/webapi/slice/admin/domain/service/ProjectServiceSpec.scala b/webapi/src/test/scala/org/knora/webapi/slice/admin/domain/service/ProjectServiceSpec.scala
index f7badf15e1..325f7e58a4 100644
--- a/webapi/src/test/scala/org/knora/webapi/slice/admin/domain/service/ProjectServiceSpec.scala
+++ b/webapi/src/test/scala/org/knora/webapi/slice/admin/domain/service/ProjectServiceSpec.scala
@@ -29,7 +29,7 @@ object ProjectServiceSpec extends ZIOSpecDefault {
shortname = shortname,
shortcode = shortcode,
longname = None,
- description = List(StringLiteralV2.from("description not used in test", None)),
+ description = List(StringLiteralV2.from("description not used in test", None)).map(Description.unsafeFrom),
keywords = List.empty,
logo = None,
ontologies = List.empty,