From 55e49fb763ac6bd8ece5dfd27c14e3df70fad74e Mon Sep 17 00:00:00 2001 From: irinaschubert Date: Wed, 13 Oct 2021 09:37:57 +0200 Subject: [PATCH 1/7] Add language to group descriptions --- test_data/all_data/admin-data.ttl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test_data/all_data/admin-data.ttl b/test_data/all_data/admin-data.ttl index c07a58f042..dccd501131 100644 --- a/test_data/all_data/admin-data.ttl +++ b/test_data/all_data/admin-data.ttl @@ -204,7 +204,7 @@ knora-admin:groupName "Image reviewer"^^xsd:string ; - knora-admin:groupDescriptions "A group for image reviewers."^^xsd:string ; + knora-admin:groupDescriptions "A group for image reviewers."@en ; knora-admin:belongsToProject ; @@ -433,7 +433,7 @@ Die Internetpublikation macht das digitalisierte Korpus dieser Frühdrucke durc rdf:type knora-admin:UserGroup ; knora-admin:groupName "Thing searcher"^^xsd:string ; - knora-admin:groupDescriptions "A group for thing searchers."^^xsd:string ; + knora-admin:groupDescriptions "A group for thing searchers."@en ; knora-admin:belongsToProject ; knora-admin:status "true"^^xsd:boolean ; knora-admin:hasSelfJoinEnabled "true"^^xsd:boolean . From 8ca3a997560253989d8927f76316b36f1dc4001f Mon Sep 17 00:00:00 2001 From: irinaschubert Date: Wed, 13 Oct 2021 09:42:53 +0200 Subject: [PATCH 2/7] add language to group descriptions in test data --- .../drawings-gods_admin-data.ttl | 8 ++++---- .../lumieres-lausanne_admin.ttl | 12 ++++++------ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/test_data/other.v1.DrawingsGodsV1Spec/drawings-gods_admin-data.ttl b/test_data/other.v1.DrawingsGodsV1Spec/drawings-gods_admin-data.ttl index 991a0a1abd..dbff2ee0ba 100644 --- a/test_data/other.v1.DrawingsGodsV1Spec/drawings-gods_admin-data.ttl +++ b/test_data/other.v1.DrawingsGodsV1Spec/drawings-gods_admin-data.ttl @@ -20,28 +20,28 @@ rdf:type knora-admin:UserGroup ; knora-admin:groupName "Meta-annotators"^^xsd:string ; - knora-admin:groupDescriptions "A group of users allowed to annotate data. Does not upload images nor files. Does not access to personal data."^^xsd:string ; + knora-admin:groupDescriptions "A group of users allowed to annotate data. Does not upload images nor files. Does not access to personal data."@en ; knora-admin:belongsToProject ; knora-admin:status "true"^^xsd:boolean ; knora-admin:hasSelfJoinEnabled "false"^^xsd:boolean . rdf:type knora-admin:UserGroup ; knora-admin:groupName "Drawings contributors"^^xsd:string ; - knora-admin:groupDescriptions "A group of users allowed to upload images, files and annotate data. Does not access to personal data."^^xsd:string ; + knora-admin:groupDescriptions "A group of users allowed to upload images, files and annotate data. Does not access to personal data."@en ; knora-admin:belongsToProject ; knora-admin:status "true"^^xsd:boolean ; knora-admin:hasSelfJoinEnabled "false"^^xsd:boolean . rdf:type knora-admin:UserGroup ; knora-admin:groupName "SNF team"^^xsd:string ; - knora-admin:groupDescriptions "A core group of members from the SNF project. Access to any data, including sensitive."^^xsd:string ; + knora-admin:groupDescriptions "A core group of members from the SNF project. Access to any data, including sensitive."@en ; knora-admin:belongsToProject ; knora-admin:status "true"^^xsd:boolean ; knora-admin:hasSelfJoinEnabled "false"^^xsd:boolean . rdf:type knora-admin:UserGroup ; knora-admin:groupName "Administrators"^^xsd:string ; - knora-admin:groupDescriptions "A custom admin group created to apply permission precedence rules. Replaces the built-in knora-admin:ProjectAdmin group, not used for this project."^^xsd:string ; + knora-admin:groupDescriptions "A custom admin group created to apply permission precedence rules. Replaces the built-in knora-admin:ProjectAdmin group, not used for this project."@en ; knora-admin:belongsToProject ; knora-admin:status "true"^^xsd:boolean ; knora-admin:hasSelfJoinEnabled "false"^^xsd:boolean . diff --git a/test_data/other.v2.LumieresLausanneV2E2ESpec/lumieres-lausanne_admin.ttl b/test_data/other.v2.LumieresLausanneV2E2ESpec/lumieres-lausanne_admin.ttl index e2a43c3ffb..42086c3d4d 100644 --- a/test_data/other.v2.LumieresLausanneV2E2ESpec/lumieres-lausanne_admin.ttl +++ b/test_data/other.v2.LumieresLausanneV2E2ESpec/lumieres-lausanne_admin.ttl @@ -25,42 +25,42 @@ rdf:type knora-admin:UserGroup ; knora-admin:groupName "Utilisateur"^^xsd:string ; - knora-admin:groupDescriptions """Statut permanent. Attribué à toute personne désireuse de s'enregistrer. N'est membre d'aucun autre groupe (étudiant, chercheur). Par rapport au visiteur anonyme sans login, accès supplémentaire à la gestion des collections, aux transcriptions/documents joints/projets slmt si autorisation."""^^xsd:string ; + knora-admin:groupDescriptions """Statut permanent. Attribué à toute personne désireuse de s'enregistrer. N'est membre d'aucun autre groupe (étudiant, chercheur). Par rapport au visiteur anonyme sans login, accès supplémentaire à la gestion des collections, aux transcriptions/documents joints/projets slmt si autorisation."""@fr ; knora-admin:belongsToProject ; knora-admin:status "true"^^xsd:boolean ; knora-admin:hasSelfJoinEnabled "false"^^xsd:boolean . rdf:type knora-admin:UserGroup ; knora-admin:groupName "Etudiant"^^xsd:string ; - knora-admin:groupDescriptions """Statut temporaire. Uniquement les étudiants UNIL liés à un séminaire donné dans le cadre du projet Lumières.Lausanne. Ont reçu les consignes ainsi qu'une initiation (obligatoire). A la fin du séminaire, leur statut est changé en statut "Utilisateur", sauf demande particulière."""^^xsd:string ; + knora-admin:groupDescriptions """Statut temporaire. Uniquement les étudiants UNIL liés à un séminaire donné dans le cadre du projet Lumières.Lausanne. Ont reçu les consignes ainsi qu'une initiation (obligatoire). A la fin du séminaire, leur statut est changé en statut "Utilisateur", sauf demande particulière."""@fr ; knora-admin:belongsToProject ; knora-admin:status "true"^^xsd:boolean ; knora-admin:hasSelfJoinEnabled "false"^^xsd:boolean . rdf:type knora-admin:UserGroup ; knora-admin:groupName "Chercheur"^^xsd:string ; - knora-admin:groupDescriptions "Statut permanent. Doctorants, professeurs, autres chercheurs qui ont reçu préalablement l'autorisation d'un directeur. Ont reçu les consignes (obligatoire), et si possible une initiation."^^xsd:string ; + knora-admin:groupDescriptions "Statut permanent. Doctorants, professeurs, autres chercheurs qui ont reçu préalablement l'autorisation d'un directeur. Ont reçu les consignes (obligatoire), et si possible une initiation."@fr ; knora-admin:belongsToProject ; knora-admin:status "true"^^xsd:boolean ; knora-admin:hasSelfJoinEnabled "false"^^xsd:boolean . rdf:type knora-admin:UserGroup ; knora-admin:groupName "Doctorant"^^xsd:string ; - knora-admin:groupDescriptions "Statut temporaire. Doctorants et étudiants-assistants directement liés au Projet Lumières.Lausanne. Ont reçu les consignes ainsi qu'une initiation (obligatoire). Une fois leur mandat terminé, passent en statut Chercheur."^^xsd:string ; + knora-admin:groupDescriptions "Statut temporaire. Doctorants et étudiants-assistants directement liés au Projet Lumières.Lausanne. Ont reçu les consignes ainsi qu'une initiation (obligatoire). Une fois leur mandat terminé, passent en statut Chercheur."@fr ; knora-admin:belongsToProject ; knora-admin:status "true"^^xsd:boolean ; knora-admin:hasSelfJoinEnabled "false"^^xsd:boolean . rdf:type knora-admin:UserGroup ; knora-admin:groupName "Directeur"^^xsd:string ; - knora-admin:groupDescriptions "Béla Kapossy, Béatrice Lovis."^^xsd:string ; + knora-admin:groupDescriptions "Béla Kapossy, Béatrice Lovis."@fr ; knora-admin:belongsToProject ; knora-admin:status "true"^^xsd:boolean ; knora-admin:hasSelfJoinEnabled "false"^^xsd:boolean . rdf:type knora-admin:UserGroup ; knora-admin:groupName "Administrateur"^^xsd:string ; - knora-admin:groupDescriptions "Béatrice Lovis."^^xsd:string ; + knora-admin:groupDescriptions "Béatrice Lovis."@fr ; knora-admin:belongsToProject ; knora-admin:status "true"^^xsd:boolean ; knora-admin:hasSelfJoinEnabled "false"^^xsd:boolean . From ce341fb215eaa797ae7fe5755acb120fd72a2dcf Mon Sep 17 00:00:00 2001 From: irinaschubert Date: Wed, 13 Oct 2021 09:50:37 +0200 Subject: [PATCH 3/7] Update documentation --- docs/03-apis/api-admin/groups.md | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/docs/03-apis/api-admin/groups.md b/docs/03-apis/api-admin/groups.md index 7a0848f252..23e1c755d6 100644 --- a/docs/03-apis/api-admin/groups.md +++ b/docs/03-apis/api-admin/groups.md @@ -42,7 +42,7 @@ License along with DSP. If not, see . - Required permission: SystemAdmin / hasProjectAllAdminPermission / hasProjectAllGroupAdminPermission - Required information: name (unique inside project), project IRI -- Optional information: group description +- Optional information: group descriptions - Returns information about the newly created group - TypeScript Docs: groupFormats - CreateGroupApiRequestV1 - POST: `/admin/groups` @@ -51,7 +51,10 @@ License along with DSP. If not, see . ```json { "name": "NewGroup", - "description": "NewGroupDescription", + "descriptions": [ + {"value": "NewGroupDescription", "language": "en"}, + {"value": "NeueGruppenBeschreibung", "language": "de"} + ], "project": "http://rdfh.ch/projects/00FF", "status": true, "selfjoin": false @@ -65,7 +68,7 @@ specified by the `id` in the request body as below: { "id": "http://rdfh.ch/groups/00FF/a95UWs71KUklnFOe1rcw1w", "name": "GroupWithCustomIRI", - "description": "A new group with a custom IRI", + "descriptions": [{"value": "A new group with a custom IRI", "language": "en"}], "project": "http://rdfh.ch/projects/00FF", "status": true, "selfjoin": false @@ -77,7 +80,7 @@ specified by the `id` in the request body as below: - Required permission: SystemAdmin / hasProjectAllAdminPermission / hasProjectAllGroupAdminPermission / hasProjectRestrictedGroupAdminPermission (for this group) -- Changeable information: `name`, `description`, `selfjoin` +- Changeable information: `name`, `descriptions`, `selfjoin` - TypeScript Docs: groupFormats - ChangeGroupApiRequestADM - PUT: `/admin/groups/` - BODY: @@ -85,7 +88,7 @@ hasProjectRestrictedGroupAdminPermission (for this group) ```json { "name": "UpdatedGroupName", - "description": "UpdatedGroupDescription", + "descriptions": [{"value": "UpdatedGroupDescription", "language": "en"}], "selfjoin": false } ``` @@ -117,7 +120,7 @@ Example Group Information stored in admin named graph: : rdf:type knora-admin:UserGroup ; knora-admin:groupName "Name of the group" ; - knora-admin:groupDescriptions "A description of the group" ; + knora-admin:groupDescriptions "A description of the group"@en ; knora-admin:belongsToProject ; knora-admin:status "true"^^xsd:boolean ; knora-admin:hasSelfJoinEnabled "false"^^xsd:boolean . From 0dac02525ec2c86a43058993085ccb1c2adc7482 Mon Sep 17 00:00:00 2001 From: irinaschubert Date: Wed, 13 Oct 2021 14:25:23 +0200 Subject: [PATCH 4/7] fix failing tests --- .../org/knora/webapi/sharedtestdata/SharedTestDataADM.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webapi/src/test/scala/org/knora/webapi/sharedtestdata/SharedTestDataADM.scala b/webapi/src/test/scala/org/knora/webapi/sharedtestdata/SharedTestDataADM.scala index 43d420e21e..d4bc3b078e 100644 --- a/webapi/src/test/scala/org/knora/webapi/sharedtestdata/SharedTestDataADM.scala +++ b/webapi/src/test/scala/org/knora/webapi/sharedtestdata/SharedTestDataADM.scala @@ -347,7 +347,7 @@ object SharedTestDataADM { def imagesReviewerGroup: GroupADM = GroupADM( id = "http://rdfh.ch/groups/00FF/images-reviewer", name = "Image reviewer", - descriptions = Seq(StringLiteralV2(value = "A group for image reviewers.", language = None)), + descriptions = Seq(StringLiteralV2(value = "A group for image reviewers.", language = Some("en"))), project = imagesProject, status = true, selfjoin = false From d73d30d92762e68afcc58132468d2c120a046a39 Mon Sep 17 00:00:00 2001 From: irinaschubert Date: Thu, 14 Oct 2021 11:27:11 +0200 Subject: [PATCH 5/7] add plugin to update data --- knora-ontologies/knora-admin.ttl | 2 +- knora-ontologies/knora-base.ttl | 2 +- test_data/upgrade/BUILD.bazel | 1 + test_data/upgrade/pr1921.trig | 41 +++++++++ .../main/scala/org/knora/webapi/package.scala | 2 +- .../upgrade/RepositoryUpdatePlan.scala | 6 +- .../upgrade/plugins/UpgradePluginPR1921.scala | 80 ++++++++++++++++ .../triplestore/upgrade/plugins/BUILD.bazel | 19 ++++ .../plugins/UpgradePluginPR1921Spec.scala | 91 +++++++++++++++++++ 9 files changed, 240 insertions(+), 4 deletions(-) create mode 100644 test_data/upgrade/pr1921.trig create mode 100644 webapi/src/main/scala/org/knora/webapi/store/triplestore/upgrade/plugins/UpgradePluginPR1921.scala create mode 100644 webapi/src/test/scala/org/knora/webapi/store/triplestore/upgrade/plugins/UpgradePluginPR1921Spec.scala diff --git a/knora-ontologies/knora-admin.ttl b/knora-ontologies/knora-admin.ttl index d030c16837..99cf35707f 100644 --- a/knora-ontologies/knora-admin.ttl +++ b/knora-ontologies/knora-admin.ttl @@ -569,7 +569,7 @@ ] , [ rdf:type owl:Restriction ; owl:onProperty :groupDescriptions ; - owl:maxCardinality "1"^^xsd:nonNegativeInteger + owl:minCardinality "1"^^xsd:nonNegativeInteger ] , [ rdf:type owl:Restriction ; owl:onProperty :status ; diff --git a/knora-ontologies/knora-base.ttl b/knora-ontologies/knora-base.ttl index 10f06620f6..89720f556b 100644 --- a/knora-ontologies/knora-base.ttl +++ b/knora-ontologies/knora-base.ttl @@ -33,7 +33,7 @@ :attachedToProject knora-admin:SystemProject ; - :ontologyVersion "knora-base v12" . + :ontologyVersion "knora-base v13" . diff --git a/test_data/upgrade/BUILD.bazel b/test_data/upgrade/BUILD.bazel index f32844866a..d2d7311255 100644 --- a/test_data/upgrade/BUILD.bazel +++ b/test_data/upgrade/BUILD.bazel @@ -9,5 +9,6 @@ filegroup( "pr1372.trig", "pr1615.trig", "pr1746.trig", + "pr1921.trig", ], ) diff --git a/test_data/upgrade/pr1921.trig b/test_data/upgrade/pr1921.trig new file mode 100644 index 0000000000..5796a00529 --- /dev/null +++ b/test_data/upgrade/pr1921.trig @@ -0,0 +1,41 @@ +@prefix xsd: . +@prefix rdf: . +@prefix knora-admin: . + + a knora-admin:knoraProject ; + knora-admin:projectLongname "Test Project"^^xsd:string ; + knora-admin:projectShortname "test-project"^^xsd:string ; + knora-admin:projectShortcode "0105"^^xsd:string ; + knora-admin:projectDescription "Project description"^^xsd:string ; + knora-admin:projectKeywords "Keyword"^^xsd:string ; + knora-admin:status "true"^^xsd:boolean ; + knora-admin:hasSelfJoinEnabled "false"^^xsd:boolean . + + rdf:type knora-admin:UserGroup ; + knora-admin:groupName "Group without language string"^^xsd:string ; + knora-admin:groupDescriptions "A group description without language attribute."^^xsd:string ; + knora-admin:belongsToProject ; + knora-admin:status "true"^^xsd:boolean ; + knora-admin:hasSelfJoinEnabled "false"^^xsd:boolean . + + rdf:type knora-admin:UserGroup ; + knora-admin:groupName "Group without language string"^^xsd:string ; + knora-admin:groupDescriptions "A group description without language attribute." ; + knora-admin:belongsToProject ; + knora-admin:status "true"^^xsd:boolean ; + knora-admin:hasSelfJoinEnabled "false"^^xsd:boolean . + + rdf:type knora-admin:UserGroup ; + knora-admin:groupName "Group with language string"^^xsd:string ; + knora-admin:groupDescriptions "Eine Gruppe mit Sprachattribut."@de ; + knora-admin:belongsToProject ; + knora-admin:status "true"^^xsd:boolean ; + knora-admin:hasSelfJoinEnabled "false"^^xsd:boolean . + + rdf:type knora-admin:UserGroup ; + knora-admin:groupName "Group with language string"^^xsd:string ; + knora-admin:groupDescriptions "A group with language attribute."@en ; + knora-admin:belongsToProject ; + knora-admin:status "true"^^xsd:boolean ; + knora-admin:hasSelfJoinEnabled "false"^^xsd:boolean . + diff --git a/webapi/src/main/scala/org/knora/webapi/package.scala b/webapi/src/main/scala/org/knora/webapi/package.scala index 92ea6e889f..f76b10ca51 100644 --- a/webapi/src/main/scala/org/knora/webapi/package.scala +++ b/webapi/src/main/scala/org/knora/webapi/package.scala @@ -25,7 +25,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: String = "knora-base v12" + val KnoraBaseVersion: String = "knora-base v13" /** * `IRI` is a synonym for `String`, used to improve code readability. diff --git a/webapi/src/main/scala/org/knora/webapi/store/triplestore/upgrade/RepositoryUpdatePlan.scala b/webapi/src/main/scala/org/knora/webapi/store/triplestore/upgrade/RepositoryUpdatePlan.scala index fade4726e9..b1b8781b2a 100644 --- a/webapi/src/main/scala/org/knora/webapi/store/triplestore/upgrade/RepositoryUpdatePlan.scala +++ b/webapi/src/main/scala/org/knora/webapi/store/triplestore/upgrade/RepositoryUpdatePlan.scala @@ -43,7 +43,11 @@ object RepositoryUpdatePlan { PluginForKnoraBaseVersion(versionNumber = 9, plugin = new UpgradePluginPR1746(featureFactoryConfig, log)), PluginForKnoraBaseVersion(versionNumber = 10, plugin = new NoopPlugin), // PR 1808 PluginForKnoraBaseVersion(versionNumber = 11, plugin = new NoopPlugin), // PR 1813 - PluginForKnoraBaseVersion(versionNumber = 12, plugin = new NoopPlugin) // PR 1891 + PluginForKnoraBaseVersion(versionNumber = 12, plugin = new NoopPlugin), // PR 1891 + PluginForKnoraBaseVersion( + versionNumber = 13, + plugin = new UpgradePluginPR1921(featureFactoryConfig, log) + ) // PR 1921 ) /** diff --git a/webapi/src/main/scala/org/knora/webapi/store/triplestore/upgrade/plugins/UpgradePluginPR1921.scala b/webapi/src/main/scala/org/knora/webapi/store/triplestore/upgrade/plugins/UpgradePluginPR1921.scala new file mode 100644 index 0000000000..04e12a6302 --- /dev/null +++ b/webapi/src/main/scala/org/knora/webapi/store/triplestore/upgrade/plugins/UpgradePluginPR1921.scala @@ -0,0 +1,80 @@ +/* + * Copyright © 2015-2021 Data and Service Center for the Humanities (DaSCH) + * + * This file is part of Knora. + * + * Knora is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Knora is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with Knora. If not, see . + */ + +package org.knora.webapi.store.triplestore.upgrade.plugins + +import com.typesafe.scalalogging.Logger +import org.knora.webapi.feature.FeatureFactoryConfig +import org.knora.webapi.messages.store.triplestoremessages.StringLiteralV2 +import org.knora.webapi.messages.util.rdf._ +import org.knora.webapi.store.triplestore.upgrade.UpgradePlugin + +/** + * Transforms a repository for Knora PR 1921. + */ +class UpgradePluginPR1921(featureFactoryConfig: FeatureFactoryConfig, log: Logger) extends UpgradePlugin { + private val nodeFactory: RdfNodeFactory = RdfFeatureFactory.getRdfNodeFactory(featureFactoryConfig) + // Group descriptions without language attribute get DEFAULT_LANG attribute + private val DEFAULT_LANG = "en" + + override def transform(model: RdfModel): Unit = { + val statementsToRemove: collection.mutable.Set[Statement] = collection.mutable.Set.empty + val statementsToAdd: collection.mutable.Set[Statement] = collection.mutable.Set.empty + + def replaceSimpleStringWithRdfLiteral(statement: Statement, languageTag: String): Unit = { + val descriptionWithLanguage: RdfLiteral = + nodeFactory.makeStringWithLanguage(statement.obj.stringValue, languageTag) + + statementsToRemove += statement + + statementsToAdd += nodeFactory.makeStatement( + subj = statement.subj, + pred = statement.pred, + obj = descriptionWithLanguage, + context = statement.context + ) + + log.warn(s"Updated <${statement.subj}> <${statement.pred}> to <${descriptionWithLanguage}>") + } + + for (statement: Statement <- model) { + statement.pred match { + case predicate: IriNode => + if (predicate.stringValue == "http://www.knora.org/ontology/knora-admin#groupDescriptions") { + statement.obj match { + case stringWithLanguage: StringWithLanguage => + () + case stringWithLanguage: StringLiteralV2 => + () + case _ => + replaceSimpleStringWithRdfLiteral( + statement = statement, + languageTag = DEFAULT_LANG + ) + } + } + + case _ => () + } + } + + model.removeStatements(statementsToRemove.toSet) + model.addStatements(statementsToAdd.toSet) + } +} diff --git a/webapi/src/test/scala/org/knora/webapi/store/triplestore/upgrade/plugins/BUILD.bazel b/webapi/src/test/scala/org/knora/webapi/store/triplestore/upgrade/plugins/BUILD.bazel index 8aab125c43..3389f28eb1 100644 --- a/webapi/src/test/scala/org/knora/webapi/store/triplestore/upgrade/plugins/BUILD.bazel +++ b/webapi/src/test/scala/org/knora/webapi/store/triplestore/upgrade/plugins/BUILD.bazel @@ -122,3 +122,22 @@ scala_test( "//webapi:test_library", ] + BASE_TEST_DEPENDENCIES, ) + +scala_test( + name = "UpgradePluginPR1921Spec", + size = "small", + srcs = [ + "UpgradePluginPR1921Spec.scala", + "UpgradePluginSpec.scala", + ], + data = [ + "//knora-ontologies", + "//test_data", + "//test_data/upgrade", + ], + jvm_flags = ["-Dconfig.resource=fuseki.conf"], + deps = ALL_WEBAPI_MAIN_DEPENDENCIES + [ + "//webapi:main_library", + "//webapi:test_library", + ] + BASE_TEST_DEPENDENCIES, +) diff --git a/webapi/src/test/scala/org/knora/webapi/store/triplestore/upgrade/plugins/UpgradePluginPR1921Spec.scala b/webapi/src/test/scala/org/knora/webapi/store/triplestore/upgrade/plugins/UpgradePluginPR1921Spec.scala new file mode 100644 index 0000000000..a0959e5032 --- /dev/null +++ b/webapi/src/test/scala/org/knora/webapi/store/triplestore/upgrade/plugins/UpgradePluginPR1921Spec.scala @@ -0,0 +1,91 @@ +/* + * Copyright © 2015-2021 Data and Service Center for the Humanities (DaSCH) + * + * This file is part of Knora. + * + * Knora is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Knora is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with Knora. If not, see . + */ + +package org.knora.webapi.store.triplestore.upgrade.plugins + +import com.typesafe.scalalogging.LazyLogging +import org.knora.webapi.exceptions.AssertionException +import org.knora.webapi.messages.util.rdf._ + +class UpgradePluginPR1921Spec extends UpgradePluginSpec with LazyLogging { + private val nodeFactory: RdfNodeFactory = RdfFeatureFactory.getRdfNodeFactory(defaultFeatureFactoryConfig) + + private def checkLiteral(model: RdfModel, subj: IriNode, pred: IriNode, expectedObj: RdfLiteral): Unit = + model + .find( + subj = Some(subj), + pred = Some(pred), + obj = None + ) + .toSet + .headOption match { + case Some(statement: Statement) => + statement.obj match { + case rdfLiteral: RdfLiteral => assert(rdfLiteral == expectedObj) + case other => throw AssertionException(s"Unexpected object for $pred: $other") + } + + case None => throw AssertionException(s"No statement found with subject $subj and predicate $pred") + } + + "Upgrade plugin PR921" should { + "replace simple strings in group descriptions with language strings" in { + // Parse the input file. + val model: RdfModel = trigFileToModel("test_data/upgrade/pr1921.trig") + + // Use the plugin to transform the input. + val plugin = new UpgradePluginPR1921(defaultFeatureFactoryConfig, logger) + plugin.transform(model) + + // Check that a group description without language attribute gets a language attribute. String is marked as string. + checkLiteral( + model = model, + subj = nodeFactory.makeIriNode("http://rdfh.ch/groups/0105/group-without-language-attribute-1"), + pred = nodeFactory.makeIriNode("http://www.knora.org/ontology/knora-admin#groupDescriptions"), + expectedObj = + nodeFactory.makeStringWithLanguage("A group description without language attribute.", language = "en") + ) + + // Check that a group description without language attribute gets a language attribute. String is not marked as string. + checkLiteral( + model = model, + subj = nodeFactory.makeIriNode("http://rdfh.ch/groups/0105/group-without-language-attribute-2"), + pred = nodeFactory.makeIriNode("http://www.knora.org/ontology/knora-admin#groupDescriptions"), + expectedObj = + nodeFactory.makeStringWithLanguage("A group description without language attribute.", language = "en") + ) + + // Check that a group description with a language attribute is not changed. + checkLiteral( + model = model, + subj = nodeFactory.makeIriNode("http://rdfh.ch/groups/0105/group-with-language-attribute-de"), + pred = nodeFactory.makeIriNode("http://www.knora.org/ontology/knora-admin#groupDescriptions"), + expectedObj = nodeFactory.makeStringWithLanguage(value = "Eine Gruppe mit Sprachattribut.", language = "de") + ) + + // Check that a group description with default language attribute is not changed. + checkLiteral( + model = model, + subj = nodeFactory.makeIriNode("http://rdfh.ch/groups/0105/group-with-language-attribute-en"), + pred = nodeFactory.makeIriNode("http://www.knora.org/ontology/knora-admin#groupDescriptions"), + expectedObj = nodeFactory.makeStringWithLanguage(value = "A group with language attribute.", language = "en") + ) + } + } +} From 5d67118ceca0e9e0eb418bfd54b56136a560a74d Mon Sep 17 00:00:00 2001 From: irinaschubert Date: Thu, 14 Oct 2021 15:02:35 +0200 Subject: [PATCH 6/7] update plugin to update data --- test_data/upgrade/pr1921.trig | 18 ++++++++-- .../upgrade/plugins/UpgradePluginPR1921.scala | 35 ++++++++++++++++++- .../plugins/UpgradePluginPR1921Spec.scala | 22 ++++++++++++ 3 files changed, 72 insertions(+), 3 deletions(-) diff --git a/test_data/upgrade/pr1921.trig b/test_data/upgrade/pr1921.trig index 5796a00529..f8d7a119e8 100644 --- a/test_data/upgrade/pr1921.trig +++ b/test_data/upgrade/pr1921.trig @@ -12,19 +12,33 @@ knora-admin:hasSelfJoinEnabled "false"^^xsd:boolean . rdf:type knora-admin:UserGroup ; - knora-admin:groupName "Group without language string"^^xsd:string ; + knora-admin:groupName "Group without language string 1"^^xsd:string ; knora-admin:groupDescriptions "A group description without language attribute."^^xsd:string ; knora-admin:belongsToProject ; knora-admin:status "true"^^xsd:boolean ; knora-admin:hasSelfJoinEnabled "false"^^xsd:boolean . rdf:type knora-admin:UserGroup ; - knora-admin:groupName "Group without language string"^^xsd:string ; + knora-admin:groupName "Group without language string 2"^^xsd:string ; knora-admin:groupDescriptions "A group description without language attribute." ; knora-admin:belongsToProject ; knora-admin:status "true"^^xsd:boolean ; knora-admin:hasSelfJoinEnabled "false"^^xsd:boolean . + rdf:type knora-admin:UserGroup ; + knora-admin:groupName "Group without language string 3"^^xsd:string ; + knora-admin:groupDescription "A group description with old predicate name and without language attribute."^^xsd:string ; + knora-admin:belongsToProject ; + knora-admin:status "true"^^xsd:boolean ; + knora-admin:hasSelfJoinEnabled "false"^^xsd:boolean . + + rdf:type knora-admin:UserGroup ; + knora-admin:groupName "Group without language string 4"^^xsd:string ; + knora-admin:groupDescription "A group description with old predicate name and without language attribute." ; + knora-admin:belongsToProject ; + knora-admin:status "true"^^xsd:boolean ; + knora-admin:hasSelfJoinEnabled "false"^^xsd:boolean . + rdf:type knora-admin:UserGroup ; knora-admin:groupName "Group with language string"^^xsd:string ; knora-admin:groupDescriptions "Eine Gruppe mit Sprachattribut."@de ; diff --git a/webapi/src/main/scala/org/knora/webapi/store/triplestore/upgrade/plugins/UpgradePluginPR1921.scala b/webapi/src/main/scala/org/knora/webapi/store/triplestore/upgrade/plugins/UpgradePluginPR1921.scala index 04e12a6302..7abbcad663 100644 --- a/webapi/src/main/scala/org/knora/webapi/store/triplestore/upgrade/plugins/UpgradePluginPR1921.scala +++ b/webapi/src/main/scala/org/knora/webapi/store/triplestore/upgrade/plugins/UpgradePluginPR1921.scala @@ -41,11 +41,14 @@ class UpgradePluginPR1921(featureFactoryConfig: FeatureFactoryConfig, log: Logge val descriptionWithLanguage: RdfLiteral = nodeFactory.makeStringWithLanguage(statement.obj.stringValue, languageTag) + val newPredicateName: IriNode = + nodeFactory.makeIriNode("http://www.knora.org/ontology/knora-admin#groupDescriptions") + statementsToRemove += statement statementsToAdd += nodeFactory.makeStatement( subj = statement.subj, - pred = statement.pred, + pred = newPredicateName, obj = descriptionWithLanguage, context = statement.context ) @@ -53,6 +56,23 @@ class UpgradePluginPR1921(featureFactoryConfig: FeatureFactoryConfig, log: Logge log.warn(s"Updated <${statement.subj}> <${statement.pred}> to <${descriptionWithLanguage}>") } + def replaceOldPredicateNameOnly(statement: Statement): Unit = { + + val newPredicateName: IriNode = + nodeFactory.makeIriNode("http://www.knora.org/ontology/knora-admin#groupDescriptions") + + statementsToRemove += statement + + statementsToAdd += nodeFactory.makeStatement( + subj = statement.subj, + pred = newPredicateName, + obj = statement.obj, + context = statement.context + ) + + log.warn(s"Updated <${statement.pred}> to <${newPredicateName.stringValue}>") + } + for (statement: Statement <- model) { statement.pred match { case predicate: IriNode => @@ -70,6 +90,19 @@ class UpgradePluginPR1921(featureFactoryConfig: FeatureFactoryConfig, log: Logge } } + if (predicate.stringValue == "http://www.knora.org/ontology/knora-admin#groupDescription") { + statement.obj match { + case stringWithLanguage: StringWithLanguage => + replaceOldPredicateNameOnly(statement) + case stringWithLanguage: StringLiteralV2 => + replaceOldPredicateNameOnly(statement) + case _ => + replaceSimpleStringWithRdfLiteral( + statement = statement, + languageTag = DEFAULT_LANG + ) + } + } case _ => () } } diff --git a/webapi/src/test/scala/org/knora/webapi/store/triplestore/upgrade/plugins/UpgradePluginPR1921Spec.scala b/webapi/src/test/scala/org/knora/webapi/store/triplestore/upgrade/plugins/UpgradePluginPR1921Spec.scala index a0959e5032..a3c300ebd7 100644 --- a/webapi/src/test/scala/org/knora/webapi/store/triplestore/upgrade/plugins/UpgradePluginPR1921Spec.scala +++ b/webapi/src/test/scala/org/knora/webapi/store/triplestore/upgrade/plugins/UpgradePluginPR1921Spec.scala @@ -71,6 +71,28 @@ class UpgradePluginPR1921Spec extends UpgradePluginSpec with LazyLogging { nodeFactory.makeStringWithLanguage("A group description without language attribute.", language = "en") ) + // Check that a group description with old predicate name and without language attribute gets a language attribute. String is marked as string. + checkLiteral( + model = model, + subj = nodeFactory.makeIriNode("http://rdfh.ch/groups/0105/group-without-language-attribute-3"), + pred = nodeFactory.makeIriNode("http://www.knora.org/ontology/knora-admin#groupDescriptions"), + expectedObj = nodeFactory.makeStringWithLanguage( + "A group description with old predicate name and without language attribute.", + language = "en" + ) + ) + + // Check that a group description with old predicate name and without language attribute gets a language attribute. String is not marked as string. + checkLiteral( + model = model, + subj = nodeFactory.makeIriNode("http://rdfh.ch/groups/0105/group-without-language-attribute-4"), + pred = nodeFactory.makeIriNode("http://www.knora.org/ontology/knora-admin#groupDescriptions"), + expectedObj = nodeFactory.makeStringWithLanguage( + "A group description with old predicate name and without language attribute.", + language = "en" + ) + ) + // Check that a group description with a language attribute is not changed. checkLiteral( model = model, From 06f969771af035b42b4e07b50b76f4ba00ac7f9e Mon Sep 17 00:00:00 2001 From: irinaschubert Date: Thu, 14 Oct 2021 16:17:54 +0200 Subject: [PATCH 7/7] improve code --- .../upgrade/plugins/UpgradePluginPR1921.scala | 84 +++++++++---------- .../plugins/UpgradePluginPR1921Spec.scala | 16 ++-- 2 files changed, 50 insertions(+), 50 deletions(-) diff --git a/webapi/src/main/scala/org/knora/webapi/store/triplestore/upgrade/plugins/UpgradePluginPR1921.scala b/webapi/src/main/scala/org/knora/webapi/store/triplestore/upgrade/plugins/UpgradePluginPR1921.scala index 7abbcad663..b8d4d2a4f2 100644 --- a/webapi/src/main/scala/org/knora/webapi/store/triplestore/upgrade/plugins/UpgradePluginPR1921.scala +++ b/webapi/src/main/scala/org/knora/webapi/store/triplestore/upgrade/plugins/UpgradePluginPR1921.scala @@ -30,48 +30,48 @@ import org.knora.webapi.store.triplestore.upgrade.UpgradePlugin */ class UpgradePluginPR1921(featureFactoryConfig: FeatureFactoryConfig, log: Logger) extends UpgradePlugin { private val nodeFactory: RdfNodeFactory = RdfFeatureFactory.getRdfNodeFactory(featureFactoryConfig) - // Group descriptions without language attribute get DEFAULT_LANG attribute + // Group descriptions without language attribute get language attribute defined in DEFAULT_LANG private val DEFAULT_LANG = "en" override def transform(model: RdfModel): Unit = { val statementsToRemove: collection.mutable.Set[Statement] = collection.mutable.Set.empty val statementsToAdd: collection.mutable.Set[Statement] = collection.mutable.Set.empty - def replaceSimpleStringWithRdfLiteral(statement: Statement, languageTag: String): Unit = { - val descriptionWithLanguage: RdfLiteral = - nodeFactory.makeStringWithLanguage(statement.obj.stringValue, languageTag) - - val newPredicateName: IriNode = - nodeFactory.makeIriNode("http://www.knora.org/ontology/knora-admin#groupDescriptions") - - statementsToRemove += statement - - statementsToAdd += nodeFactory.makeStatement( - subj = statement.subj, - pred = newPredicateName, - obj = descriptionWithLanguage, - context = statement.context - ) - - log.warn(s"Updated <${statement.subj}> <${statement.pred}> to <${descriptionWithLanguage}>") - } - - def replaceOldPredicateNameOnly(statement: Statement): Unit = { - - val newPredicateName: IriNode = - nodeFactory.makeIriNode("http://www.knora.org/ontology/knora-admin#groupDescriptions") - - statementsToRemove += statement - - statementsToAdd += nodeFactory.makeStatement( - subj = statement.subj, - pred = newPredicateName, - obj = statement.obj, - context = statement.context - ) - - log.warn(s"Updated <${statement.pred}> to <${newPredicateName.stringValue}>") - } + val newPredicateLabel: IriNode = + nodeFactory.makeIriNode("http://www.knora.org/ontology/knora-admin#groupDescriptions") + + def updateGroupDescription(statement: Statement, languageTag: Option[String]): Unit = + languageTag match { + // the group description did not have a language attribute + case Some(lang) => + val groupDescriptionWithLanguage: RdfLiteral = + nodeFactory.makeStringWithLanguage(statement.obj.stringValue, lang) + + statementsToRemove += statement + + statementsToAdd += nodeFactory.makeStatement( + subj = statement.subj, + pred = newPredicateLabel, + obj = groupDescriptionWithLanguage, + context = statement.context + ) + + log.warn( + s"Updated <${statement.subj}> <${statement.pred}> to <${newPredicateLabel.stringValue}> with <${groupDescriptionWithLanguage}>" + ) + + // the group description did already have a language attribute + case None => + statementsToRemove += statement + + statementsToAdd += nodeFactory.makeStatement( + subj = statement.subj, + pred = newPredicateLabel, + obj = statement.obj, + context = statement.context + ) + log.warn(s"Updated <${statement.pred}> to <${newPredicateLabel.stringValue}>") + } for (statement: Statement <- model) { statement.pred match { @@ -83,9 +83,9 @@ class UpgradePluginPR1921(featureFactoryConfig: FeatureFactoryConfig, log: Logge case stringWithLanguage: StringLiteralV2 => () case _ => - replaceSimpleStringWithRdfLiteral( + updateGroupDescription( statement = statement, - languageTag = DEFAULT_LANG + languageTag = Some(DEFAULT_LANG) ) } } @@ -93,13 +93,13 @@ class UpgradePluginPR1921(featureFactoryConfig: FeatureFactoryConfig, log: Logge if (predicate.stringValue == "http://www.knora.org/ontology/knora-admin#groupDescription") { statement.obj match { case stringWithLanguage: StringWithLanguage => - replaceOldPredicateNameOnly(statement) + updateGroupDescription(statement, None) case stringWithLanguage: StringLiteralV2 => - replaceOldPredicateNameOnly(statement) + updateGroupDescription(statement, None) case _ => - replaceSimpleStringWithRdfLiteral( + updateGroupDescription( statement = statement, - languageTag = DEFAULT_LANG + languageTag = Some(DEFAULT_LANG) ) } } diff --git a/webapi/src/test/scala/org/knora/webapi/store/triplestore/upgrade/plugins/UpgradePluginPR1921Spec.scala b/webapi/src/test/scala/org/knora/webapi/store/triplestore/upgrade/plugins/UpgradePluginPR1921Spec.scala index a3c300ebd7..a4e4b2edb5 100644 --- a/webapi/src/test/scala/org/knora/webapi/store/triplestore/upgrade/plugins/UpgradePluginPR1921Spec.scala +++ b/webapi/src/test/scala/org/knora/webapi/store/triplestore/upgrade/plugins/UpgradePluginPR1921Spec.scala @@ -45,14 +45,13 @@ class UpgradePluginPR1921Spec extends UpgradePluginSpec with LazyLogging { } "Upgrade plugin PR921" should { - "replace simple strings in group descriptions with language strings" in { - // Parse the input file. - val model: RdfModel = trigFileToModel("test_data/upgrade/pr1921.trig") - - // Use the plugin to transform the input. - val plugin = new UpgradePluginPR1921(defaultFeatureFactoryConfig, logger) - plugin.transform(model) + // Parse the input file. + val model: RdfModel = trigFileToModel("test_data/upgrade/pr1921.trig") + // Use the plugin to transform the input. + val plugin = new UpgradePluginPR1921(defaultFeatureFactoryConfig, logger) + plugin.transform(model) + "replace simple strings in group descriptions with language strings" in { // Check that a group description without language attribute gets a language attribute. String is marked as string. checkLiteral( model = model, @@ -92,7 +91,8 @@ class UpgradePluginPR1921Spec extends UpgradePluginSpec with LazyLogging { language = "en" ) ) - + } + "not change group descriptions which have language attributes" in { // Check that a group description with a language attribute is not changed. checkLiteral( model = model,