From 81af10221481aefe4ca5a382c60ac6e4f01772ae Mon Sep 17 00:00:00 2001 From: Matthias Ronge Date: Thu, 30 Mar 2023 10:20:14 +0200 Subject: [PATCH 01/72] Implement interface and tests --- .../RulesetManagementInterface.java | 17 +++ .../dataeditor/ruleset/RulesetManagement.java | 6 +- .../ruleset/RulesetManagementIT.java | 117 ++++++++++++++++++ .../src/test/resources/ruleset.xsd | 30 ++++- .../resources/testReimportOfMetadataModes.xml | 70 +++++++++++ Kitodo/rulesets/ruleset.xsd | 19 ++- 6 files changed, 255 insertions(+), 4 deletions(-) create mode 100644 Kitodo-DataEditor/src/test/resources/testReimportOfMetadataModes.xml diff --git a/Kitodo-API/src/main/java/org/kitodo/api/dataeditor/rulesetmanagement/RulesetManagementInterface.java b/Kitodo-API/src/main/java/org/kitodo/api/dataeditor/rulesetmanagement/RulesetManagementInterface.java index 3b33dc39a49..81d14832016 100644 --- a/Kitodo-API/src/main/java/org/kitodo/api/dataeditor/rulesetmanagement/RulesetManagementInterface.java +++ b/Kitodo-API/src/main/java/org/kitodo/api/dataeditor/rulesetmanagement/RulesetManagementInterface.java @@ -16,6 +16,9 @@ import java.util.Collection; import java.util.List; import java.util.Locale.LanguageRange; + +import org.kitodo.api.Metadata; + import java.util.Map; import java.util.Optional; @@ -143,4 +146,18 @@ StructuralElementViewInterface getStructuralElementView(String structuralElement * @return the “always showing” value or its default value */ boolean isAlwaysShowingForKey(String keyId); + + /** + * Updates metadata during a repeated catalog import, depending on the + * reimport settings specified in the ruleset. + * + * @param metadata + * current metadata + * @param acquisitionStage + * current acquisition stage + * @param updateItems + * items obtained from import + * @return number of metadata added items + */ + int updateMetadata(Collection metadata, String acquisitionStage, Collection updateItems); } diff --git a/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/RulesetManagement.java b/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/RulesetManagement.java index 90c799167ae..c0b11d1856f 100644 --- a/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/RulesetManagement.java +++ b/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/RulesetManagement.java @@ -27,6 +27,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.kitodo.api.Metadata; import org.kitodo.api.dataeditor.rulesetmanagement.FunctionalDivision; import org.kitodo.api.dataeditor.rulesetmanagement.FunctionalMetadata; import org.kitodo.api.dataeditor.rulesetmanagement.RulesetManagementInterface; @@ -321,5 +322,8 @@ public boolean isAlwaysShowingForKey(String keyId) { return false; } - + @Override + public int updateMetadata(Collection metadata, String acquisitionStage, Collection updateItems) { + throw new UnsupportedOperationException("not yet implemented"); + } } diff --git a/Kitodo-DataEditor/src/test/java/org/kitodo/dataeditor/ruleset/RulesetManagementIT.java b/Kitodo-DataEditor/src/test/java/org/kitodo/dataeditor/ruleset/RulesetManagementIT.java index b1779318fd5..6ea1cd6b5c7 100644 --- a/Kitodo-DataEditor/src/test/java/org/kitodo/dataeditor/ruleset/RulesetManagementIT.java +++ b/Kitodo-DataEditor/src/test/java/org/kitodo/dataeditor/ruleset/RulesetManagementIT.java @@ -31,6 +31,7 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Locale.LanguageRange; @@ -40,6 +41,7 @@ import org.apache.commons.lang3.StringUtils; import org.junit.Test; +import org.kitodo.api.MdSec; import org.kitodo.api.Metadata; import org.kitodo.api.MetadataEntry; import org.kitodo.api.dataeditor.rulesetmanagement.ComplexMetadataViewInterface; @@ -1066,6 +1068,113 @@ public void testValidationByCodomain() throws IOException { Collections.emptyList())); } + public void testReimportOfMetadataModesCreate() throws Exception { + RulesetManagement underTest = new RulesetManagement(); + underTest.load(new File("src/test/resources/testReimportOfMetadataModes.xml")); + + Collection metadata = new HashSet<>(); + metadata.add(newMetadataEntry("metadataToReplaceByDefault", "value to replace")); + metadata.add(newMetadataEntry("metadataToReplaceExplicitly", "value to replace")); + metadata.add(newMetadataEntry("metadataToAdd", "value 1")); + metadata.add(newMetadataEntry("metadataToAddDuringCreationAndKeepLater", "value 1")); + metadata.add(newMetadataEntry("metadataToKeep", "value not to replace")); + metadata.add(newMetadataEntry("metadataToKeepExceptInEditing", "value not to replace")); + + Collection imported = new HashSet<>(); + imported.add(newMetadataEntry("metadataToReplaceByDefault", "replaced value")); // 0 + imported.add(newMetadataEntry("metadataToReplaceExplicitly", "replaced value")); // 0 + imported.add(newMetadataEntry("metadataToAdd", "value 2")); // 1 + imported.add(newMetadataEntry("metadataToAdd", "value 3")); // 1 + imported.add(newMetadataEntry("metadataToAddDuringCreationAndKeepLater", "value 2")); // 1 + imported.add(newMetadataEntry("metadataToKeep", "value must not appear in result")); // 0 + imported.add(newMetadataEntry("metadataToKeepExceptInEditing", "value not to replace")); // 0 + imported.add(newMetadataEntry("metadataThatIsNew", "new value")); // 1 + + int numAdded = underTest.updateMetadata(metadata, "create", imported); + assertEquals(4, numAdded); + + List defaultReplace = metadata.stream() + .filter(element -> element.getKey().equals("metadataToReplaceByDefault")).collect(Collectors.toList()); + assertEquals(1, defaultReplace.size()); + assertEquals("replaced value", ((MetadataEntry) defaultReplace.get(0)).getValue()); + + List explicitReplace = metadata.stream() + .filter(element -> element.getKey().equals("metadataToReplaceExplicitly")).collect(Collectors.toList()); + assertEquals(1, explicitReplace.size()); + assertEquals("replaced value", ((MetadataEntry) explicitReplace.get(0)).getValue()); + + List add = metadata.stream().filter(element -> element.getKey().equals("metadataToAdd")) + .collect(Collectors.toList()); + assertEquals(2, add.size()); + assertThat( + add.stream().map(MetadataEntry.class::cast).map(MetadataEntry::getValue).collect(Collectors.toList()), + containsInAnyOrder("value 1", "value 2")); + + List addCreate = metadata.stream() + .filter(element -> element.getKey().equals("metadataToAddDuringCreationAndKeepLater")) + .collect(Collectors.toList()); + assertEquals(2, addCreate.size()); + assertThat( + addCreate.stream().map(MetadataEntry.class::cast).map(MetadataEntry::getValue).collect(Collectors.toList()), + containsInAnyOrder("value 1", "value 2")); + + List keep = metadata.stream().filter(element -> element.getKey().equals("metadataToKeep")) + .collect(Collectors.toList()); + assertEquals(1, keep.size()); + assertEquals("value not to replace", ((MetadataEntry) keep.get(0)).getValue()); + + List keepNoEdit = metadata.stream() + .filter(element -> element.getKey().equals("metadataToKeepExceptInEditing")) + .collect(Collectors.toList()); + assertEquals(1, keepNoEdit.size()); + assertEquals("value not to replace", ((MetadataEntry) keepNoEdit.get(0)).getValue()); + } + + public void testReimportOfMetadataModesEdit() throws Exception { + RulesetManagement underTest = new RulesetManagement(); + underTest.load(new File("src/test/resources/testReimportOfMetadataModes.xml")); + + Collection metadata = new HashSet<>(); + metadata.add(newMetadataEntry("metadataToAddDuringCreationAndKeepLater", "value 1")); + metadata.add(newMetadataEntry("metadataToAddDuringCreationAndKeepLater", "value 2")); + metadata.add(newMetadataEntry("metadataToKeepExceptInEditing", "value 1")); + metadata.add(newMetadataEntry("metadataToKeepExceptInEditing", "value 2")); + + Collection imported = new HashSet<>(); + imported.add(newMetadataEntry("metadataToAddDuringCreationAndKeepLater", "value not to replace")); // 0 + imported.add(newMetadataEntry("metadataToKeepExceptInEditing", "replaced value")); // -1 + + int numAdded = underTest.updateMetadata(metadata, "edit", imported); + assertEquals(-1, numAdded); + + List keepLater = metadata.stream() + .filter(element -> element.getKey().equals("metadataToAddDuringCreationAndKeepLater")) + .collect(Collectors.toList()); + assertEquals(2, keepLater.size()); + assertThat( + keepLater.stream().map(MetadataEntry.class::cast).map(MetadataEntry::getValue).collect(Collectors.toList()), + containsInAnyOrder("value 1", "value 2")); + + List addCreate = metadata.stream() + .filter(element -> element.getKey().equals("metadataToAddDuringCreationAndKeepLater")) + .collect(Collectors.toList()); + assertEquals(2, addCreate.size()); + assertThat( + addCreate.stream().map(MetadataEntry.class::cast).map(MetadataEntry::getValue).collect(Collectors.toList()), + containsInAnyOrder("value 1", "value 2")); + + List keep = metadata.stream().filter(element -> element.getKey().equals("metadataToKeep")) + .collect(Collectors.toList()); + assertEquals(1, keep.size()); + assertEquals("value not to replace", ((MetadataEntry) keep.get(0)).getValue()); + + List replaceInEdit = metadata.stream() + .filter(element -> element.getKey().equals("metadataToKeepExceptInEditing")) + .collect(Collectors.toList()); + assertEquals(1, replaceInEdit.size()); + assertEquals("replaced value", ((MetadataEntry) replaceInEdit.get(0)).getValue()); + } + /** * The method provides a simple access to a metadata key in a list of * MetadataViewWithValuesInterface. @@ -1128,4 +1237,12 @@ private List ids(List metadataViewWithV .map(metadataViewWithValuesInterface -> metadataViewWithValuesInterface.getMetadata().get().getId()) .collect(Collectors.toList()); } + + private MetadataEntry newMetadataEntry(String key, String value) { + MetadataEntry newMetadataEntry = new MetadataEntry(); + newMetadataEntry.setKey(key); + newMetadataEntry.setValue(value); + newMetadataEntry.setDomain(MdSec.DMD_SEC); + return newMetadataEntry; + } } diff --git a/Kitodo-DataEditor/src/test/resources/ruleset.xsd b/Kitodo-DataEditor/src/test/resources/ruleset.xsd index b102eb5eba7..fa6c923eddf 100644 --- a/Kitodo-DataEditor/src/test/resources/ruleset.xsd +++ b/Kitodo-DataEditor/src/test/resources/ruleset.xsd @@ -49,9 +49,13 @@ URI; if the type is specified, this applies. If a namespace has been specified, Production looks for an XML file in the same directory whose file name is the same as the last segment of the namespace URI and, if it finds it, makes the namespace elements available as a selection list. + + The attribute "minDigits" can be used with type="integer" to define a minimum number of digits, which + will save the value with leading zeroes, if it has less digits. + @@ -265,6 +269,22 @@ + + + + The attribute "reimport" indicates how the metadata entry should behave when imported repeatedly: + 'add' adds the newly imported metadata entry to the existing entries. + 'replace' replaces an existing metadata entry with the new value. (This is the default case.) + 'keep' keeps the first existing value and discards the additionally imported value. + + + + + + + + + @@ -297,7 +317,8 @@ A <ruleset> technically describes the description of digital objects in structure and the assignment of metadata. The assumed default language of <label>s without the "lang" attribute is - English, unless another language is specified as default with the "lang" attribute here. Section + English, unless another language is specified as default with the "lang" attribute here. + <include>s allow to preload embedded ruleset files. Section <declaration> defines the possible <division>s and metadata <key>s. In section <restriction>, the possible combinations of the former can be restricted. In section <editing>, settings for displaying the input fields in the metadata editor can be made. @@ -305,6 +326,7 @@ + @@ -341,6 +363,7 @@ + @@ -399,7 +422,7 @@ - The attribute "unspecified" inicates whether the divisions, keys or options not mentioned in a + The attribute "unspecified" indicates whether the divisions, keys or options not mentioned in a <restriction> or <permit> are 'forbidden' and may not be offered, or whether they are 'unrestricted', and are to be arranged afterwards to explicitly named entries. The latter allows the few regularly used entries of a large set of values, for example a namespace, to be placed at the top @@ -420,6 +443,8 @@ 'authorLastName' The value is used as the author's last name to form the author-title key. + 'childCount' will set the (1-based) child number, when creating child documents. + 'dataSource' Internal identifier of the data source in order to be able to update the imported metadata entries from the data source later. @@ -442,6 +467,7 @@ + diff --git a/Kitodo-DataEditor/src/test/resources/testReimportOfMetadataModes.xml b/Kitodo-DataEditor/src/test/resources/testReimportOfMetadataModes.xml new file mode 100644 index 00000000000..a5d717f1979 --- /dev/null +++ b/Kitodo-DataEditor/src/test/resources/testReimportOfMetadataModes.xml @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Kitodo/rulesets/ruleset.xsd b/Kitodo/rulesets/ruleset.xsd index 173239dccf7..fa6c923eddf 100644 --- a/Kitodo/rulesets/ruleset.xsd +++ b/Kitodo/rulesets/ruleset.xsd @@ -269,6 +269,22 @@ + + + + The attribute "reimport" indicates how the metadata entry should behave when imported repeatedly: + 'add' adds the newly imported metadata entry to the existing entries. + 'replace' replaces an existing metadata entry with the new value. (This is the default case.) + 'keep' keeps the first existing value and discards the additionally imported value. + + + + + + + + + @@ -347,6 +363,7 @@ + @@ -405,7 +422,7 @@ - The attribute "unspecified" inicates whether the divisions, keys or options not mentioned in a + The attribute "unspecified" indicates whether the divisions, keys or options not mentioned in a <restriction> or <permit> are 'forbidden' and may not be offered, or whether they are 'unrestricted', and are to be arranged afterwards to explicitly named entries. The latter allows the few regularly used entries of a large set of values, for example a namespace, to be placed at the top From 76725eeae90ac45fba36ddd99bd8d71f63db6889 Mon Sep 17 00:00:00 2001 From: Matthias Ronge Date: Thu, 30 Mar 2023 10:31:10 +0200 Subject: [PATCH 02/72] Get reimport settings from ruleset --- .../dataeditor/ruleset/RulesetManagement.java | 2 + .../kitodo/dataeditor/ruleset/Settings.java | 1 + .../dataeditor/ruleset/xml/Reimport.java | 40 +++++++++++++++++++ .../dataeditor/ruleset/xml/Setting.java | 14 +++++++ 4 files changed, 57 insertions(+) create mode 100644 Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/xml/Reimport.java diff --git a/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/RulesetManagement.java b/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/RulesetManagement.java index c0b11d1856f..6c3cf68a4ea 100644 --- a/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/RulesetManagement.java +++ b/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/RulesetManagement.java @@ -324,6 +324,8 @@ public boolean isAlwaysShowingForKey(String keyId) { @Override public int updateMetadata(Collection metadata, String acquisitionStage, Collection updateItems) { + Settings settings = ruleset.getSettings(acquisitionStage); + throw new UnsupportedOperationException("not yet implemented"); } } diff --git a/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/Settings.java b/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/Settings.java index 9d13437de52..6823bf001fe 100644 --- a/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/Settings.java +++ b/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/Settings.java @@ -157,6 +157,7 @@ private List merge(Collection currentSettings, Collection + * + * This file is part of the Kitodo project. + * + * It is licensed under GNU General Public License version 3 or later. + * + * For the full copyright and license information, please read the + * GPL3-License.txt file that was distributed with this source code. + */ + +package org.kitodo.dataeditor.ruleset.xml; + +import javax.xml.bind.annotation.XmlEnum; +import javax.xml.bind.annotation.XmlEnumValue; + +/** + * This class is a backing bean for the XML attribute reimport in the + * ruleset. With it, JAXB can map the attribute to an enum. + */ +@XmlEnum(String.class) +public enum Reimport { + /** + * The metadata should be added. + */ + @XmlEnumValue("add") + ADD, + + /** + * The existing metadata should be kept. + */ + @XmlEnumValue("keep") + KEEP, + + /** + * The existing metadata should be replaced. + */ + @XmlEnumValue("replace") + REPLACE +} diff --git a/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/xml/Setting.java b/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/xml/Setting.java index e7cdd33aa6e..4a325e22ceb 100644 --- a/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/xml/Setting.java +++ b/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/xml/Setting.java @@ -73,6 +73,12 @@ public class Setting { @XmlAttribute private Boolean multiline; + /** + * This will specify how to update metadata in repeated imports. + */ + @XmlAttribute + private Reimport reimport; + /** * The settings for sub-keys. */ @@ -248,4 +254,12 @@ public void setMultiline(Boolean multiline) { public void setSettings(List settings) { this.settings = settings; } + + public Reimport getReimport() { + return reimport; + } + + public void setReimport(Reimport reimport) { + this.reimport = reimport; + } } From 3dd9ac40cc59c523e85d7cd1b7a39939613e572c Mon Sep 17 00:00:00 2001 From: Matthias Ronge Date: Thu, 30 Mar 2023 11:26:33 +0200 Subject: [PATCH 03/72] Implement metadata update --- .../dataeditor/ruleset/MetadataUpdater.java | 77 +++++++++++++++++++ .../dataeditor/ruleset/RulesetManagement.java | 15 +++- .../kitodo/dataeditor/ruleset/Settings.java | 16 ++++ .../ruleset/RulesetManagementIT.java | 19 +---- 4 files changed, 108 insertions(+), 19 deletions(-) create mode 100644 Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/MetadataUpdater.java diff --git a/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/MetadataUpdater.java b/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/MetadataUpdater.java new file mode 100644 index 00000000000..aecd02c28c9 --- /dev/null +++ b/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/MetadataUpdater.java @@ -0,0 +1,77 @@ +package org.kitodo.dataeditor.ruleset; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map.Entry; + +import org.apache.commons.lang3.tuple.MutableTriple; +import org.kitodo.api.Metadata; +import org.kitodo.dataeditor.ruleset.xml.Reimport; + +/** + * Performs an update merge of metadata. + */ +class MetadataUpdater extends MutableTriple, Reimport, Collection> { + + /** + * The metadata during the union. + */ + private HashMap unifying; + + /** + * Performs the update. @param currentMetadata the collection being updated + * + * @param updateMetadata + * the new metadata that is conditionally inserted + * @param settings + * how to replace the metadata + */ + void update(Collection currentMetadata, Collection updateMetadata, + Settings settings) { + + unifying = new HashMap<>(); + for (Metadata metadata : currentMetadata) { + unifying.computeIfAbsent(metadata.getKey(), MetadataUpdater::create).getLeft().add(metadata); + } + for (Metadata metadata : updateMetadata) { + unifying.computeIfAbsent(metadata.getKey(), MetadataUpdater::create).getRight().add(metadata); + } + for (Entry entry:unifying.entrySet()) { + entry.getValue().setMiddle(settings.getReimport(entry.getKey())); + } + + currentMetadata.clear(); + for (Entry entry:unifying.entrySet()) { + MetadataUpdater metadata = entry.getValue(); + switch(metadata.getMiddle()) { + case ADD: + currentMetadata.addAll(metadata.getLeft()); + currentMetadata.addAll(metadata.getRight()); + break; + case KEEP: + currentMetadata.addAll(metadata.getLeft()); + break; + case REPLACE: + currentMetadata.addAll(metadata.getRight()); + break; + default: throw new IllegalStateException("complete switch"); + } + } + + unifying = null; + } + + /** + * Makeshift constructor function for {@code Map.computeIfAbsent()}. + * @see Map#computeIfAbsent(Object, java.util.function.Function) + * @param key key passed by the caller, to fulfill the method signature + * @return created storage object + */ + private static MetadataUpdater create(String key) { + MetadataUpdater created = new MetadataUpdater(); + created.setLeft(new ArrayList()); + created.setRight(new ArrayList()); + return created; + } +} diff --git a/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/RulesetManagement.java b/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/RulesetManagement.java index 6c3cf68a4ea..efde47a0773 100644 --- a/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/RulesetManagement.java +++ b/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/RulesetManagement.java @@ -13,20 +13,23 @@ import java.io.File; import java.io.IOException; -import java.util.ArrayList; +import java.util.*; import java.util.Collection; import java.util.List; import java.util.Locale.LanguageRange; import java.util.Map; +import java.util.Map.Entry; import java.util.Objects; import java.util.Optional; import java.util.Set; +import java.util.function.Function; import java.util.stream.Collectors; import javax.xml.bind.JAXBException; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.apache.commons.lang3.tuple.MutableTriple; import org.kitodo.api.Metadata; import org.kitodo.api.dataeditor.rulesetmanagement.FunctionalDivision; import org.kitodo.api.dataeditor.rulesetmanagement.FunctionalMetadata; @@ -36,6 +39,7 @@ import org.kitodo.dataeditor.ruleset.xml.Division; import org.kitodo.dataeditor.ruleset.xml.Key; import org.kitodo.dataeditor.ruleset.xml.Namespace; +import org.kitodo.dataeditor.ruleset.xml.Reimport; import org.kitodo.dataeditor.ruleset.xml.Ruleset; import org.kitodo.dataeditor.ruleset.xml.Setting; import org.kitodo.utils.JAXBContextCache; @@ -323,9 +327,12 @@ public boolean isAlwaysShowingForKey(String keyId) { } @Override - public int updateMetadata(Collection metadata, String acquisitionStage, Collection updateItems) { - Settings settings = ruleset.getSettings(acquisitionStage); + public int updateMetadata(Collection currentMetadata, String acquisitionStage, + Collection updateMetadata) { - throw new UnsupportedOperationException("not yet implemented"); + MetadataUpdater metadataUpdater = new MetadataUpdater(); + int sizeBefore = currentMetadata.size(); + metadataUpdater.update(currentMetadata, updateMetadata, ruleset.getSettings(acquisitionStage)); + return currentMetadata.size() - sizeBefore; } } diff --git a/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/Settings.java b/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/Settings.java index 6823bf001fe..0e856c8572a 100644 --- a/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/Settings.java +++ b/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/Settings.java @@ -21,6 +21,7 @@ import java.util.function.Function; import java.util.stream.Collectors; +import org.kitodo.dataeditor.ruleset.xml.Reimport; import org.kitodo.dataeditor.ruleset.xml.Setting; /** @@ -44,6 +45,21 @@ public Settings(Collection baseSettings) { .collect(Collectors.toMap(Setting::getKey, Function.identity())); } + /** + * Returns the reimport setting for a key. + * + * @param keyId + * key for which the query is + * @return reimport setting + */ + Reimport getReimport(String keyId) { + if (currentSettings.containsKey(keyId)) { + return currentSettings.get(keyId).getReimport(); + } else { + return Reimport.REPLACE; + } + } + /** * Returns the settings for a key. * diff --git a/Kitodo-DataEditor/src/test/java/org/kitodo/dataeditor/ruleset/RulesetManagementIT.java b/Kitodo-DataEditor/src/test/java/org/kitodo/dataeditor/ruleset/RulesetManagementIT.java index 6ea1cd6b5c7..d6222498a32 100644 --- a/Kitodo-DataEditor/src/test/java/org/kitodo/dataeditor/ruleset/RulesetManagementIT.java +++ b/Kitodo-DataEditor/src/test/java/org/kitodo/dataeditor/ruleset/RulesetManagementIT.java @@ -1068,6 +1068,7 @@ public void testValidationByCodomain() throws IOException { Collections.emptyList())); } + @Test public void testReimportOfMetadataModesCreate() throws Exception { RulesetManagement underTest = new RulesetManagement(); underTest.load(new File("src/test/resources/testReimportOfMetadataModes.xml")); @@ -1105,10 +1106,10 @@ public void testReimportOfMetadataModesCreate() throws Exception { List add = metadata.stream().filter(element -> element.getKey().equals("metadataToAdd")) .collect(Collectors.toList()); - assertEquals(2, add.size()); + assertEquals(3, add.size()); assertThat( add.stream().map(MetadataEntry.class::cast).map(MetadataEntry::getValue).collect(Collectors.toList()), - containsInAnyOrder("value 1", "value 2")); + containsInAnyOrder("value 1", "value 2", "value 3")); List addCreate = metadata.stream() .filter(element -> element.getKey().equals("metadataToAddDuringCreationAndKeepLater")) @@ -1130,6 +1131,7 @@ public void testReimportOfMetadataModesCreate() throws Exception { assertEquals("value not to replace", ((MetadataEntry) keepNoEdit.get(0)).getValue()); } + @Test public void testReimportOfMetadataModesEdit() throws Exception { RulesetManagement underTest = new RulesetManagement(); underTest.load(new File("src/test/resources/testReimportOfMetadataModes.xml")); @@ -1155,19 +1157,6 @@ public void testReimportOfMetadataModesEdit() throws Exception { keepLater.stream().map(MetadataEntry.class::cast).map(MetadataEntry::getValue).collect(Collectors.toList()), containsInAnyOrder("value 1", "value 2")); - List addCreate = metadata.stream() - .filter(element -> element.getKey().equals("metadataToAddDuringCreationAndKeepLater")) - .collect(Collectors.toList()); - assertEquals(2, addCreate.size()); - assertThat( - addCreate.stream().map(MetadataEntry.class::cast).map(MetadataEntry::getValue).collect(Collectors.toList()), - containsInAnyOrder("value 1", "value 2")); - - List keep = metadata.stream().filter(element -> element.getKey().equals("metadataToKeep")) - .collect(Collectors.toList()); - assertEquals(1, keep.size()); - assertEquals("value not to replace", ((MetadataEntry) keep.get(0)).getValue()); - List replaceInEdit = metadata.stream() .filter(element -> element.getKey().equals("metadataToKeepExceptInEditing")) .collect(Collectors.toList()); From a04c25d136ea5d3f29b56e63f650658bc7c67abe Mon Sep 17 00:00:00 2001 From: Matthias Ronge Date: Thu, 30 Mar 2023 12:41:27 +0200 Subject: [PATCH 04/72] Implement use --- .../RulesetManagementInterface.java | 2 +- .../kitodo/dataeditor/ruleset/Settings.java | 10 +++++--- .../createprocess/ProcessFieldedMetadata.java | 25 ++++++++----------- .../forms/dataeditor/MetadataPanel.java | 2 +- .../production/helper/ProcessHelper.java | 2 +- .../org/kitodo/DummyRulesetManagement.java | 7 ++++++ .../forms/createprocess/ProcessDetailIT.java | 2 +- .../process/ProcessValidatorIT.java | 2 +- .../process/TitleGeneratorTest.java | 2 +- 9 files changed, 30 insertions(+), 24 deletions(-) diff --git a/Kitodo-API/src/main/java/org/kitodo/api/dataeditor/rulesetmanagement/RulesetManagementInterface.java b/Kitodo-API/src/main/java/org/kitodo/api/dataeditor/rulesetmanagement/RulesetManagementInterface.java index 81d14832016..95043bebd1a 100644 --- a/Kitodo-API/src/main/java/org/kitodo/api/dataeditor/rulesetmanagement/RulesetManagementInterface.java +++ b/Kitodo-API/src/main/java/org/kitodo/api/dataeditor/rulesetmanagement/RulesetManagementInterface.java @@ -157,7 +157,7 @@ StructuralElementViewInterface getStructuralElementView(String structuralElement * current acquisition stage * @param updateItems * items obtained from import - * @return number of metadata added items + * @return number of added metadata items */ int updateMetadata(Collection metadata, String acquisitionStage, Collection updateItems); } diff --git a/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/Settings.java b/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/Settings.java index 0e856c8572a..150c913b138 100644 --- a/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/Settings.java +++ b/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/Settings.java @@ -53,11 +53,13 @@ public Settings(Collection baseSettings) { * @return reimport setting */ Reimport getReimport(String keyId) { - if (currentSettings.containsKey(keyId)) { - return currentSettings.get(keyId).getReimport(); - } else { - return Reimport.REPLACE; + Setting settingForKey = currentSettings.get(keyId); + if (settingForKey != null) { + Reimport reimport = settingForKey.getReimport(); + if (reimport != null) + return reimport; } + return Reimport.REPLACE; } /** diff --git a/Kitodo/src/main/java/org/kitodo/production/forms/createprocess/ProcessFieldedMetadata.java b/Kitodo/src/main/java/org/kitodo/production/forms/createprocess/ProcessFieldedMetadata.java index 04ce1e58ce0..719e5b03496 100644 --- a/Kitodo/src/main/java/org/kitodo/production/forms/createprocess/ProcessFieldedMetadata.java +++ b/Kitodo/src/main/java/org/kitodo/production/forms/createprocess/ProcessFieldedMetadata.java @@ -41,6 +41,7 @@ import org.kitodo.api.dataeditor.rulesetmanagement.InputType; import org.kitodo.api.dataeditor.rulesetmanagement.MetadataViewInterface; import org.kitodo.api.dataeditor.rulesetmanagement.MetadataViewWithValuesInterface; +import org.kitodo.api.dataeditor.rulesetmanagement.RulesetManagementInterface; import org.kitodo.api.dataeditor.rulesetmanagement.SimpleMetadataViewInterface; import org.kitodo.api.dataeditor.rulesetmanagement.StructuralElementViewInterface; import org.kitodo.api.dataformat.Division; @@ -93,6 +94,11 @@ public class ProcessFieldedMetadata extends ProcessDetail implements Serializabl */ private ComplexMetadataViewInterface metadataView; + /** + * To access the ruleset functions. + */ + private RulesetManagementInterface rulesetService; + /** * The tree node that JSF has to display. */ @@ -117,9 +123,11 @@ public ProcessFieldedMetadata() { * structure selected by the user * @param divisionView * information about that structure from the rule set + * @param rulesetManagementInterface */ - public ProcessFieldedMetadata(Division structure, StructuralElementViewInterface divisionView) { + public ProcessFieldedMetadata(Division structure, StructuralElementViewInterface divisionView, RulesetManagementInterface rulesetService) { this(null, structure, divisionView, null, null, structure.getMetadata()); + this.rulesetService = rulesetService; buildTreeNodeAndCreateMetadataTable(); } @@ -131,18 +139,7 @@ public ProcessFieldedMetadata(Division structure, StructuralElementViewInterf * @return returns count of added metadata */ public int addMetadataIfNotExists(Collection potentialMetadataItems) { - Collection metadataToAdd = new ArrayList<>(); - potentialMetadataItems.forEach( potentialMetadataItem -> { - if (metadata.stream().noneMatch(item -> item.getKey().equals(potentialMetadataItem.getKey()))) { - if (!(METADATA_KEY_LABEL.equals(potentialMetadataItem.getKey()) && StringUtils.isNotEmpty( - division.getLabel()) || METADATA_KEY_ORDERLABEL.equals( - potentialMetadataItem.getKey()) && StringUtils.isNotEmpty(division.getOrderlabel()))) { - metadataToAdd.add(potentialMetadataItem); - } - - } - }); - metadata.addAll(metadataToAdd); + int count = rulesetService.updateMetadata(metadata, "create", potentialMetadataItems); TreeNode editedTreeNode = treeNode; @@ -150,7 +147,7 @@ public int addMetadataIfNotExists(Collection potentialMetadataItems) { overwriteTreeNodes(editedTreeNode.getChildren(), treeNode.getChildren()); - return metadataToAdd.size(); + return count; } private void buildTreeNodeAndCreateMetadataTable() { diff --git a/Kitodo/src/main/java/org/kitodo/production/forms/dataeditor/MetadataPanel.java b/Kitodo/src/main/java/org/kitodo/production/forms/dataeditor/MetadataPanel.java index b6c2f371bdf..b9bbf5b2214 100644 --- a/Kitodo/src/main/java/org/kitodo/production/forms/dataeditor/MetadataPanel.java +++ b/Kitodo/src/main/java/org/kitodo/production/forms/dataeditor/MetadataPanel.java @@ -178,7 +178,7 @@ void showPhysical(Optional optionalPhysicalDivision) { private ProcessFieldedMetadata createProcessFieldedMetadata(Division structure) { StructuralElementViewInterface divisionView = dataEditorForm.getRulesetManagement().getStructuralElementView( structure.getType(), dataEditorForm.getAcquisitionStage(), dataEditorForm.getPriorityList()); - return new ProcessFieldedMetadata(structure, divisionView); + return new ProcessFieldedMetadata(structure, divisionView, dataEditorForm.getRulesetManagement()); } /** diff --git a/Kitodo/src/main/java/org/kitodo/production/helper/ProcessHelper.java b/Kitodo/src/main/java/org/kitodo/production/helper/ProcessHelper.java index f30b3f1a3de..4359f604171 100644 --- a/Kitodo/src/main/java/org/kitodo/production/helper/ProcessHelper.java +++ b/Kitodo/src/main/java/org/kitodo/production/helper/ProcessHelper.java @@ -99,7 +99,7 @@ public static ProcessFieldedMetadata initializeProcessDetails(LogicalDivision st RulesetManagementInterface managementInterface, String stage, List priorityList) { StructuralElementViewInterface divisionView = managementInterface.getStructuralElementView(structure.getType(), stage, priorityList); - return new ProcessFieldedMetadata(structure, divisionView); + return new ProcessFieldedMetadata(structure, divisionView, managementInterface); } /** diff --git a/Kitodo/src/test/java/org/kitodo/DummyRulesetManagement.java b/Kitodo/src/test/java/org/kitodo/DummyRulesetManagement.java index fd4cdce3ac2..b12619fab87 100644 --- a/Kitodo/src/test/java/org/kitodo/DummyRulesetManagement.java +++ b/Kitodo/src/test/java/org/kitodo/DummyRulesetManagement.java @@ -19,6 +19,7 @@ import java.util.Map; import java.util.Optional; +import org.kitodo.api.Metadata; import org.kitodo.api.dataeditor.rulesetmanagement.ComplexMetadataViewInterface; import org.kitodo.api.dataeditor.rulesetmanagement.FunctionalDivision; import org.kitodo.api.dataeditor.rulesetmanagement.FunctionalMetadata; @@ -77,4 +78,10 @@ public void load(File rulesetFile) throws IOException { public boolean isAlwaysShowingForKey(String keyId) { throw new UnsupportedOperationException(); } + + @Override + public int updateMetadata(Collection metadata, String acquisitionStage, + Collection updateItems) { + throw new UnsupportedOperationException(); + } } diff --git a/Kitodo/src/test/java/org/kitodo/production/forms/createprocess/ProcessDetailIT.java b/Kitodo/src/test/java/org/kitodo/production/forms/createprocess/ProcessDetailIT.java index 2a176dfeb1d..179e528d633 100644 --- a/Kitodo/src/test/java/org/kitodo/production/forms/createprocess/ProcessDetailIT.java +++ b/Kitodo/src/test/java/org/kitodo/production/forms/createprocess/ProcessDetailIT.java @@ -39,7 +39,7 @@ public void shouldCopyProcessDetail() throws Exception { titleDocMain.setKey("TitleDocMain"); titleDocMain.setValue("Lorem Ipsum"); division.getMetadata().add(titleDocMain); - ProcessFieldedMetadata processFieldedMetadata = new ProcessFieldedMetadata(division, divisionView); + ProcessFieldedMetadata processFieldedMetadata = new ProcessFieldedMetadata(division, divisionView, ruleset); TreeNode treeNode = processFieldedMetadata.getTreeNode(); ProcessDetail processDetail = (ProcessDetail) treeNode.getChildren().get(0).getData(); int beforeCopying = treeNode.getChildCount(); diff --git a/Kitodo/src/test/java/org/kitodo/production/process/ProcessValidatorIT.java b/Kitodo/src/test/java/org/kitodo/production/process/ProcessValidatorIT.java index 147ec62d0c1..55557a6a5b1 100644 --- a/Kitodo/src/test/java/org/kitodo/production/process/ProcessValidatorIT.java +++ b/Kitodo/src/test/java/org/kitodo/production/process/ProcessValidatorIT.java @@ -114,7 +114,7 @@ private List createProcessDetailsList() throws IOException { rulesetManagementInterface.load(new File("src/test/resources/rulesets/monograph.xml")); StructuralElementViewInterface monograph = rulesetManagementInterface.getStructuralElementView( "Monograph", "", Locale.LanguageRange.parse("en")); - ProcessFieldedMetadata processDetails = new ProcessFieldedMetadata(workpiece.getLogicalStructure(), monograph); + ProcessFieldedMetadata processDetails = new ProcessFieldedMetadata(workpiece.getLogicalStructure(), monograph, rulesetManagementInterface); for (ProcessDetail detail : processDetails.getRows()) { switch (detail.getMetadataID()) { case "TitleDocMain": diff --git a/Kitodo/src/test/java/org/kitodo/production/process/TitleGeneratorTest.java b/Kitodo/src/test/java/org/kitodo/production/process/TitleGeneratorTest.java index d5db365ed82..f678b3b4146 100644 --- a/Kitodo/src/test/java/org/kitodo/production/process/TitleGeneratorTest.java +++ b/Kitodo/src/test/java/org/kitodo/production/process/TitleGeneratorTest.java @@ -106,7 +106,7 @@ static List createProcessDetailsList() throws IOException { rulesetManagementInterface.load(new File("src/test/resources/rulesets/monograph.xml")); StructuralElementViewInterface monograph = rulesetManagementInterface.getStructuralElementView( "Monograph", "", Locale.LanguageRange.parse("en")); - ProcessFieldedMetadata processDetails = new ProcessFieldedMetadata(workpiece.getLogicalStructure(), monograph); + ProcessFieldedMetadata processDetails = new ProcessFieldedMetadata(workpiece.getLogicalStructure(), monograph, rulesetManagementInterface); for (ProcessDetail detail : processDetails.getRows()) { switch (detail.getMetadataID()) { case "TitleDocMain": From d4b2085ca317ca515f720f2dc74c47f5a97dbca7 Mon Sep 17 00:00:00 2001 From: Matthias Ronge Date: Thu, 30 Mar 2023 13:59:25 +0200 Subject: [PATCH 05/72] Clean-up --- .../dataeditor/ruleset/MetadataUpdater.java | 77 ------------------- .../dataeditor/ruleset/RulesetManagement.java | 49 ++++++++++-- .../createprocess/MetadataImportDialog.java | 2 +- .../createprocess/ProcessFieldedMetadata.java | 34 +------- 4 files changed, 47 insertions(+), 115 deletions(-) delete mode 100644 Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/MetadataUpdater.java diff --git a/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/MetadataUpdater.java b/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/MetadataUpdater.java deleted file mode 100644 index aecd02c28c9..00000000000 --- a/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/MetadataUpdater.java +++ /dev/null @@ -1,77 +0,0 @@ -package org.kitodo.dataeditor.ruleset; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map.Entry; - -import org.apache.commons.lang3.tuple.MutableTriple; -import org.kitodo.api.Metadata; -import org.kitodo.dataeditor.ruleset.xml.Reimport; - -/** - * Performs an update merge of metadata. - */ -class MetadataUpdater extends MutableTriple, Reimport, Collection> { - - /** - * The metadata during the union. - */ - private HashMap unifying; - - /** - * Performs the update. @param currentMetadata the collection being updated - * - * @param updateMetadata - * the new metadata that is conditionally inserted - * @param settings - * how to replace the metadata - */ - void update(Collection currentMetadata, Collection updateMetadata, - Settings settings) { - - unifying = new HashMap<>(); - for (Metadata metadata : currentMetadata) { - unifying.computeIfAbsent(metadata.getKey(), MetadataUpdater::create).getLeft().add(metadata); - } - for (Metadata metadata : updateMetadata) { - unifying.computeIfAbsent(metadata.getKey(), MetadataUpdater::create).getRight().add(metadata); - } - for (Entry entry:unifying.entrySet()) { - entry.getValue().setMiddle(settings.getReimport(entry.getKey())); - } - - currentMetadata.clear(); - for (Entry entry:unifying.entrySet()) { - MetadataUpdater metadata = entry.getValue(); - switch(metadata.getMiddle()) { - case ADD: - currentMetadata.addAll(metadata.getLeft()); - currentMetadata.addAll(metadata.getRight()); - break; - case KEEP: - currentMetadata.addAll(metadata.getLeft()); - break; - case REPLACE: - currentMetadata.addAll(metadata.getRight()); - break; - default: throw new IllegalStateException("complete switch"); - } - } - - unifying = null; - } - - /** - * Makeshift constructor function for {@code Map.computeIfAbsent()}. - * @see Map#computeIfAbsent(Object, java.util.function.Function) - * @param key key passed by the caller, to fulfill the method signature - * @return created storage object - */ - private static MetadataUpdater create(String key) { - MetadataUpdater created = new MetadataUpdater(); - created.setLeft(new ArrayList()); - created.setRight(new ArrayList()); - return created; - } -} diff --git a/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/RulesetManagement.java b/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/RulesetManagement.java index efde47a0773..2f9d244996d 100644 --- a/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/RulesetManagement.java +++ b/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/RulesetManagement.java @@ -13,23 +13,23 @@ import java.io.File; import java.io.IOException; -import java.util.*; +import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; import java.util.List; import java.util.Locale.LanguageRange; +import java.util.function.Function; import java.util.Map; -import java.util.Map.Entry; import java.util.Objects; import java.util.Optional; import java.util.Set; -import java.util.function.Function; import java.util.stream.Collectors; import javax.xml.bind.JAXBException; +import org.apache.commons.lang3.tuple.MutableTriple; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.apache.commons.lang3.tuple.MutableTriple; import org.kitodo.api.Metadata; import org.kitodo.api.dataeditor.rulesetmanagement.FunctionalDivision; import org.kitodo.api.dataeditor.rulesetmanagement.FunctionalMetadata; @@ -330,9 +330,46 @@ public boolean isAlwaysShowingForKey(String keyId) { public int updateMetadata(Collection currentMetadata, String acquisitionStage, Collection updateMetadata) { - MetadataUpdater metadataUpdater = new MetadataUpdater(); + final Function, Reimport, Collection>> entryProducer = key -> { + var entry = new MutableTriple, Reimport, Collection>(); + entry.setLeft(new ArrayList<>()); + entry.setRight(new ArrayList<>()); + return entry; + }; + + HashMap, Reimport, Collection>> unifying = new HashMap<>(); + for (Metadata metadata : currentMetadata) { + unifying.computeIfAbsent(metadata.getKey(), entryProducer).getLeft().add(metadata); + } + for (Metadata metadata : updateMetadata) { + unifying.computeIfAbsent(metadata.getKey(), entryProducer).getRight().add(metadata); + } + Settings settings = ruleset.getSettings(acquisitionStage); + for (var entry : unifying.entrySet()) { + entry.getValue().setMiddle(settings.getReimport(entry.getKey())); + } + int sizeBefore = currentMetadata.size(); - metadataUpdater.update(currentMetadata, updateMetadata, ruleset.getSettings(acquisitionStage)); + currentMetadata.clear(); + for (var entry : unifying.entrySet()) { + var metadata = entry.getValue(); + Collection currentEntries = metadata.getLeft(); + Collection updateEntries = metadata.getRight(); + + switch (metadata.getMiddle()) { + case ADD: + currentMetadata.addAll(currentEntries); + currentMetadata.addAll(updateEntries); + break; + case KEEP: + currentMetadata.addAll(currentEntries); + break; + case REPLACE: + currentMetadata.addAll(updateEntries.isEmpty() ? currentEntries : updateEntries); + break; + default: throw new IllegalStateException("complete switch"); + } + } return currentMetadata.size() - sizeBefore; } } diff --git a/Kitodo/src/main/java/org/kitodo/production/forms/createprocess/MetadataImportDialog.java b/Kitodo/src/main/java/org/kitodo/production/forms/createprocess/MetadataImportDialog.java index a2fdcd91234..b7a7c03a627 100644 --- a/Kitodo/src/main/java/org/kitodo/production/forms/createprocess/MetadataImportDialog.java +++ b/Kitodo/src/main/java/org/kitodo/production/forms/createprocess/MetadataImportDialog.java @@ -122,7 +122,7 @@ public List getImportConfigurations() { * @param processes * The linked list of TempProcess instances */ - void extendsMetadataTableOfMetadataTab(LinkedList processes) { + void extendsMetadataTableOfMetadataTab(LinkedList processes) throws InvalidMetadataValueException, NoSuchMetadataFieldException { int countOfAddedMetadata = 0; if (processes.size() > 0) { TempProcess process = processes.getFirst(); diff --git a/Kitodo/src/main/java/org/kitodo/production/forms/createprocess/ProcessFieldedMetadata.java b/Kitodo/src/main/java/org/kitodo/production/forms/createprocess/ProcessFieldedMetadata.java index 719e5b03496..6d59a6a096c 100644 --- a/Kitodo/src/main/java/org/kitodo/production/forms/createprocess/ProcessFieldedMetadata.java +++ b/Kitodo/src/main/java/org/kitodo/production/forms/createprocess/ProcessFieldedMetadata.java @@ -138,15 +138,10 @@ public ProcessFieldedMetadata(Division structure, StructuralElementViewInterf * metadata to add if not exist * @return returns count of added metadata */ - public int addMetadataIfNotExists(Collection potentialMetadataItems) { + public int addMetadataIfNotExists(Collection potentialMetadataItems) throws InvalidMetadataValueException, NoSuchMetadataFieldException { + preserve(); int count = rulesetService.updateMetadata(metadata, "create", potentialMetadataItems); - - TreeNode editedTreeNode = treeNode; - buildTreeNodeAndCreateMetadataTable(); - - overwriteTreeNodes(editedTreeNode.getChildren(), treeNode.getChildren()); - return count; } @@ -156,29 +151,6 @@ private void buildTreeNodeAndCreateMetadataTable() { createMetadataTable(); } - /** - * Overwrites the target list with source list of tree nodes based on the - * metadata id. - * - * @param source - * The list of source tree nodes - * @param target - * The list of target tree nodes - */ - private static void overwriteTreeNodes(List source, List target) { - int index = 0; - for (TreeNode targetNode : target) { - ProcessDetail row = (ProcessDetail) targetNode.getData(); - Optional treeNodeOptional = source.stream().filter( - sourceNode -> ((ProcessDetail) sourceNode.getData()).getMetadataID().equals(row.getMetadataID())) - .findFirst(); - if (treeNodeOptional.isPresent()) { - target.set(index, treeNodeOptional.get()); - } - index++; - } - } - /** * Creates a sub-panel for a metadata group. * @@ -613,7 +585,7 @@ public Collection getMetadata(boolean skipEmpty) throws InvalidMetadat } else { result.setMetadata(new HashSet<>(DataEditorService.getExistingMetadataRows(treeNode.getChildren()))); } - return Collections.singletonList(result); + return result.getMetadata().isEmpty() ? Collections.emptyList() : Collections.singletonList(result); } /** From 88c50d176b149f98fbfed24e018ee5ba114cb186 Mon Sep 17 00:00:00 2001 From: Matthias Ronge Date: Thu, 30 Mar 2023 14:25:07 +0200 Subject: [PATCH 06/72] Organize imports --- .../rulesetmanagement/RulesetManagementInterface.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Kitodo-API/src/main/java/org/kitodo/api/dataeditor/rulesetmanagement/RulesetManagementInterface.java b/Kitodo-API/src/main/java/org/kitodo/api/dataeditor/rulesetmanagement/RulesetManagementInterface.java index 95043bebd1a..916fa3990ac 100644 --- a/Kitodo-API/src/main/java/org/kitodo/api/dataeditor/rulesetmanagement/RulesetManagementInterface.java +++ b/Kitodo-API/src/main/java/org/kitodo/api/dataeditor/rulesetmanagement/RulesetManagementInterface.java @@ -16,12 +16,11 @@ import java.util.Collection; import java.util.List; import java.util.Locale.LanguageRange; - -import org.kitodo.api.Metadata; - import java.util.Map; import java.util.Optional; +import org.kitodo.api.Metadata; + /** * Interface for a service that provides access to the ruleset. * From 96eb697f8f57886e2883aa077066a20f78e69713 Mon Sep 17 00:00:00 2001 From: Matthias Ronge Date: Thu, 30 Mar 2023 14:32:06 +0200 Subject: [PATCH 07/72] Add javadoc --- .../dataeditor/ruleset/xml/Setting.java | 30 ++++++++++++++----- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/xml/Setting.java b/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/xml/Setting.java index 4a325e22ceb..3d2874c7177 100644 --- a/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/xml/Setting.java +++ b/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/xml/Setting.java @@ -142,6 +142,17 @@ public Boolean getMultiline() { return multiline; } + /** + * Returns the value “reimport” if one is set. This getter returns + * {@code null} if the attribute was not entered. This is needed, for + * example, when merging attributes. + * + * @return the value “excluded”, if set, else {@code null} + */ + public Reimport getReimport() { + return reimport; + } + /** * Returns the editor settings. * @@ -245,6 +256,17 @@ public void setMultiline(Boolean multiline) { this.multiline = multiline; } + /** + * This sets the “reimport” value. If you set the value to {@code null}, no + * attribute is written. + * + * @param reimport + * “reimport” value to set + */ + public void setReimport(Reimport reimport) { + this.reimport = reimport; + } + /** * Sets the settings for nested keys. * @@ -254,12 +276,4 @@ public void setMultiline(Boolean multiline) { public void setSettings(List settings) { this.settings = settings; } - - public Reimport getReimport() { - return reimport; - } - - public void setReimport(Reimport reimport) { - this.reimport = reimport; - } } From 7214ff3d1a604a4c8c8e83a9f94851640dbdf669 Mon Sep 17 00:00:00 2001 From: Matthias Ronge Date: Thu, 30 Mar 2023 14:46:41 +0200 Subject: [PATCH 08/72] Fix checkstyle (kitodo-data-editor) --- .../org/kitodo/dataeditor/ruleset/RulesetManagement.java | 8 ++++---- .../main/java/org/kitodo/dataeditor/ruleset/Settings.java | 3 ++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/RulesetManagement.java b/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/RulesetManagement.java index 2f9d244996d..2f001d6df2e 100644 --- a/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/RulesetManagement.java +++ b/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/RulesetManagement.java @@ -18,11 +18,11 @@ import java.util.HashMap; import java.util.List; import java.util.Locale.LanguageRange; -import java.util.function.Function; import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.Set; +import java.util.function.Function; import java.util.stream.Collectors; import javax.xml.bind.JAXBException; @@ -360,13 +360,13 @@ public int updateMetadata(Collection currentMetadata, String acquisiti case ADD: currentMetadata.addAll(currentEntries); currentMetadata.addAll(updateEntries); - break; + break; case KEEP: currentMetadata.addAll(currentEntries); - break; + break; case REPLACE: currentMetadata.addAll(updateEntries.isEmpty() ? currentEntries : updateEntries); - break; + break; default: throw new IllegalStateException("complete switch"); } } diff --git a/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/Settings.java b/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/Settings.java index 150c913b138..ca285193d33 100644 --- a/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/Settings.java +++ b/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/Settings.java @@ -56,8 +56,9 @@ Reimport getReimport(String keyId) { Setting settingForKey = currentSettings.get(keyId); if (settingForKey != null) { Reimport reimport = settingForKey.getReimport(); - if (reimport != null) + if (reimport != null) { return reimport; + } } return Reimport.REPLACE; } From e31c7c21b5d8f8f1be75b28f4e36b463d9a9778b Mon Sep 17 00:00:00 2001 From: Matthias Ronge Date: Thu, 30 Mar 2023 14:57:41 +0200 Subject: [PATCH 09/72] Fix checkstyle --- .../forms/createprocess/MetadataImportDialog.java | 4 +++- .../createprocess/ProcessFieldedMetadata.java | 15 ++++++++++----- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/Kitodo/src/main/java/org/kitodo/production/forms/createprocess/MetadataImportDialog.java b/Kitodo/src/main/java/org/kitodo/production/forms/createprocess/MetadataImportDialog.java index b7a7c03a627..aeacaa04a2b 100644 --- a/Kitodo/src/main/java/org/kitodo/production/forms/createprocess/MetadataImportDialog.java +++ b/Kitodo/src/main/java/org/kitodo/production/forms/createprocess/MetadataImportDialog.java @@ -122,7 +122,9 @@ public List getImportConfigurations() { * @param processes * The linked list of TempProcess instances */ - void extendsMetadataTableOfMetadataTab(LinkedList processes) throws InvalidMetadataValueException, NoSuchMetadataFieldException { + void extendsMetadataTableOfMetadataTab(LinkedList processes) + throws InvalidMetadataValueException, NoSuchMetadataFieldException { + int countOfAddedMetadata = 0; if (processes.size() > 0) { TempProcess process = processes.getFirst(); diff --git a/Kitodo/src/main/java/org/kitodo/production/forms/createprocess/ProcessFieldedMetadata.java b/Kitodo/src/main/java/org/kitodo/production/forms/createprocess/ProcessFieldedMetadata.java index 6d59a6a096c..4d6522a5e37 100644 --- a/Kitodo/src/main/java/org/kitodo/production/forms/createprocess/ProcessFieldedMetadata.java +++ b/Kitodo/src/main/java/org/kitodo/production/forms/createprocess/ProcessFieldedMetadata.java @@ -116,16 +116,19 @@ public ProcessFieldedMetadata() { } /** - * Creates a new root metadata group representing the metadata table - * content in the processMetadata. + * Creates a new root metadata group representing the metadata table content + * in the processMetadata. * * @param structure * structure selected by the user * @param divisionView * information about that structure from the rule set - * @param rulesetManagementInterface + * @param rulesetService + * the ruleset used for displaying */ - public ProcessFieldedMetadata(Division structure, StructuralElementViewInterface divisionView, RulesetManagementInterface rulesetService) { + public ProcessFieldedMetadata(Division structure, StructuralElementViewInterface divisionView, + RulesetManagementInterface rulesetService) { + this(null, structure, divisionView, null, null, structure.getMetadata()); this.rulesetService = rulesetService; buildTreeNodeAndCreateMetadataTable(); @@ -138,7 +141,9 @@ public ProcessFieldedMetadata(Division structure, StructuralElementViewInterf * metadata to add if not exist * @return returns count of added metadata */ - public int addMetadataIfNotExists(Collection potentialMetadataItems) throws InvalidMetadataValueException, NoSuchMetadataFieldException { + public int addMetadataIfNotExists(Collection potentialMetadataItems) + throws InvalidMetadataValueException, NoSuchMetadataFieldException { + preserve(); int count = rulesetService.updateMetadata(metadata, "create", potentialMetadataItems); buildTreeNodeAndCreateMetadataTable(); From 418dc62caada6e0b43a7bb848e4b9c53abe198f4 Mon Sep 17 00:00:00 2001 From: Matthias Ronge Date: Fri, 31 Mar 2023 09:15:38 +0200 Subject: [PATCH 10/72] Explain use on ruleset subhh.xml --- Kitodo/rulesets/subhh.xml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/Kitodo/rulesets/subhh.xml b/Kitodo/rulesets/subhh.xml index 154bdd4c551..260f855c042 100644 --- a/Kitodo/rulesets/subhh.xml +++ b/Kitodo/rulesets/subhh.xml @@ -1170,6 +1170,25 @@ selection list is displayed, otherwise a multi-line text field. + - optional attribute 'reimport': + Defines the behaviour on repeated imports. Defaults to + 'replace'. Possible values: + + add Add the additionally imported + metadata to the existing ones. + + keep Only import a new value if there + isn’t an existing value. If there + is, keep the existing value(s) and + doesn’t change it. + + replace Remove any existing values, and + replace them with the newly + imported values. + + Note that 'reimport' settings only affect the top level + metadata and have no effect on sub-keys. + - optional member tag: setting (optional, repeatable) To define settings on sub-keys of @@ -1180,6 +1199,8 @@ --> + + From 0d7371bf0d98d7426755d6d6106b0b80cc8a15cd Mon Sep 17 00:00:00 2001 From: Matthias Ronge Date: Fri, 31 Mar 2023 09:24:41 +0200 Subject: [PATCH 11/72] Fix Codacy complains --- Kitodo/rulesets/subhh.xml | 6 ++++-- .../org/kitodo/production/process/ProcessValidatorIT.java | 3 ++- .../org/kitodo/production/process/TitleGeneratorTest.java | 3 ++- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/Kitodo/rulesets/subhh.xml b/Kitodo/rulesets/subhh.xml index 260f855c042..7eb5ce2694d 100644 --- a/Kitodo/rulesets/subhh.xml +++ b/Kitodo/rulesets/subhh.xml @@ -1197,10 +1197,12 @@ At least one of the optional attributes should be assigned or at least one child setting tag should be present. --> - + + + diff --git a/Kitodo/src/test/java/org/kitodo/production/process/ProcessValidatorIT.java b/Kitodo/src/test/java/org/kitodo/production/process/ProcessValidatorIT.java index 55557a6a5b1..c114f30d2b2 100644 --- a/Kitodo/src/test/java/org/kitodo/production/process/ProcessValidatorIT.java +++ b/Kitodo/src/test/java/org/kitodo/production/process/ProcessValidatorIT.java @@ -114,7 +114,8 @@ private List createProcessDetailsList() throws IOException { rulesetManagementInterface.load(new File("src/test/resources/rulesets/monograph.xml")); StructuralElementViewInterface monograph = rulesetManagementInterface.getStructuralElementView( "Monograph", "", Locale.LanguageRange.parse("en")); - ProcessFieldedMetadata processDetails = new ProcessFieldedMetadata(workpiece.getLogicalStructure(), monograph, rulesetManagementInterface); + ProcessFieldedMetadata processDetails = new ProcessFieldedMetadata(workpiece.getLogicalStructure(), monograph, + rulesetManagementInterface); for (ProcessDetail detail : processDetails.getRows()) { switch (detail.getMetadataID()) { case "TitleDocMain": diff --git a/Kitodo/src/test/java/org/kitodo/production/process/TitleGeneratorTest.java b/Kitodo/src/test/java/org/kitodo/production/process/TitleGeneratorTest.java index f678b3b4146..c0257f7d82c 100644 --- a/Kitodo/src/test/java/org/kitodo/production/process/TitleGeneratorTest.java +++ b/Kitodo/src/test/java/org/kitodo/production/process/TitleGeneratorTest.java @@ -106,7 +106,8 @@ static List createProcessDetailsList() throws IOException { rulesetManagementInterface.load(new File("src/test/resources/rulesets/monograph.xml")); StructuralElementViewInterface monograph = rulesetManagementInterface.getStructuralElementView( "Monograph", "", Locale.LanguageRange.parse("en")); - ProcessFieldedMetadata processDetails = new ProcessFieldedMetadata(workpiece.getLogicalStructure(), monograph, rulesetManagementInterface); + ProcessFieldedMetadata processDetails = new ProcessFieldedMetadata(workpiece.getLogicalStructure(), monograph, + rulesetManagementInterface); for (ProcessDetail detail : processDetails.getRows()) { switch (detail.getMetadataID()) { case "TitleDocMain": From 92e39388a4ecf4f6d442d6ffe2b901ffcd36464a Mon Sep 17 00:00:00 2001 From: Matthias Ronge Date: Tue, 11 Apr 2023 14:29:47 +0200 Subject: [PATCH 12/72] Use wrong use of Objects.nonNull() to check for null values Cf. https://github.com/kitodo/kitodo-production/issues/4087 --- .../main/java/org/kitodo/dataeditor/ruleset/Settings.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/Settings.java b/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/Settings.java index ca285193d33..461682863b2 100644 --- a/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/Settings.java +++ b/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/Settings.java @@ -17,6 +17,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.function.Function; import java.util.stream.Collectors; @@ -54,9 +55,9 @@ public Settings(Collection baseSettings) { */ Reimport getReimport(String keyId) { Setting settingForKey = currentSettings.get(keyId); - if (settingForKey != null) { + if (Objects.nonNull(settingForKey)) { Reimport reimport = settingForKey.getReimport(); - if (reimport != null) { + if (Objects.nonNull(reimport)) { return reimport; } } From e66b31e3467ce54b77436d7eb290b0cf04dabe0f Mon Sep 17 00:00:00 2001 From: Matthias Ronge Date: Tue, 11 Apr 2023 14:38:07 +0200 Subject: [PATCH 13/72] Use an other error message If someone get this message as he use a non valid entry it would be very difficult to find the right place and the causing issue. Maybe something like that "Used not supported reimport case {}" where{} is replaced by the wrong value can make it easier for him. --- .../java/org/kitodo/dataeditor/ruleset/RulesetManagement.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/RulesetManagement.java b/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/RulesetManagement.java index 2f001d6df2e..6bc9e582088 100644 --- a/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/RulesetManagement.java +++ b/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/RulesetManagement.java @@ -367,7 +367,9 @@ public int updateMetadata(Collection currentMetadata, String acquisiti case REPLACE: currentMetadata.addAll(updateEntries.isEmpty() ? currentEntries : updateEntries); break; - default: throw new IllegalStateException("complete switch"); + default: + throw new IllegalStateException( + "Used not supported reimport case {}".replace("{}", metadata.getMiddle().toString())); } } return currentMetadata.size() - sizeBefore; From b83c520bc7629f96be4e98fbeeafd5e3d52c7fa3 Mon Sep 17 00:00:00 2001 From: Matthias Ronge Date: Tue, 11 Apr 2023 17:07:45 +0200 Subject: [PATCH 14/72] Replace 'var' typing with explicit type naming --- .../java/org/kitodo/dataeditor/ruleset/RulesetManagement.java | 2 +- .../src/main/java/org/kitodo/docket/ExportXmlLog.java | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/RulesetManagement.java b/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/RulesetManagement.java index 6bc9e582088..63673813c5c 100644 --- a/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/RulesetManagement.java +++ b/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/RulesetManagement.java @@ -331,7 +331,7 @@ public int updateMetadata(Collection currentMetadata, String acquisiti Collection updateMetadata) { final Function, Reimport, Collection>> entryProducer = key -> { - var entry = new MutableTriple, Reimport, Collection>(); + MutableTriple, Reimport, Collection> entry = new MutableTriple<>(); entry.setLeft(new ArrayList<>()); entry.setRight(new ArrayList<>()); return entry; diff --git a/Kitodo-Docket/src/main/java/org/kitodo/docket/ExportXmlLog.java b/Kitodo-Docket/src/main/java/org/kitodo/docket/ExportXmlLog.java index 12749bfa3ea..735ce9695d7 100644 --- a/Kitodo-Docket/src/main/java/org/kitodo/docket/ExportXmlLog.java +++ b/Kitodo-Docket/src/main/java/org/kitodo/docket/ExportXmlLog.java @@ -20,6 +20,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -350,7 +351,7 @@ private List createMetadataElements(Namespace xmlns, DocketData docketD HashMap names = getNamespacesFromConfig(); Namespace[] namespaces = new Namespace[names.size()]; int index = 0; - for (var entries = names.entrySet().iterator(); entries.hasNext(); index++) { + for (Iterator> entries = names.entrySet().iterator(); entries.hasNext(); index++) { Entry entry = entries.next(); namespaces[index] = Namespace.getNamespace(entry.getKey(), entry.getValue()); } From eb12937d0b5f246ad18d739fabb7b3cc7d193cf3 Mon Sep 17 00:00:00 2001 From: Matthias Ronge Date: Wed, 19 Apr 2023 15:11:23 +0200 Subject: [PATCH 15/72] Add an explaination that 'replace' does not delete not-imported metadata --- Kitodo/rulesets/ruleset.xsd | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Kitodo/rulesets/ruleset.xsd b/Kitodo/rulesets/ruleset.xsd index fa6c923eddf..1105604adc0 100644 --- a/Kitodo/rulesets/ruleset.xsd +++ b/Kitodo/rulesets/ruleset.xsd @@ -273,8 +273,12 @@ The attribute "reimport" indicates how the metadata entry should behave when imported repeatedly: + 'add' adds the newly imported metadata entry to the existing entries. + 'replace' replaces an existing metadata entry with the new value. (This is the default case.) + Note that metadata, for which there is no value, is kept and not deleted. + 'keep' keeps the first existing value and discards the additionally imported value. From 23b24f8da45cef4f49833c2f4840b1f95c07370a Mon Sep 17 00:00:00 2001 From: Matthias Ronge Date: Thu, 13 Apr 2023 12:18:51 +0200 Subject: [PATCH 16/72] Write process title to allowed metadata keys set so in the ruleset --- .../src/test/resources/ruleset.xsd | 17 ++++++++-- Kitodo/rulesets/ruleset.xsd | 6 ++-- .../createprocess/CreateProcessForm.java | 31 +++++++++++++++++-- .../production/metadata/MetadataEditor.java | 2 +- 4 files changed, 48 insertions(+), 8 deletions(-) diff --git a/Kitodo-DataEditor/src/test/resources/ruleset.xsd b/Kitodo-DataEditor/src/test/resources/ruleset.xsd index b102eb5eba7..4547a016b0b 100644 --- a/Kitodo-DataEditor/src/test/resources/ruleset.xsd +++ b/Kitodo-DataEditor/src/test/resources/ruleset.xsd @@ -49,9 +49,13 @@ URI; if the type is specified, this applies. If a namespace has been specified, Production looks for an XML file in the same directory whose file name is the same as the last segment of the namespace URI and, if it finds it, makes the namespace elements available as a selection list. + + The attribute "minDigits" can be used with type="integer" to define a minimum number of digits, which + will save the value with leading zeroes, if it has less digits. + @@ -297,7 +301,8 @@ A <ruleset> technically describes the description of digital objects in structure and the assignment of metadata. The assumed default language of <label>s without the "lang" attribute is - English, unless another language is specified as default with the "lang" attribute here. Section + English, unless another language is specified as default with the "lang" attribute here. + <include>s allow to preload embedded ruleset files. Section <declaration> defines the possible <division>s and metadata <key>s. In section <restriction>, the possible combinations of the former can be restricted. In section <editing>, settings for displaying the input fields in the metadata editor can be made. @@ -305,6 +310,7 @@ + @@ -420,15 +426,19 @@ 'authorLastName' The value is used as the author's last name to form the author-title key. + 'childCount' will set the (1-based) child number, when creating child documents. + 'dataSource' Internal identifier of the data source in order to be able to update the imported metadata entries from the data source later. 'displaySummary' will be displayed as summary on the Title Record Link tab when creating a new process. + 'docType' During import, the type of the logical root of the document is set from this metadata value. + 'higherlevelIdentifier' must be available when fetching a data record from a data source in order to fetch a higher-level data record as well. - 'processTitle' The generated author-title key is written in this field. + 'processTitle' The process title is written in this field. 'recordIdentifier' Identifier of the data record fetched from an external data source, so that the imported metadata entries from the data source can be updated later. @@ -442,13 +452,14 @@ + + - diff --git a/Kitodo/rulesets/ruleset.xsd b/Kitodo/rulesets/ruleset.xsd index 173239dccf7..4547a016b0b 100644 --- a/Kitodo/rulesets/ruleset.xsd +++ b/Kitodo/rulesets/ruleset.xsd @@ -433,10 +433,12 @@ 'displaySummary' will be displayed as summary on the Title Record Link tab when creating a new process. + 'docType' During import, the type of the logical root of the document is set from this metadata value. + 'higherlevelIdentifier' must be available when fetching a data record from a data source in order to fetch a higher-level data record as well. - 'processTitle' The generated author-title key is written in this field. + 'processTitle' The process title is written in this field. 'recordIdentifier' Identifier of the data record fetched from an external data source, so that the imported metadata entries from the data source can be updated later. @@ -453,11 +455,11 @@ + - diff --git a/Kitodo/src/main/java/org/kitodo/production/forms/createprocess/CreateProcessForm.java b/Kitodo/src/main/java/org/kitodo/production/forms/createprocess/CreateProcessForm.java index bc6912770da..b4b0880185c 100644 --- a/Kitodo/src/main/java/org/kitodo/production/forms/createprocess/CreateProcessForm.java +++ b/Kitodo/src/main/java/org/kitodo/production/forms/createprocess/CreateProcessForm.java @@ -35,8 +35,11 @@ import org.apache.logging.log4j.Logger; import org.kitodo.api.MetadataEntry; import org.kitodo.api.dataeditor.rulesetmanagement.FunctionalMetadata; +import org.kitodo.api.dataeditor.rulesetmanagement.MetadataViewInterface; import org.kitodo.api.dataeditor.rulesetmanagement.RulesetManagementInterface; +import org.kitodo.api.dataeditor.rulesetmanagement.SimpleMetadataViewInterface; import org.kitodo.api.dataeditor.rulesetmanagement.StructuralElementViewInterface; +import org.kitodo.api.dataformat.Division; import org.kitodo.api.dataformat.LogicalDivision; import org.kitodo.api.dataformat.Workpiece; import org.kitodo.api.externaldatamanagement.ImportConfigurationType; @@ -632,13 +635,37 @@ private void saveProcessHierarchyMetadata() { private void saveTempProcessMetadata(TempProcess tempProcess) { try (OutputStream out = ServiceManager.getFileService() .write(ServiceManager.getProcessService().getMetadataFileUri(tempProcess.getProcess()))) { - tempProcess.getWorkpiece().setId(tempProcess.getProcess().getId().toString()); - ServiceManager.getMetsService().save(tempProcess.getWorkpiece(), out); + Workpiece workpiece = tempProcess.getWorkpiece(); + workpiece.setId(tempProcess.getProcess().getId().toString()); + setProcessTitleMetadata(workpiece); + ServiceManager.getMetsService().save(workpiece, out); } catch (IOException e) { Helper.setErrorMessage(e.getLocalizedMessage(), logger, e); } } + private void setProcessTitleMetadata(Workpiece workpiece) { + String processTitle = currentProcess.getProcess().getTitle(); + Collection keysForProcessTitle = rulesetManagement.getFunctionalKeys(FunctionalMetadata.PROCESS_TITLE); + addAddableMetadataRecursive(workpiece.getLogicalStructure(), keysForProcessTitle, processTitle); + addAddableMetadataRecursive(workpiece.getPhysicalStructure(), keysForProcessTitle, processTitle); + } + + private void addAddableMetadataRecursive(Division division, Collection keys, String value) { + StructuralElementViewInterface divisionView = rulesetManagement.getStructuralElementView(division.getType(), + acquisitionStage, priorityList); + for (MetadataViewInterface addableMetadataView : divisionView.getAddableMetadata(division.getMetadata(), + Collections.emptyList())) { + if (addableMetadataView instanceof SimpleMetadataViewInterface + && keys.contains(addableMetadataView.getId())) { + MetadataEditor.writeMetadataEntry(division, (SimpleMetadataViewInterface) addableMetadataView, value); + } + } + for (Division child : division.getChildren()) { + addAddableMetadataRecursive(child, keys, value); + } + } + private boolean createProcessesLocation(List processes) { for (TempProcess tempProcess : processes) { if (processes.indexOf(tempProcess) > 0 && Objects.isNull(tempProcess.getMetadataNodes())) { diff --git a/Kitodo/src/main/java/org/kitodo/production/metadata/MetadataEditor.java b/Kitodo/src/main/java/org/kitodo/production/metadata/MetadataEditor.java index 2350339b1e2..3fef6be5c9d 100644 --- a/Kitodo/src/main/java/org/kitodo/production/metadata/MetadataEditor.java +++ b/Kitodo/src/main/java/org/kitodo/production/metadata/MetadataEditor.java @@ -672,7 +672,7 @@ public static void removeAllMetadata(LogicalDivision logicalDivision, String key * and the value is different from either {@code label} or * {@code orderlabel}. */ - public static void writeMetadataEntry(LogicalDivision division, + public static void writeMetadataEntry(Division division, SimpleMetadataViewInterface simpleMetadataView, String value) { Domain domain = simpleMetadataView.getDomain().orElse(Domain.DESCRIPTION); From 2379455a09ede85e2ae9c1683bcb83884cdcadc9 Mon Sep 17 00:00:00 2001 From: Matthias Ronge Date: Wed, 19 Apr 2023 15:53:29 +0200 Subject: [PATCH 17/72] Fix a null-pointer exception if process is created without ruleset --- .../forms/createprocess/CreateProcessForm.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/Kitodo/src/main/java/org/kitodo/production/forms/createprocess/CreateProcessForm.java b/Kitodo/src/main/java/org/kitodo/production/forms/createprocess/CreateProcessForm.java index b4b0880185c..9a741e86728 100644 --- a/Kitodo/src/main/java/org/kitodo/production/forms/createprocess/CreateProcessForm.java +++ b/Kitodo/src/main/java/org/kitodo/production/forms/createprocess/CreateProcessForm.java @@ -637,7 +637,9 @@ private void saveTempProcessMetadata(TempProcess tempProcess) { .write(ServiceManager.getProcessService().getMetadataFileUri(tempProcess.getProcess()))) { Workpiece workpiece = tempProcess.getWorkpiece(); workpiece.setId(tempProcess.getProcess().getId().toString()); - setProcessTitleMetadata(workpiece); + if (Objects.nonNull(rulesetManagement)) { + setProcessTitleMetadata(workpiece); + } ServiceManager.getMetsService().save(workpiece, out); } catch (IOException e) { Helper.setErrorMessage(e.getLocalizedMessage(), logger, e); @@ -645,10 +647,12 @@ private void saveTempProcessMetadata(TempProcess tempProcess) { } private void setProcessTitleMetadata(Workpiece workpiece) { - String processTitle = currentProcess.getProcess().getTitle(); Collection keysForProcessTitle = rulesetManagement.getFunctionalKeys(FunctionalMetadata.PROCESS_TITLE); - addAddableMetadataRecursive(workpiece.getLogicalStructure(), keysForProcessTitle, processTitle); - addAddableMetadataRecursive(workpiece.getPhysicalStructure(), keysForProcessTitle, processTitle); + if (!keysForProcessTitle.isEmpty()) { + String processTitle = currentProcess.getProcess().getTitle(); + addAddableMetadataRecursive(workpiece.getLogicalStructure(), keysForProcessTitle, processTitle); + addAddableMetadataRecursive(workpiece.getPhysicalStructure(), keysForProcessTitle, processTitle); + } } private void addAddableMetadataRecursive(Division division, Collection keys, String value) { From 9cfe1181610db9736b9284e7064c0aaa2b526171 Mon Sep 17 00:00:00 2001 From: Arved Solth Date: Mon, 22 May 2023 14:33:29 +0200 Subject: [PATCH 18/72] Do not reset form data on changing ldap group on user edit page --- .../webapp/WEB-INF/templates/includes/userEdit/details.xhtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Kitodo/src/main/webapp/WEB-INF/templates/includes/userEdit/details.xhtml b/Kitodo/src/main/webapp/WEB-INF/templates/includes/userEdit/details.xhtml index 31cfcffa27a..74fc4e4b8a4 100644 --- a/Kitodo/src/main/webapp/WEB-INF/templates/includes/userEdit/details.xhtml +++ b/Kitodo/src/main/webapp/WEB-INF/templates/includes/userEdit/details.xhtml @@ -144,7 +144,7 @@ - +
From 6af03c4a586ad4883698b25d5406f6402d9443ea Mon Sep 17 00:00:00 2001 From: Matthias Ronge Date: Wed, 24 May 2023 15:24:11 +0200 Subject: [PATCH 19/72] Split long method --- .../dataeditor/ruleset/RulesetManagement.java | 45 +++++++++++-------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/RulesetManagement.java b/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/RulesetManagement.java index 63673813c5c..9da9d28d146 100644 --- a/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/RulesetManagement.java +++ b/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/RulesetManagement.java @@ -330,25 +330,8 @@ public boolean isAlwaysShowingForKey(String keyId) { public int updateMetadata(Collection currentMetadata, String acquisitionStage, Collection updateMetadata) { - final Function, Reimport, Collection>> entryProducer = key -> { - MutableTriple, Reimport, Collection> entry = new MutableTriple<>(); - entry.setLeft(new ArrayList<>()); - entry.setRight(new ArrayList<>()); - return entry; - }; - - HashMap, Reimport, Collection>> unifying = new HashMap<>(); - for (Metadata metadata : currentMetadata) { - unifying.computeIfAbsent(metadata.getKey(), entryProducer).getLeft().add(metadata); - } - for (Metadata metadata : updateMetadata) { - unifying.computeIfAbsent(metadata.getKey(), entryProducer).getRight().add(metadata); - } - Settings settings = ruleset.getSettings(acquisitionStage); - for (var entry : unifying.entrySet()) { - entry.getValue().setMiddle(settings.getReimport(entry.getKey())); - } - + HashMap, Reimport, Collection>> unifying = unifyMetadataByKey( + currentMetadata, acquisitionStage, updateMetadata); int sizeBefore = currentMetadata.size(); currentMetadata.clear(); for (var entry : unifying.entrySet()) { @@ -374,4 +357,28 @@ public int updateMetadata(Collection currentMetadata, String acquisiti } return currentMetadata.size() - sizeBefore; } + + private HashMap, Reimport, Collection>> unifyMetadataByKey( + Collection currentMetadata, String acquisitionStage, Collection updateMetadata) { + + final Function, Reimport, Collection>> entryProducer = key -> { + MutableTriple, Reimport, Collection> entry = new MutableTriple<>(); + entry.setLeft(new ArrayList<>()); + entry.setRight(new ArrayList<>()); + return entry; + }; + + HashMap, Reimport, Collection>> unifying = new HashMap<>(); + for (Metadata metadata : currentMetadata) { + unifying.computeIfAbsent(metadata.getKey(), entryProducer).getLeft().add(metadata); + } + for (Metadata metadata : updateMetadata) { + unifying.computeIfAbsent(metadata.getKey(), entryProducer).getRight().add(metadata); + } + Settings settings = ruleset.getSettings(acquisitionStage); + for (var entry : unifying.entrySet()) { + entry.getValue().setMiddle(settings.getReimport(entry.getKey())); + } + return unifying; + } } From 63b349ae43fccbda475e623e2d3a82c6f4e19270 Mon Sep 17 00:00:00 2001 From: Henning Gerhardt Date: Tue, 16 May 2023 11:51:38 +0200 Subject: [PATCH 20/72] Split big method into smaller pieces --- Kitodo/pom.xml | 2 +- .../production/security/SecurityConfig.java | 229 ++++++++++++------ 2 files changed, 157 insertions(+), 74 deletions(-) diff --git a/Kitodo/pom.xml b/Kitodo/pom.xml index e2dc36427a4..8419108e04f 100644 --- a/Kitodo/pom.xml +++ b/Kitodo/pom.xml @@ -27,7 +27,7 @@ ${project.parent.basedir} - 4 + 3 1.9.7 Production 604800000 diff --git a/Kitodo/src/main/java/org/kitodo/production/security/SecurityConfig.java b/Kitodo/src/main/java/org/kitodo/production/security/SecurityConfig.java index 8a597c2f930..7c5e34e0520 100644 --- a/Kitodo/src/main/java/org/kitodo/production/security/SecurityConfig.java +++ b/Kitodo/src/main/java/org/kitodo/production/security/SecurityConfig.java @@ -99,99 +99,182 @@ protected void configure(HttpSecurity http) throws Exception { http.sessionManagement().maximumSessions(1).sessionRegistry(getSessionRegistry()) .expiredUrl(LOGIN_PAGE); - // viewAll... Authority to view list of entities - // view...... Authority to view entity at edit page - // edit...... Authority to change and save entities at edit page - http.authorizeRequests() - .antMatchers("/pages/clientEdit.jsf*").hasAnyAuthority( - EDIT_CLIENT + GLOBAL, - EDIT_CLIENT + CLIENT_ANY, - VIEW_CLIENT + GLOBAL, - VIEW_CLIENT + CLIENT_ANY) + // site specific rules + authorizeSpecificPages(http); - .antMatchers("/pages/indexingPage.jsf").hasAnyAuthority( - "editIndex_" + GLOBAL, - "viewIndex_" + GLOBAL) + // more general rules should be at end + authorizeGeneralPages(http); - .antMatchers("/pages/processes.jsf").hasAnyAuthority( - VIEW_ALL_PROCESSES + GLOBAL, - VIEW_ALL_PROCESSES + CLIENT_ANY) - .antMatchers("/pages/processEdit.jsf*").hasAnyAuthority( - EDIT_PROCESS + GLOBAL, - EDIT_PROCESS + CLIENT_ANY, - VIEW_PROCESS + GLOBAL, - VIEW_PROCESS + CLIENT_ANY) + http.addFilterAfter(new SecurityObjectAccessFilter(), FilterSecurityInterceptor.class); - .antMatchers("/pages/projects.jsf").hasAnyAuthority( - VIEW_ALL_PROJECTS + GLOBAL, - VIEW_ALL_PROJECTS + CLIENT_ANY, - VIEW_ALL_TEMPLATES + GLOBAL, - VIEW_ALL_TEMPLATES + CLIENT_ANY, - VIEW_ALL_DOCKETS + GLOBAL, - VIEW_ALL_DOCKETS + CLIENT_ANY, - VIEW_ALL_RULESETS + GLOBAL, - VIEW_ALL_RULESETS + CLIENT_ANY, - VIEW_ALL_WORKFLOWS + GLOBAL) - .antMatchers("/pages/projectEdit.jsf*").hasAnyAuthority( - EDIT_PROJECT + GLOBAL, - EDIT_PROJECT + CLIENT_ANY, - VIEW_PROJECT + GLOBAL, - VIEW_PROJECT + CLIENT_ANY) + handleFormLogin(http); + } - .antMatchers("/pages/templateEdit.jsf*").hasAnyAuthority( - EDIT_TEMPLATE + GLOBAL, - EDIT_TEMPLATE + CLIENT_ANY, - VIEW_TEMPLATE + GLOBAL, - VIEW_TEMPLATE + CLIENT_ANY) + private void authorizeSpecificPages(HttpSecurity http) throws Exception { + authorizePageClientEdit(http); - .antMatchers("/pages/docketEdit.jsf*").hasAnyAuthority( - EDIT_DOCKET + GLOBAL, - EDIT_DOCKET + CLIENT_ANY, - VIEW_DOCKET + GLOBAL, - VIEW_DOCKET + CLIENT_ANY) + authorizePageIndexing(http); - .antMatchers("/pages/rulesetEdit.jsf*").hasAnyAuthority( - EDIT_RULESET + GLOBAL, - EDIT_RULESET + CLIENT_ANY, - VIEW_RULESET + GLOBAL, - VIEW_RULESET + CLIENT_ANY) + authorizePageProcesses(http); - .antMatchers("/pages/workflowEdit.jsf*").hasAnyAuthority( - EDIT_WORKFLOW + GLOBAL, - EDIT_WORKFLOW + CLIENT_ANY, - VIEW_WORKFLOW + GLOBAL, - VIEW_WORKFLOW + CLIENT_ANY) + authorizePageProcessEdit(http); - .antMatchers("/pages/tasks.jsf").hasAnyAuthority( - VIEW_ALL_TASKS + GLOBAL, - VIEW_ALL_TASKS + CLIENT_ANY) + authorizePageProjects(http); + + authorizePageProjectEdit(http); + + authorizePageTemplateEdit(http); + + authorizePageDocketEdit(http); + + authorizePageRulesetEdit(http); + + authorizePageWorkflowEdit(http); + + authorizePageTasks(http); + + authorizePageUsers(http); + + authorizePageRoleEdit(http); + + authorizePageLdapGroupEdit(http); + } + + private void authorizeGeneralPages(HttpSecurity http) throws Exception { + http.authorizeRequests() + .antMatchers("/pages/images/**").permitAll() + .antMatchers("/javax.faces.resource/**", "**/resources/**").permitAll() + .antMatchers("/js/modeler.js").permitAll() + .antMatchers("/js/toggle.js").permitAll() + .anyRequest().authenticated(); + } + + private void authorizePageLdapGroupEdit(HttpSecurity http) throws Exception { + http.authorizeRequests() + .antMatchers("/pages/ldapgroupEdit.jsf*").hasAnyAuthority( + "editLdapGroup_" + GLOBAL, + "viewLdapGroup_" + GLOBAL); + } + + private void authorizePageRoleEdit(HttpSecurity http) throws Exception { + http.authorizeRequests() + .antMatchers("/pages/roleEdit.jsf*").hasAnyAuthority( + EDIT_ROLE + GLOBAL, + EDIT_ROLE + CLIENT_ANY, + VIEW_ROLE + GLOBAL, + VIEW_ROLE + CLIENT_ANY); + } + private void authorizePageUsers(HttpSecurity http) throws Exception { + http.authorizeRequests() .antMatchers("/pages/users.jsf").hasAnyAuthority( VIEW_ALL_USERS + GLOBAL, VIEW_ALL_USERS + CLIENT_ANY, VIEW_ALL_ROLES + GLOBAL, VIEW_ALL_ROLES + CLIENT_ANY, "viewAllClients_" + GLOBAL, - "viewAllLdapGroups_" + GLOBAL) + "viewAllLdapGroups_" + GLOBAL); + } - .antMatchers("/pages/roleEdit.jsf*").hasAnyAuthority( - EDIT_ROLE + GLOBAL, - EDIT_ROLE + CLIENT_ANY, - VIEW_ROLE + GLOBAL, - VIEW_ROLE + CLIENT_ANY) + private void authorizePageTasks(HttpSecurity http) throws Exception { + http.authorizeRequests() + .antMatchers("/pages/tasks.jsf").hasAnyAuthority( + VIEW_ALL_TASKS + GLOBAL, + VIEW_ALL_TASKS + CLIENT_ANY); + } - .antMatchers("/pages/ldapgroupEdit.jsf*").hasAnyAuthority( - "editLdapGroup_" + GLOBAL, - "viewLdapGroup_" + GLOBAL) + private void authorizePageWorkflowEdit(HttpSecurity http) throws Exception { + http.authorizeRequests() + .antMatchers("/pages/workflowEdit.jsf*").hasAnyAuthority( + EDIT_WORKFLOW + GLOBAL, + EDIT_WORKFLOW + CLIENT_ANY, + VIEW_WORKFLOW + GLOBAL, + VIEW_WORKFLOW + CLIENT_ANY); + } - .antMatchers("/pages/images/**").permitAll() - .antMatchers("/javax.faces.resource/**", "**/resources/**").permitAll() - .antMatchers("/js/modeler.js").permitAll() - .antMatchers("/js/toggle.js").permitAll() - .anyRequest().authenticated(); + private void authorizePageRulesetEdit(HttpSecurity http) throws Exception { + http.authorizeRequests() + .antMatchers("/pages/rulesetEdit.jsf*").hasAnyAuthority( + EDIT_RULESET + GLOBAL, + EDIT_RULESET + CLIENT_ANY, + VIEW_RULESET + GLOBAL, + VIEW_RULESET + CLIENT_ANY); + } - http.addFilterAfter(new SecurityObjectAccessFilter(), FilterSecurityInterceptor.class); + private void authorizePageDocketEdit(HttpSecurity http) throws Exception { + http.authorizeRequests() + .antMatchers("/pages/docketEdit.jsf*").hasAnyAuthority( + EDIT_DOCKET + GLOBAL, + EDIT_DOCKET + CLIENT_ANY, + VIEW_DOCKET + GLOBAL, + VIEW_DOCKET + CLIENT_ANY); + } + + private void authorizePageTemplateEdit(HttpSecurity http) throws Exception { + http.authorizeRequests() + .antMatchers("/pages/templateEdit.jsf*").hasAnyAuthority( + EDIT_TEMPLATE + GLOBAL, + EDIT_TEMPLATE + CLIENT_ANY, + VIEW_TEMPLATE + GLOBAL, + VIEW_TEMPLATE + CLIENT_ANY); + } + + private void authorizePageProjectEdit(HttpSecurity http) throws Exception { + http.authorizeRequests() + .antMatchers("/pages/projectEdit.jsf*").hasAnyAuthority( + EDIT_PROJECT + GLOBAL, + EDIT_PROJECT + CLIENT_ANY, + VIEW_PROJECT + GLOBAL, + VIEW_PROJECT + CLIENT_ANY); + } + + private void authorizePageProjects(HttpSecurity http) throws Exception { + http.authorizeRequests() + .antMatchers("/pages/projects.jsf").hasAnyAuthority( + VIEW_ALL_PROJECTS + GLOBAL, + VIEW_ALL_PROJECTS + CLIENT_ANY, + VIEW_ALL_TEMPLATES + GLOBAL, + VIEW_ALL_TEMPLATES + CLIENT_ANY, + VIEW_ALL_DOCKETS + GLOBAL, + VIEW_ALL_DOCKETS + CLIENT_ANY, + VIEW_ALL_RULESETS + GLOBAL, + VIEW_ALL_RULESETS + CLIENT_ANY, + VIEW_ALL_WORKFLOWS + GLOBAL); + } + + private void authorizePageProcessEdit(HttpSecurity http) throws Exception { + http.authorizeRequests() + .antMatchers("/pages/processEdit.jsf*").hasAnyAuthority( + EDIT_PROCESS + GLOBAL, + EDIT_PROCESS + CLIENT_ANY, + VIEW_PROCESS + GLOBAL, + VIEW_PROCESS + CLIENT_ANY); + } + + private void authorizePageProcesses(HttpSecurity http) throws Exception { + http.authorizeRequests() + .antMatchers("/pages/processes.jsf").hasAnyAuthority( + VIEW_ALL_PROCESSES + GLOBAL, + VIEW_ALL_PROCESSES + CLIENT_ANY); + } + + private void authorizePageIndexing(HttpSecurity http) throws Exception { + http.authorizeRequests() + .antMatchers("/pages/indexingPage.jsf").hasAnyAuthority( + "editIndex_" + GLOBAL, + "viewIndex_" + GLOBAL); + } + + private void authorizePageClientEdit(HttpSecurity http) throws Exception { + http.authorizeRequests() + .antMatchers("/pages/clientEdit.jsf*").hasAnyAuthority( + EDIT_CLIENT + GLOBAL, + EDIT_CLIENT + CLIENT_ANY, + VIEW_CLIENT + GLOBAL, + VIEW_CLIENT + CLIENT_ANY); + } + private void handleFormLogin(HttpSecurity http) throws Exception { http.formLogin() .loginPage(LOGIN_PAGE) .loginProcessingUrl("/login") From ad2097fa14ebd0d9428dd92d4656581e712bbfd2 Mon Sep 17 00:00:00 2001 From: Markus Weigelt Date: Tue, 30 May 2023 15:06:51 +0200 Subject: [PATCH 21/72] Fix thumbnail scrolling --- .../resources/js/media_detail_audio.js | 254 ++++++++++++++++++ .../webapp/WEB-INF/resources/js/scroll.js | 2 +- .../metadataEditor/dialogs/pagination.xhtml | 2 +- .../includes/metadataEditor/gallery.xhtml | 2 +- .../metadataEditor/logicalStructure.xhtml | 4 +- .../metadataEditor/physicalStructure.xhtml | 4 +- 6 files changed, 261 insertions(+), 7 deletions(-) create mode 100644 Kitodo/src/main/webapp/WEB-INF/resources/js/media_detail_audio.js diff --git a/Kitodo/src/main/webapp/WEB-INF/resources/js/media_detail_audio.js b/Kitodo/src/main/webapp/WEB-INF/resources/js/media_detail_audio.js new file mode 100644 index 00000000000..049d0f7da75 --- /dev/null +++ b/Kitodo/src/main/webapp/WEB-INF/resources/js/media_detail_audio.js @@ -0,0 +1,254 @@ +/** + * (c) Kitodo. Key to digital objects e. V. + * + * This file is part of the Kitodo project. + * + * It is licensed under GNU General Public License version 3 or later. + * + * For the full copyright and license information, please read the + * GPL3-License.txt file that was distributed with this source code. + */ +/* globals ol */ +// jshint unused:false + +// Kitodo namespace +var kitodo = {}; +kitodo.map = null; + +/** + * @param {Object=} options Custom control options for Kitodo in OpenLayers + * @extends {ol.control.Rotate} + * @constructor + */ +kitodo.RotateLeftControl = function(options = {}) { + var buttonLeft = document.createElement('button'); + buttonLeft.innerHTML = ""; + buttonLeft.setAttribute("type", "button"); + buttonLeft.setAttribute("title", "Rotate left"); + + var this_ = this; + + var handleRotateLeft = function() { + var view = this_.getMap().getView(); + view.animate({ + rotation: view.getRotation() - (90 * (Math.PI / 180)), + duration: 100 + }); + }; + + buttonLeft.addEventListener('click', handleRotateLeft, false); + + var elementLeft = document.createElement('div'); + elementLeft.className = 'rotate-left ol-unselectable ol-control ol-rotate'; + elementLeft.appendChild(buttonLeft); + + ol.control.Control.call(this, { + element: elementLeft, + target: options.target + }); +}; + +/** + * @param {Object=} options Custom control options for Kitodo in OpenLayers + * @extends {ol.control.Rotate} + * @constructor + */ +kitodo.RotateRightControl = function(options = {}) { + var buttonRight = document.createElement('button'); + buttonRight.innerHTML = ""; + buttonRight.setAttribute("type", "button"); + buttonRight.setAttribute("title", "Rotate right"); + + var this_ = this; + + var handleRotateRight = function() { + var view = this_.getMap().getView(); + view.animate({ + rotation: view.getRotation() + (90 * (Math.PI / 180)), + duration: 100 + }); + }; + + buttonRight.addEventListener('click', handleRotateRight, false); + + var elementRight = document.createElement('div'); + elementRight.className = 'rotate-right ol-unselectable ol-control ol-rotate'; + elementRight.appendChild(buttonRight); + + ol.control.Control.call(this, { + element: elementRight, + target: options.target, + duration: 250 + }); +}; + +function resetNorth() { + if (kitodo.map) { + let view = kitodo.map.getView(); + view.animate({ + rotation: 0, + duration: 0 + }); + } +} + +/** + * @param {Object=} options Custom control options for Kitodo in OpenLayers + * @extends {ol.control.Rotate} + * @constructor + */ +kitodo.ResetNorthControl = function(options = {}) { + let buttonResetNorth = document.createElement("button"); + buttonResetNorth.innerHTML = ""; + buttonResetNorth.setAttribute("type", "button"); + buttonResetNorth.setAttribute("title", "Reset orientation"); + + buttonResetNorth.addEventListener("click", resetNorth, false); + + let elementResetNorth = document.createElement("div"); + elementResetNorth.className = "ol-rotate ol-unselectable ol-control"; /*ol-rotate-reset*/ + elementResetNorth.appendChild(buttonResetNorth); + + ol.control.Control.call(this, { + element: elementResetNorth, + target: options.target, + duration: 250 + }); +}; + +ol.inherits(kitodo.RotateLeftControl, ol.control.Rotate); +ol.inherits(kitodo.RotateRightControl, ol.control.Rotate); +ol.inherits(kitodo.ResetNorthControl, ol.control.Rotate); + +function random(length) { + var text = ""; + var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + + for (var i = 0; i < length; i++) { + text += possible.charAt(Math.floor(Math.random() * possible.length)); + } + + return text; +} + +function createProjection(extent) { + return new ol.proj.Projection({ + code: 'kitodo-image', + units: 'pixels', + extent: extent + }); +} + +function createSource(extent, imagePath, projection) { + return new ol.source.ImageStatic({ + url: imagePath, + projection: projection, + imageExtent: extent + }); +} + +function hideCanvas() { + let map = document.querySelector("#map canvas"); + let loadingIcon = document.querySelector("#map > .fa-spinner"); + if (map) { + map.style.opacity = 0; + loadingIcon.style.opacity = 1; + } +} + +function showCanvas() { + let map = document.querySelector("#map canvas"); + let loadingIcon = document.querySelector("#map > .fa-spinner"); + if (map) { + map.style.opacity = 1; + loadingIcon.style.opacity = 0; + } +} + +function initializeMap(imageDimensions, imagePath) { + // Map image coordinates to map coordinates to be able to use image extent in pixels. + let extent = [0, 0, imageDimensions[0], imageDimensions[1]]; + let projection = createProjection(extent); + + kitodo.map = new ol.Map({ + controls: ol.control.defaults({ + attributionOptions: { + collapsible: false + }, + zoomOptions: { + delta: 3 + }, + rotate: false + }).extend([ + new kitodo.RotateRightControl(), + new kitodo.RotateLeftControl(), + new kitodo.ResetNorthControl() + ]), + layers: [ + new ol.layer.Image({ + source: createSource(extent, imagePath, projection) + }) + ], + target: 'map', + view: new ol.View({ + projection: projection, + center: ol.extent.getCenter(extent), + zoomFactor: 1.1 + }) + }); + kitodo.map.getView().fit(extent, {}); + kitodo.map.on("rendercomplete", function () { + showCanvas(); + }); +} + +function updateMap(imageDimensions, imagePath) { + // Map image coordinates to map coordinates to be able to use image extent in pixels. + let extent = [0, 0, imageDimensions[0], imageDimensions[1]]; + let projection = createProjection(extent); + + kitodo.map.getLayers().getArray()[0].setSource(createSource(extent, imagePath, projection)); + kitodo.map.getView().setCenter(ol.extent.getCenter(extent)); + kitodo.map.getView().getProjection().setExtent(extent); + kitodo.map.getView().fit(extent, {}); +} + +function addListener(element) { + element.on("load", function () { + if (kitodo.map && $("#map .ol-viewport").length) { + updateMap([element.width(), element.height()], element[0].src); + } else { + initializeMap([element.width(), element.height()], element[0].src); + } + }); +} + +function initializeImage() { + resetNorth(); + hideCanvas(); + let image = $("#imagePreviewForm\\:mediaPreviewGraphicImage"); + if (image.length > 0) { + addListener(image); + image[0].src = image[0].src.replace(/&uuid=[a-z0-9]+/i, "") + "&uuid=" + random(8); + } +} + +function changeToMapView() { + initializeImage(); + showCanvas(); + if (kitodo.map) { + kitodo.map.handleTargetChanged_(); + } +} + +// reload map if container was resized +$('#thirdColumnWrapper').on('resize', function () { + if (kitodo.map) { + // FIXME: This causes lags. It should only be executed *once* after resize. + kitodo.map.updateSize(); + } +}); + +$(document).ready(function () { + initializeImage(); +}); diff --git a/Kitodo/src/main/webapp/WEB-INF/resources/js/scroll.js b/Kitodo/src/main/webapp/WEB-INF/resources/js/scroll.js index 1077f56519f..d735d1d4453 100644 --- a/Kitodo/src/main/webapp/WEB-INF/resources/js/scroll.js +++ b/Kitodo/src/main/webapp/WEB-INF/resources/js/scroll.js @@ -157,7 +157,7 @@ function initializeStructureTreeScrolling() { } function scrollToPreviewThumbnail(thumbnail, scrollable) { - let thumbnailHeight = thumbnail.parent().parent().height(); + let thumbnailHeight = thumbnail.closest(".thumbnail-parent").height(); let selectedIndex = scrollable.find(".thumbnail + .thumbnail-container").index(thumbnail); if (selectedIndex >= 0) { scrollable.animate({ diff --git a/Kitodo/src/main/webapp/WEB-INF/templates/includes/metadataEditor/dialogs/pagination.xhtml b/Kitodo/src/main/webapp/WEB-INF/templates/includes/metadataEditor/dialogs/pagination.xhtml index 34480d3424c..d0bd9ab3245 100644 --- a/Kitodo/src/main/webapp/WEB-INF/templates/includes/metadataEditor/dialogs/pagination.xhtml +++ b/Kitodo/src/main/webapp/WEB-INF/templates/includes/metadataEditor/dialogs/pagination.xhtml @@ -48,7 +48,7 @@ + update="galleryHeadingWrapper,imagePreviewForm:mediaDetail,metadataAccordion:logicalMetadataWrapperPanel"/>
diff --git a/Kitodo/src/main/webapp/WEB-INF/templates/includes/metadataEditor/gallery.xhtml b/Kitodo/src/main/webapp/WEB-INF/templates/includes/metadataEditor/gallery.xhtml index 3f1cfb68f4d..7a0f95c10d6 100644 --- a/Kitodo/src/main/webapp/WEB-INF/templates/includes/metadataEditor/gallery.xhtml +++ b/Kitodo/src/main/webapp/WEB-INF/templates/includes/metadataEditor/gallery.xhtml @@ -37,7 +37,7 @@ diff --git a/Kitodo/src/main/webapp/WEB-INF/templates/includes/metadataEditor/logicalStructure.xhtml b/Kitodo/src/main/webapp/WEB-INF/templates/includes/metadataEditor/logicalStructure.xhtml index 1a3011d6e27..21aad4f2c82 100644 --- a/Kitodo/src/main/webapp/WEB-INF/templates/includes/metadataEditor/logicalStructure.xhtml +++ b/Kitodo/src/main/webapp/WEB-INF/templates/includes/metadataEditor/logicalStructure.xhtml @@ -75,7 +75,7 @@ changeToMapView(); expandMetadata('logical-metadata-tab');" update="galleryHeadingWrapper - imagePreviewForm:mediaDetailContainer + imagePreviewForm:mediaDetail contextMenuLogicalTree imagePreviewForm:stripeContextMenu imagePreviewForm:mediaContextMenu @@ -90,7 +90,7 @@ update="@(.stripe) @(.thumbnail) galleryHeadingWrapper - imagePreviewForm:mediaDetailContainer + imagePreviewForm:mediaDetail contextMenuLogicalTree physicalTree metadataAccordion:logicalMetadataWrapperPanel"/> diff --git a/Kitodo/src/main/webapp/WEB-INF/templates/includes/metadataEditor/physicalStructure.xhtml b/Kitodo/src/main/webapp/WEB-INF/templates/includes/metadataEditor/physicalStructure.xhtml index 2cbc5d22c12..337879d9e06 100644 --- a/Kitodo/src/main/webapp/WEB-INF/templates/includes/metadataEditor/physicalStructure.xhtml +++ b/Kitodo/src/main/webapp/WEB-INF/templates/includes/metadataEditor/physicalStructure.xhtml @@ -37,7 +37,7 @@ initializeImage(); expandMetadata('physical-metadata-tab');" update="galleryHeadingWrapper - imagePreviewForm:mediaDetailContainer + imagePreviewForm:mediaDetail metadataAccordion:physicalMetadataWrapperPanel"/> From 468fe40b702979d95b9334f3e34f35733f2e54f0 Mon Sep 17 00:00:00 2001 From: Markus Weigelt Date: Tue, 30 May 2023 15:20:09 +0200 Subject: [PATCH 22/72] Remove file --- .../resources/js/media_detail_audio.js | 254 ------------------ 1 file changed, 254 deletions(-) delete mode 100644 Kitodo/src/main/webapp/WEB-INF/resources/js/media_detail_audio.js diff --git a/Kitodo/src/main/webapp/WEB-INF/resources/js/media_detail_audio.js b/Kitodo/src/main/webapp/WEB-INF/resources/js/media_detail_audio.js deleted file mode 100644 index 049d0f7da75..00000000000 --- a/Kitodo/src/main/webapp/WEB-INF/resources/js/media_detail_audio.js +++ /dev/null @@ -1,254 +0,0 @@ -/** - * (c) Kitodo. Key to digital objects e. V. - * - * This file is part of the Kitodo project. - * - * It is licensed under GNU General Public License version 3 or later. - * - * For the full copyright and license information, please read the - * GPL3-License.txt file that was distributed with this source code. - */ -/* globals ol */ -// jshint unused:false - -// Kitodo namespace -var kitodo = {}; -kitodo.map = null; - -/** - * @param {Object=} options Custom control options for Kitodo in OpenLayers - * @extends {ol.control.Rotate} - * @constructor - */ -kitodo.RotateLeftControl = function(options = {}) { - var buttonLeft = document.createElement('button'); - buttonLeft.innerHTML = ""; - buttonLeft.setAttribute("type", "button"); - buttonLeft.setAttribute("title", "Rotate left"); - - var this_ = this; - - var handleRotateLeft = function() { - var view = this_.getMap().getView(); - view.animate({ - rotation: view.getRotation() - (90 * (Math.PI / 180)), - duration: 100 - }); - }; - - buttonLeft.addEventListener('click', handleRotateLeft, false); - - var elementLeft = document.createElement('div'); - elementLeft.className = 'rotate-left ol-unselectable ol-control ol-rotate'; - elementLeft.appendChild(buttonLeft); - - ol.control.Control.call(this, { - element: elementLeft, - target: options.target - }); -}; - -/** - * @param {Object=} options Custom control options for Kitodo in OpenLayers - * @extends {ol.control.Rotate} - * @constructor - */ -kitodo.RotateRightControl = function(options = {}) { - var buttonRight = document.createElement('button'); - buttonRight.innerHTML = ""; - buttonRight.setAttribute("type", "button"); - buttonRight.setAttribute("title", "Rotate right"); - - var this_ = this; - - var handleRotateRight = function() { - var view = this_.getMap().getView(); - view.animate({ - rotation: view.getRotation() + (90 * (Math.PI / 180)), - duration: 100 - }); - }; - - buttonRight.addEventListener('click', handleRotateRight, false); - - var elementRight = document.createElement('div'); - elementRight.className = 'rotate-right ol-unselectable ol-control ol-rotate'; - elementRight.appendChild(buttonRight); - - ol.control.Control.call(this, { - element: elementRight, - target: options.target, - duration: 250 - }); -}; - -function resetNorth() { - if (kitodo.map) { - let view = kitodo.map.getView(); - view.animate({ - rotation: 0, - duration: 0 - }); - } -} - -/** - * @param {Object=} options Custom control options for Kitodo in OpenLayers - * @extends {ol.control.Rotate} - * @constructor - */ -kitodo.ResetNorthControl = function(options = {}) { - let buttonResetNorth = document.createElement("button"); - buttonResetNorth.innerHTML = ""; - buttonResetNorth.setAttribute("type", "button"); - buttonResetNorth.setAttribute("title", "Reset orientation"); - - buttonResetNorth.addEventListener("click", resetNorth, false); - - let elementResetNorth = document.createElement("div"); - elementResetNorth.className = "ol-rotate ol-unselectable ol-control"; /*ol-rotate-reset*/ - elementResetNorth.appendChild(buttonResetNorth); - - ol.control.Control.call(this, { - element: elementResetNorth, - target: options.target, - duration: 250 - }); -}; - -ol.inherits(kitodo.RotateLeftControl, ol.control.Rotate); -ol.inherits(kitodo.RotateRightControl, ol.control.Rotate); -ol.inherits(kitodo.ResetNorthControl, ol.control.Rotate); - -function random(length) { - var text = ""; - var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; - - for (var i = 0; i < length; i++) { - text += possible.charAt(Math.floor(Math.random() * possible.length)); - } - - return text; -} - -function createProjection(extent) { - return new ol.proj.Projection({ - code: 'kitodo-image', - units: 'pixels', - extent: extent - }); -} - -function createSource(extent, imagePath, projection) { - return new ol.source.ImageStatic({ - url: imagePath, - projection: projection, - imageExtent: extent - }); -} - -function hideCanvas() { - let map = document.querySelector("#map canvas"); - let loadingIcon = document.querySelector("#map > .fa-spinner"); - if (map) { - map.style.opacity = 0; - loadingIcon.style.opacity = 1; - } -} - -function showCanvas() { - let map = document.querySelector("#map canvas"); - let loadingIcon = document.querySelector("#map > .fa-spinner"); - if (map) { - map.style.opacity = 1; - loadingIcon.style.opacity = 0; - } -} - -function initializeMap(imageDimensions, imagePath) { - // Map image coordinates to map coordinates to be able to use image extent in pixels. - let extent = [0, 0, imageDimensions[0], imageDimensions[1]]; - let projection = createProjection(extent); - - kitodo.map = new ol.Map({ - controls: ol.control.defaults({ - attributionOptions: { - collapsible: false - }, - zoomOptions: { - delta: 3 - }, - rotate: false - }).extend([ - new kitodo.RotateRightControl(), - new kitodo.RotateLeftControl(), - new kitodo.ResetNorthControl() - ]), - layers: [ - new ol.layer.Image({ - source: createSource(extent, imagePath, projection) - }) - ], - target: 'map', - view: new ol.View({ - projection: projection, - center: ol.extent.getCenter(extent), - zoomFactor: 1.1 - }) - }); - kitodo.map.getView().fit(extent, {}); - kitodo.map.on("rendercomplete", function () { - showCanvas(); - }); -} - -function updateMap(imageDimensions, imagePath) { - // Map image coordinates to map coordinates to be able to use image extent in pixels. - let extent = [0, 0, imageDimensions[0], imageDimensions[1]]; - let projection = createProjection(extent); - - kitodo.map.getLayers().getArray()[0].setSource(createSource(extent, imagePath, projection)); - kitodo.map.getView().setCenter(ol.extent.getCenter(extent)); - kitodo.map.getView().getProjection().setExtent(extent); - kitodo.map.getView().fit(extent, {}); -} - -function addListener(element) { - element.on("load", function () { - if (kitodo.map && $("#map .ol-viewport").length) { - updateMap([element.width(), element.height()], element[0].src); - } else { - initializeMap([element.width(), element.height()], element[0].src); - } - }); -} - -function initializeImage() { - resetNorth(); - hideCanvas(); - let image = $("#imagePreviewForm\\:mediaPreviewGraphicImage"); - if (image.length > 0) { - addListener(image); - image[0].src = image[0].src.replace(/&uuid=[a-z0-9]+/i, "") + "&uuid=" + random(8); - } -} - -function changeToMapView() { - initializeImage(); - showCanvas(); - if (kitodo.map) { - kitodo.map.handleTargetChanged_(); - } -} - -// reload map if container was resized -$('#thirdColumnWrapper').on('resize', function () { - if (kitodo.map) { - // FIXME: This causes lags. It should only be executed *once* after resize. - kitodo.map.updateSize(); - } -}); - -$(document).ready(function () { - initializeImage(); -}); From 1979dfe9889e1bec539cf71ca4cad7b1d461337a Mon Sep 17 00:00:00 2001 From: Matthias Ronge Date: Tue, 30 May 2023 15:16:07 +0200 Subject: [PATCH 23/72] Implements the reimport behaviour respecting the maxOccurs setting --- .../RulesetManagementInterface.java | 4 +- .../dataeditor/ruleset/ReimportMetadata.java | 133 ++++++++++++++++++ .../dataeditor/ruleset/RulesetManagement.java | 73 ++++------ .../dataeditor/ruleset/xml/Reimport.java | 8 +- .../ruleset/RulesetManagementIT.java | 19 ++- .../resources/testReimportOfMetadataModes.xml | 15 +- .../createprocess/ProcessFieldedMetadata.java | 2 +- 7 files changed, 201 insertions(+), 53 deletions(-) create mode 100644 Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/ReimportMetadata.java diff --git a/Kitodo-API/src/main/java/org/kitodo/api/dataeditor/rulesetmanagement/RulesetManagementInterface.java b/Kitodo-API/src/main/java/org/kitodo/api/dataeditor/rulesetmanagement/RulesetManagementInterface.java index 916fa3990ac..64c7415977e 100644 --- a/Kitodo-API/src/main/java/org/kitodo/api/dataeditor/rulesetmanagement/RulesetManagementInterface.java +++ b/Kitodo-API/src/main/java/org/kitodo/api/dataeditor/rulesetmanagement/RulesetManagementInterface.java @@ -150,6 +150,8 @@ StructuralElementViewInterface getStructuralElementView(String structuralElement * Updates metadata during a repeated catalog import, depending on the * reimport settings specified in the ruleset. * + * @param division + * current division * @param metadata * current metadata * @param acquisitionStage @@ -158,5 +160,5 @@ StructuralElementViewInterface getStructuralElementView(String structuralElement * items obtained from import * @return number of added metadata items */ - int updateMetadata(Collection metadata, String acquisitionStage, Collection updateItems); + int updateMetadata(String division, Collection metadata, String acquisitionStage, Collection updateItems); } diff --git a/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/ReimportMetadata.java b/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/ReimportMetadata.java new file mode 100644 index 00000000000..49f8deb7252 --- /dev/null +++ b/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/ReimportMetadata.java @@ -0,0 +1,133 @@ +/* + * (c) Kitodo. Key to digital objects e. V. + * + * This file is part of the Kitodo project. + * + * It is licensed under GNU General Public License version 3 or later. + * + * For the full copyright and license information, please read the + * GPL3-License.txt file that was distributed with this source code. + */ + +package org.kitodo.dataeditor.ruleset; + +import java.util.*; +import java.util.Collection; +import java.util.Objects; +import java.util.function.Supplier; + +import org.apache.commons.lang3.ArrayUtils; +import org.kitodo.api.Metadata; +import org.kitodo.dataeditor.ruleset.xml.Reimport; + +/** + * Determines the result of re-importing metadata for a single metadata key. + */ +class ReimportMetadata implements Supplier> { + + // Metadata key for which the result of the reimport is determined. + private final String key; + + // existing metadata for this key before reimport + private Collection currentEntries; + + // configured reimport behavior + private Reimport reimport; + + // metadata fetched on reimport + private Collection updateEntries; + + // the maximum amount of metadata applicable here for this key + private int maxOccurs; + + /** + * Constructor. Generates a data set for the re-import of + * metadata for a specific key. + * + * @param key + * metadata key for which the result of the reimport is + * determined + */ + ReimportMetadata(String key) { + this.currentEntries = new ArrayList<>(); + this.updateEntries = new ArrayList<>(); + this.key = key; + this.maxOccurs = Integer.MAX_VALUE; + } + + /** + * Sets the repeated import behavior model for this metadata key. Must be a + * value from {@link Reimport}. + * + * @param reimport + * configured reimport behavior to set + */ + void setReimport(Reimport reimport) { + this.reimport = reimport; + } + + /** + * Sets the maximum number of metadata values allowed for this key. The + * setting only affects newly added metadata. + * + * @param maxOccurs + * maximum amount of metadata to set + */ + void setMaxOccurs(int maxOccurs) { + this.maxOccurs = maxOccurs; + } + + /** + * Returns the metadata key. The key is that of the contained metadata. + * + * @return the metadata key + */ + String getKey() { + return key; + } + + /** + * Adds a metadata entry to the current metadata entries. + * + * @param metadata + * metadata to add + */ + void addToCurrentEntries(Metadata metadata) { + assert Objects.equals(metadata.getKey(), key) : "keys should match"; + currentEntries.add(metadata); + } + + /** + * Adds a metadata entry to the update metadata entries. + * + * @param metadata + * metadata to add + */ + void addToUpdateEntries(Metadata metadata) { + assert Objects.equals(metadata.getKey(), key) : "keys should match"; + updateEntries.add(metadata); + } + + /** + * Merges the metadata of this key in the given behavior, respecting the + * maximum number. + * + * @return the metadata remaining after the repeated import + */ + @Override + public Collection get() { + if (!ArrayUtils.contains(Reimport.values(), reimport)) { + throw new IllegalStateException("Used not supported reimport case ".concat(Objects.toString(reimport))); + } + Collection result = reimport.equals(Reimport.REPLACE) && !updateEntries.isEmpty() ? new ArrayList<>() + : new ArrayList<>(currentEntries); + if (!reimport.equals(Reimport.KEEP) || result.isEmpty()) { + for (Metadata metadata : updateEntries) { + if (!result.contains(metadata) && result.size() < maxOccurs) { + result.add(metadata); + } + } + } + return result; + } +} diff --git a/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/RulesetManagement.java b/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/RulesetManagement.java index 9da9d28d146..d3592ef87ee 100644 --- a/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/RulesetManagement.java +++ b/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/RulesetManagement.java @@ -22,24 +22,22 @@ import java.util.Objects; import java.util.Optional; import java.util.Set; -import java.util.function.Function; import java.util.stream.Collectors; import javax.xml.bind.JAXBException; -import org.apache.commons.lang3.tuple.MutableTriple; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.kitodo.api.Metadata; import org.kitodo.api.dataeditor.rulesetmanagement.FunctionalDivision; import org.kitodo.api.dataeditor.rulesetmanagement.FunctionalMetadata; +import org.kitodo.api.dataeditor.rulesetmanagement.MetadataViewInterface; import org.kitodo.api.dataeditor.rulesetmanagement.RulesetManagementInterface; import org.kitodo.api.dataeditor.rulesetmanagement.StructuralElementViewInterface; import org.kitodo.dataeditor.ruleset.xml.AcquisitionStage; import org.kitodo.dataeditor.ruleset.xml.Division; import org.kitodo.dataeditor.ruleset.xml.Key; import org.kitodo.dataeditor.ruleset.xml.Namespace; -import org.kitodo.dataeditor.ruleset.xml.Reimport; import org.kitodo.dataeditor.ruleset.xml.Ruleset; import org.kitodo.dataeditor.ruleset.xml.Setting; import org.kitodo.utils.JAXBContextCache; @@ -53,6 +51,11 @@ public class RulesetManagement implements RulesetManagementInterface { */ private static final Logger logger = LogManager.getLogger(RulesetManagement.class); + /** + * Language used internally in places where language does not matter. + */ + private static final List ENGLISH = LanguageRange.parse("en"); + /** * The ruleset. */ @@ -327,58 +330,42 @@ public boolean isAlwaysShowingForKey(String keyId) { } @Override - public int updateMetadata(Collection currentMetadata, String acquisitionStage, + public int updateMetadata(String division, Collection currentMetadata, String acquisitionStage, Collection updateMetadata) { - HashMap, Reimport, Collection>> unifying = unifyMetadataByKey( - currentMetadata, acquisitionStage, updateMetadata); + Settings settings = ruleset.getSettings(acquisitionStage); + Collection allowedMetadata = getStructuralElementView(division, acquisitionStage, + ENGLISH).getAllowedMetadata(); + Collection metadataForReimport = createListOfMetadataToMerge(currentMetadata, settings, + allowedMetadata, updateMetadata); + int sizeBefore = currentMetadata.size(); currentMetadata.clear(); - for (var entry : unifying.entrySet()) { - var metadata = entry.getValue(); - Collection currentEntries = metadata.getLeft(); - Collection updateEntries = metadata.getRight(); - - switch (metadata.getMiddle()) { - case ADD: - currentMetadata.addAll(currentEntries); - currentMetadata.addAll(updateEntries); - break; - case KEEP: - currentMetadata.addAll(currentEntries); - break; - case REPLACE: - currentMetadata.addAll(updateEntries.isEmpty() ? currentEntries : updateEntries); - break; - default: - throw new IllegalStateException( - "Used not supported reimport case {}".replace("{}", metadata.getMiddle().toString())); - } + for (ReimportMetadata metadataInReimport : metadataForReimport) { + currentMetadata.addAll(metadataInReimport.get()); } return currentMetadata.size() - sizeBefore; } - private HashMap, Reimport, Collection>> unifyMetadataByKey( - Collection currentMetadata, String acquisitionStage, Collection updateMetadata) { - - final Function, Reimport, Collection>> entryProducer = key -> { - MutableTriple, Reimport, Collection> entry = new MutableTriple<>(); - entry.setLeft(new ArrayList<>()); - entry.setRight(new ArrayList<>()); - return entry; - }; - - HashMap, Reimport, Collection>> unifying = new HashMap<>(); + private Collection createListOfMetadataToMerge(Collection currentMetadata, + Settings settings, Collection allowedMetadata, Collection updateMetadata) { + HashMap unifying = new HashMap<>(); for (Metadata metadata : currentMetadata) { - unifying.computeIfAbsent(metadata.getKey(), entryProducer).getLeft().add(metadata); + unifying.computeIfAbsent(metadata.getKey(), ReimportMetadata::new).addToCurrentEntries(metadata); } for (Metadata metadata : updateMetadata) { - unifying.computeIfAbsent(metadata.getKey(), entryProducer).getRight().add(metadata); + unifying.computeIfAbsent(metadata.getKey(), ReimportMetadata::new).addToUpdateEntries(metadata); } - Settings settings = ruleset.getSettings(acquisitionStage); - for (var entry : unifying.entrySet()) { - entry.getValue().setMiddle(settings.getReimport(entry.getKey())); + Collection result = unifying.values(); + for (ReimportMetadata entry : result) { + entry.setReimport(settings.getReimport(entry.getKey())); } - return unifying; + for (MetadataViewInterface metadataView : allowedMetadata) { + ReimportMetadata metadataToMerge = unifying.get(metadataView.getId()); + if (Objects.nonNull(metadataToMerge)) { + metadataToMerge.setMaxOccurs(metadataView.getMaxOccurs()); + } + } + return result; } } diff --git a/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/xml/Reimport.java b/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/xml/Reimport.java index 8713c286ee7..c022ee69c08 100644 --- a/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/xml/Reimport.java +++ b/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/xml/Reimport.java @@ -14,9 +14,11 @@ import javax.xml.bind.annotation.XmlEnum; import javax.xml.bind.annotation.XmlEnumValue; +import org.apache.commons.lang3.ArrayUtils; + /** - * This class is a backing bean for the XML attribute reimport in the - * ruleset. With it, JAXB can map the attribute to an enum. + * This class is a backing bean for the XML attribute reimport in the ruleset. + * With it, JAXB can map the attribute to an enum. */ @XmlEnum(String.class) public enum Reimport { @@ -36,5 +38,5 @@ public enum Reimport { * The existing metadata should be replaced. */ @XmlEnumValue("replace") - REPLACE + REPLACE; } diff --git a/Kitodo-DataEditor/src/test/java/org/kitodo/dataeditor/ruleset/RulesetManagementIT.java b/Kitodo-DataEditor/src/test/java/org/kitodo/dataeditor/ruleset/RulesetManagementIT.java index d6222498a32..fd7402da1ef 100644 --- a/Kitodo-DataEditor/src/test/java/org/kitodo/dataeditor/ruleset/RulesetManagementIT.java +++ b/Kitodo-DataEditor/src/test/java/org/kitodo/dataeditor/ruleset/RulesetManagementIT.java @@ -12,6 +12,7 @@ package org.kitodo.dataeditor.ruleset; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.anyOf; import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.empty; @@ -1077,6 +1078,7 @@ public void testReimportOfMetadataModesCreate() throws Exception { metadata.add(newMetadataEntry("metadataToReplaceByDefault", "value to replace")); metadata.add(newMetadataEntry("metadataToReplaceExplicitly", "value to replace")); metadata.add(newMetadataEntry("metadataToAdd", "value 1")); + metadata.add(newMetadataEntry("metadataToAddWithLimit", "value 1")); metadata.add(newMetadataEntry("metadataToAddDuringCreationAndKeepLater", "value 1")); metadata.add(newMetadataEntry("metadataToKeep", "value not to replace")); metadata.add(newMetadataEntry("metadataToKeepExceptInEditing", "value not to replace")); @@ -1084,15 +1086,19 @@ public void testReimportOfMetadataModesCreate() throws Exception { Collection imported = new HashSet<>(); imported.add(newMetadataEntry("metadataToReplaceByDefault", "replaced value")); // 0 imported.add(newMetadataEntry("metadataToReplaceExplicitly", "replaced value")); // 0 + imported.add(newMetadataEntry("metadataToAdd", "value 1")); // 0 imported.add(newMetadataEntry("metadataToAdd", "value 2")); // 1 imported.add(newMetadataEntry("metadataToAdd", "value 3")); // 1 + imported.add(newMetadataEntry("metadataToAddWithLimit", "value 1")); // 0 + imported.add(newMetadataEntry("metadataToAddWithLimit", "value 2")); // 0.5 + imported.add(newMetadataEntry("metadataToAddWithLimit", "value 3")); // 0.5 imported.add(newMetadataEntry("metadataToAddDuringCreationAndKeepLater", "value 2")); // 1 imported.add(newMetadataEntry("metadataToKeep", "value must not appear in result")); // 0 imported.add(newMetadataEntry("metadataToKeepExceptInEditing", "value not to replace")); // 0 imported.add(newMetadataEntry("metadataThatIsNew", "new value")); // 1 - int numAdded = underTest.updateMetadata(metadata, "create", imported); - assertEquals(4, numAdded); + int numAdded = underTest.updateMetadata("division", metadata, "create", imported); + assertEquals(5, numAdded); List defaultReplace = metadata.stream() .filter(element -> element.getKey().equals("metadataToReplaceByDefault")).collect(Collectors.toList()); @@ -1111,6 +1117,13 @@ public void testReimportOfMetadataModesCreate() throws Exception { add.stream().map(MetadataEntry.class::cast).map(MetadataEntry::getValue).collect(Collectors.toList()), containsInAnyOrder("value 1", "value 2", "value 3")); + List limitedAdd = metadata.stream().filter(element -> element.getKey().equals("metadataToAddWithLimit")) + .collect(Collectors.toList()); + assertEquals(2, limitedAdd.size()); + assertThat( + limitedAdd.stream().map(MetadataEntry.class::cast).map(MetadataEntry::getValue).collect(Collectors.toList()), + anyOf(containsInAnyOrder("value 1", "value 2"), containsInAnyOrder("value 1", "value 3"))); + List addCreate = metadata.stream() .filter(element -> element.getKey().equals("metadataToAddDuringCreationAndKeepLater")) .collect(Collectors.toList()); @@ -1146,7 +1159,7 @@ public void testReimportOfMetadataModesEdit() throws Exception { imported.add(newMetadataEntry("metadataToAddDuringCreationAndKeepLater", "value not to replace")); // 0 imported.add(newMetadataEntry("metadataToKeepExceptInEditing", "replaced value")); // -1 - int numAdded = underTest.updateMetadata(metadata, "edit", imported); + int numAdded = underTest.updateMetadata("division", metadata, "edit", imported); assertEquals(-1, numAdded); List keepLater = metadata.stream() diff --git a/Kitodo-DataEditor/src/test/resources/testReimportOfMetadataModes.xml b/Kitodo-DataEditor/src/test/resources/testReimportOfMetadataModes.xml index a5d717f1979..a7d7e4f0691 100644 --- a/Kitodo-DataEditor/src/test/resources/testReimportOfMetadataModes.xml +++ b/Kitodo-DataEditor/src/test/resources/testReimportOfMetadataModes.xml @@ -15,8 +15,8 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://names.kitodo.org/ruleset/v2 ruleset.xsd"> - - + + @@ -32,6 +32,10 @@ + + + + @@ -50,8 +54,15 @@ + + + + + + + diff --git a/Kitodo/src/main/java/org/kitodo/production/forms/createprocess/ProcessFieldedMetadata.java b/Kitodo/src/main/java/org/kitodo/production/forms/createprocess/ProcessFieldedMetadata.java index 4d6522a5e37..7bc2b464ab6 100644 --- a/Kitodo/src/main/java/org/kitodo/production/forms/createprocess/ProcessFieldedMetadata.java +++ b/Kitodo/src/main/java/org/kitodo/production/forms/createprocess/ProcessFieldedMetadata.java @@ -145,7 +145,7 @@ public int addMetadataIfNotExists(Collection potentialMetadataItems) throws InvalidMetadataValueException, NoSuchMetadataFieldException { preserve(); - int count = rulesetService.updateMetadata(metadata, "create", potentialMetadataItems); + int count = rulesetService.updateMetadata(division.getType() ,metadata, "create", potentialMetadataItems); buildTreeNodeAndCreateMetadataTable(); return count; } From 6183027c13f4f6b78c88d19c3affae0fcd617135 Mon Sep 17 00:00:00 2001 From: Matthias Ronge Date: Wed, 31 May 2023 09:19:57 +0200 Subject: [PATCH 24/72] Fix import --- .../java/org/kitodo/dataeditor/ruleset/ReimportMetadata.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/ReimportMetadata.java b/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/ReimportMetadata.java index 49f8deb7252..8a309a33d38 100644 --- a/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/ReimportMetadata.java +++ b/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/ReimportMetadata.java @@ -11,7 +11,7 @@ package org.kitodo.dataeditor.ruleset; -import java.util.*; +import java.util.ArrayList; import java.util.Collection; import java.util.Objects; import java.util.function.Supplier; From 05b34f48215e39c834c8199ebcc3f4976c7e660f Mon Sep 17 00:00:00 2001 From: Matthias Ronge Date: Wed, 31 May 2023 09:57:40 +0200 Subject: [PATCH 25/72] Test availability using getAllowedMetadata() --- .../createprocess/CreateProcessForm.java | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/Kitodo/src/main/java/org/kitodo/production/forms/createprocess/CreateProcessForm.java b/Kitodo/src/main/java/org/kitodo/production/forms/createprocess/CreateProcessForm.java index 9a741e86728..ebac04a026c 100644 --- a/Kitodo/src/main/java/org/kitodo/production/forms/createprocess/CreateProcessForm.java +++ b/Kitodo/src/main/java/org/kitodo/production/forms/createprocess/CreateProcessForm.java @@ -650,23 +650,24 @@ private void setProcessTitleMetadata(Workpiece workpiece) { Collection keysForProcessTitle = rulesetManagement.getFunctionalKeys(FunctionalMetadata.PROCESS_TITLE); if (!keysForProcessTitle.isEmpty()) { String processTitle = currentProcess.getProcess().getTitle(); - addAddableMetadataRecursive(workpiece.getLogicalStructure(), keysForProcessTitle, processTitle); - addAddableMetadataRecursive(workpiece.getPhysicalStructure(), keysForProcessTitle, processTitle); + addAllowedMetadataRecursive(workpiece.getLogicalStructure(), keysForProcessTitle, processTitle); + addAllowedMetadataRecursive(workpiece.getPhysicalStructure(), keysForProcessTitle, processTitle); } } - private void addAddableMetadataRecursive(Division division, Collection keys, String value) { + private void addAllowedMetadataRecursive(Division division, Collection keys, String value) { StructuralElementViewInterface divisionView = rulesetManagement.getStructuralElementView(division.getType(), acquisitionStage, priorityList); - for (MetadataViewInterface addableMetadataView : divisionView.getAddableMetadata(division.getMetadata(), - Collections.emptyList())) { - if (addableMetadataView instanceof SimpleMetadataViewInterface - && keys.contains(addableMetadataView.getId())) { - MetadataEditor.writeMetadataEntry(division, (SimpleMetadataViewInterface) addableMetadataView, value); + for (MetadataViewInterface metadataView : divisionView.getAllowedMetadata()) { + if (metadataView instanceof SimpleMetadataViewInterface && keys.contains(metadataView.getId()) + && division.getMetadata().parallelStream() + .filter(metadata -> metadataView.getId().equals(metadata.getKey())) + .count() < metadataView.getMaxOccurs()) { + MetadataEditor.writeMetadataEntry(division, (SimpleMetadataViewInterface) metadataView, value); } } for (Division child : division.getChildren()) { - addAddableMetadataRecursive(child, keys, value); + addAllowedMetadataRecursive(child, keys, value); } } From 9b5fb2e00c2a7dff91a136ca0451fdd8ed1732f0 Mon Sep 17 00:00:00 2001 From: Matthias Ronge Date: Wed, 31 May 2023 10:06:00 +0200 Subject: [PATCH 26/72] Fix test dummy class --- Kitodo/src/test/java/org/kitodo/DummyRulesetManagement.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Kitodo/src/test/java/org/kitodo/DummyRulesetManagement.java b/Kitodo/src/test/java/org/kitodo/DummyRulesetManagement.java index b12619fab87..87f6003eb9d 100644 --- a/Kitodo/src/test/java/org/kitodo/DummyRulesetManagement.java +++ b/Kitodo/src/test/java/org/kitodo/DummyRulesetManagement.java @@ -80,7 +80,7 @@ public boolean isAlwaysShowingForKey(String keyId) { } @Override - public int updateMetadata(Collection metadata, String acquisitionStage, + public int updateMetadata(String division, Collection metadata, String acquisitionStage, Collection updateItems) { throw new UnsupportedOperationException(); } From 1a4151873b92e54e7e839a18f614c4044f52a525 Mon Sep 17 00:00:00 2001 From: Matthias Ronge Date: Thu, 1 Jun 2023 15:09:07 +0200 Subject: [PATCH 27/72] Renames variables ending in "interface" because they hold an instance ... of a class that implements an interface. Even if an object implements an interface, it's still an object and not an interface, so this naming is misleading. It fixes a bit of Javadoc as well, and eliminates an unnecessary call to the module loader every time a script is run, since the module was loaded when the class was instantiated. --- .../org/kitodo/dataeditor/ruleset/Rule.java | 6 +- .../dataeditor/AddDocStrucTypeDialog.java | 4 +- .../production/helper/ProcessHelper.java | 57 +++++++++---------- .../LegacyMetadataHelper.java | 12 ++-- .../production/metadata/MetadataEditor.java | 10 ++-- .../services/command/CommandService.java | 5 +- .../services/data/ImportService.java | 24 ++++---- .../production/helper/ProcessHelperIT.java | 28 ++++----- .../process/ProcessValidatorIT.java | 6 +- .../process/TitleGeneratorTest.java | 6 +- .../org/kitodo/utils/ProcessTestUtils.java | 6 +- 11 files changed, 80 insertions(+), 84 deletions(-) diff --git a/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/Rule.java b/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/Rule.java index d3905c361f7..8fc67cb509e 100644 --- a/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/Rule.java +++ b/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/Rule.java @@ -206,15 +206,15 @@ private static Collection getConditionalPermits(RestrictivePe return result; } - private static void getConditionalPermits(ConditionsMapInterface conditionsMapInterface, + private static void getConditionalPermits(ConditionsMapInterface conditionsMap, Map> metadataCache, List> metadata, Collection result) { - for (String conditionKey : conditionsMapInterface.getConditionKeys()) { + for (String conditionKey : conditionsMap.getConditionKeys()) { Optional possibleMetadata = metadataCache.computeIfAbsent(conditionKey, key -> getMetadataEntryForKey(key, metadata)); if (possibleMetadata.isPresent()) { - Condition condition = conditionsMapInterface.getCondition(conditionKey, possibleMetadata.get().getValue()); + Condition condition = conditionsMap.getCondition(conditionKey, possibleMetadata.get().getValue()); if (Objects.nonNull(condition)) { result.addAll(condition.getPermits()); getConditionalPermits(condition, metadataCache, metadata, result); // recursive diff --git a/Kitodo/src/main/java/org/kitodo/production/forms/dataeditor/AddDocStrucTypeDialog.java b/Kitodo/src/main/java/org/kitodo/production/forms/dataeditor/AddDocStrucTypeDialog.java index ebbcf0cf41a..51e13fb9b78 100644 --- a/Kitodo/src/main/java/org/kitodo/production/forms/dataeditor/AddDocStrucTypeDialog.java +++ b/Kitodo/src/main/java/org/kitodo/production/forms/dataeditor/AddDocStrucTypeDialog.java @@ -152,11 +152,11 @@ private void addMultiDocStruc() { Optional selectedStructure = dataEditor.getSelectedStructure(); if (selectedStructure.isPresent()) { if (selectedMetadata != "") { - MetadataViewInterface metadataViewInterface = getMetadataViewFromKey( + MetadataViewInterface metadataView = getMetadataViewFromKey( docStructAddTypeSelectionSelectedItem, selectedMetadata); MetadataEditor.addMultipleStructuresWithMetadata(elementsToAddSpinnerValue, docStructAddTypeSelectionSelectedItem, dataEditor.getWorkpiece(), selectedStructure.get(), - selectedDocStructPosition, metadataViewInterface, inputMetaDataValue); + selectedDocStructPosition, metadataView, inputMetaDataValue); } else { MetadataEditor.addMultipleStructures(elementsToAddSpinnerValue, docStructAddTypeSelectionSelectedItem, dataEditor.getWorkpiece(), selectedStructure.get(), selectedDocStructPosition); diff --git a/Kitodo/src/main/java/org/kitodo/production/helper/ProcessHelper.java b/Kitodo/src/main/java/org/kitodo/production/helper/ProcessHelper.java index f30b3f1a3de..398ec53eb6f 100644 --- a/Kitodo/src/main/java/org/kitodo/production/helper/ProcessHelper.java +++ b/Kitodo/src/main/java/org/kitodo/production/helper/ProcessHelper.java @@ -54,9 +54,8 @@ public class ProcessHelper { * @param tempProcess * the TempProcess for which the List of ProcessDetail objects is * created - * @param managementInterface - * RulesetManagementInterface used to create the metadata of the - * process + * @param rulesetManagement + * Ruleset management used to create the metadata of the process * @param acquisitionStage * String containing the acquisitionStage * @param priorityList @@ -68,11 +67,11 @@ public class ProcessHelper { * thrown if TempProcess contains undefined metadata */ public static List transformToProcessDetails(TempProcess tempProcess, - RulesetManagementInterface managementInterface, String acquisitionStage, + RulesetManagementInterface rulesetManagement, String acquisitionStage, List priorityList) throws InvalidMetadataValueException, NoSuchMetadataFieldException { ProcessFieldedMetadata metadata = initializeProcessDetails(tempProcess.getWorkpiece().getLogicalStructure(), - managementInterface, acquisitionStage, priorityList); + rulesetManagement, acquisitionStage, priorityList); metadata.preserve(); return metadata.getRows(); } @@ -85,8 +84,8 @@ public static List transformToProcessDetails(TempProcess tempProc * * @param structure * LogicalDivision for which to create a ProcessFieldedMetadata - * @param managementInterface - * RulesetManagementInterface used to create ProcessFieldedMetadata + * @param rulesetManagement + * Ruleset management used to create ProcessFieldedMetadata * @param stage * String containing acquisition stage used to create * ProcessFieldedMetadata @@ -96,8 +95,8 @@ public static List transformToProcessDetails(TempProcess tempProc * @return the created ProcessFieldedMetadata */ public static ProcessFieldedMetadata initializeProcessDetails(LogicalDivision structure, - RulesetManagementInterface managementInterface, String stage, List priorityList) { - StructuralElementViewInterface divisionView = managementInterface.getStructuralElementView(structure.getType(), + RulesetManagementInterface rulesetManagement, String stage, List priorityList) { + StructuralElementViewInterface divisionView = rulesetManagement.getStructuralElementView(structure.getType(), stage, priorityList); return new ProcessFieldedMetadata(structure, divisionView); } @@ -113,8 +112,8 @@ public static ProcessFieldedMetadata initializeProcessDetails(LogicalDivision st * the parent temp processes * @param docType * current division - * @param rulesetManagementInterface - * interface that provides access to the ruleset + * @param rulesetManagement + * current ruleset management * @param acquisitionStage * current acquisition level * @param priorityList @@ -124,9 +123,9 @@ public static ProcessFieldedMetadata initializeProcessDetails(LogicalDivision st */ public static void generateAtstslFields(TempProcess tempProcess, List processDetails, List parentTempProcesses, String docType, - RulesetManagementInterface rulesetManagementInterface, String acquisitionStage, + RulesetManagementInterface rulesetManagement, String acquisitionStage, List priorityList) throws ProcessGenerationException { - generateAtstslFields(tempProcess, processDetails, parentTempProcesses, docType, rulesetManagementInterface, acquisitionStage, + generateAtstslFields(tempProcess, processDetails, parentTempProcesses, docType, rulesetManagement, acquisitionStage, priorityList, null, false); } @@ -154,13 +153,13 @@ public static void generateAtstslFields(TempProcess tempProcess, List priorityList = ServiceManager.getUserService().getCurrentMetadataLanguage(); String docType = tempProcess.getWorkpiece().getLogicalStructure().getType(); - List processDetails = transformToProcessDetails(tempProcess, rulesetManagementInterface, + List processDetails = transformToProcessDetails(tempProcess, rulesetManagement, acquisitionStage, priorityList); - generateAtstslFields(tempProcess, processDetails, parentTempProcesses, docType, rulesetManagementInterface, + generateAtstslFields(tempProcess, processDetails, parentTempProcesses, docType, rulesetManagement, acquisitionStage, priorityList, null, force); } @@ -175,8 +174,8 @@ public static void generateAtstslFields(TempProcess tempProcess, List processDetails, List parentTempProcesses, String docType, - RulesetManagementInterface rulesetManagementInterface, String acquisitionStage, + RulesetManagementInterface rulesetManagement, String acquisitionStage, List priorityList, Process parentProcess, boolean force) throws ProcessGenerationException { if (!shouldGenerateAtstslFields(tempProcess) && !force) { return; } - String titleDefinition = getTitleDefinition(rulesetManagementInterface, docType, acquisitionStage, + String titleDefinition = getTitleDefinition(rulesetManagement, docType, acquisitionStage, priorityList); String currentTitle = TitleGenerator.getValueOfMetadataID(TitleGenerator.TITLE_DOC_MAIN, processDetails); if (StringUtils.isBlank(currentTitle)) { @@ -207,7 +206,7 @@ public static void generateAtstslFields(TempProcess tempProcess, List priorityList) { - StructuralElementViewInterface docTypeView = rulesetManagementInterface.getStructuralElementView(docType, + StructuralElementViewInterface docTypeView = rulesetManagement.getStructuralElementView(docType, acquisitionStage, priorityList); return docTypeView.getProcessTitle().orElse(""); } @@ -328,7 +327,7 @@ private static String getTitleFromWorkpiece(Process process) { } private static String getTitleFromParents(List parentTempProcesses, - RulesetManagementInterface rulesetManagementInterface, String acquisitionStage, + RulesetManagementInterface rulesetManagement, String acquisitionStage, List priorityList) { if (parentTempProcesses.size() == 0) { return StringUtils.EMPTY; @@ -338,7 +337,7 @@ private static String getTitleFromParents(List parentTempProcesses, String title; if (Objects.nonNull(tempProcess.getMetadataNodes())) { ProcessFieldedMetadata processFieldedMetadata = initializeTempProcessDetails(tempProcess, - rulesetManagementInterface, acquisitionStage, priorityList); + rulesetManagement, acquisitionStage, priorityList); title = getTitleFromMetadata(processFieldedMetadata.getChildMetadata()); } else { title = getTitleFromWorkpiece(tempProcess.getProcess()); @@ -352,10 +351,10 @@ private static String getTitleFromParents(List parentTempProcesses, } private static ProcessFieldedMetadata initializeTempProcessDetails(TempProcess tempProcess, - RulesetManagementInterface rulesetManagementInterface, String acquisitionStage, + RulesetManagementInterface rulesetManagement, String acquisitionStage, List priorityList) { ProcessFieldedMetadata metadata = initializeProcessDetails(tempProcess.getWorkpiece().getLogicalStructure(), - rulesetManagementInterface, acquisitionStage, priorityList); + rulesetManagement, acquisitionStage, priorityList); metadata.setMetadata(convertMetadata(tempProcess.getMetadataNodes(), MdSec.DMD_SEC)); return metadata; } diff --git a/Kitodo/src/main/java/org/kitodo/production/helper/metadata/legacytypeimplementations/LegacyMetadataHelper.java b/Kitodo/src/main/java/org/kitodo/production/helper/metadata/legacytypeimplementations/LegacyMetadataHelper.java index 4bc2931e625..5b13bbfb9af 100644 --- a/Kitodo/src/main/java/org/kitodo/production/helper/metadata/legacytypeimplementations/LegacyMetadataHelper.java +++ b/Kitodo/src/main/java/org/kitodo/production/helper/metadata/legacytypeimplementations/LegacyMetadataHelper.java @@ -35,7 +35,7 @@ public class LegacyMetadataHelper { */ private LegacyInnerPhysicalDocStructHelper legacyInnerPhysicalDocStructHelper; - private BindingSaveInterface bindingSaveInterface; + private BindingSaveInterface bindingSaver; private MetadataEntry binding; @@ -78,7 +78,7 @@ public String getValue() { * This allows the metadata to be saved. */ public void saveToBinding() { - bindingSaveInterface.saveMetadata(this); + bindingSaver.saveMetadata(this); } /** @@ -88,7 +88,7 @@ public void saveToBinding() { * the value may be, aside from the value of a metadata entry, the value of * a field of the container, which makes the matter a bit unwieldy. * - * @param bsi + * @param bindingSaver * thee binding save interface via which the metadata can * automatically save itself afterwards * @param binding @@ -97,8 +97,8 @@ public void saveToBinding() { * @param domain * the domain where the metadata entry is stored */ - public void setBinding(BindingSaveInterface bsi, MetadataEntry binding, Domain domain) { - this.bindingSaveInterface = bsi; + public void setBinding(BindingSaveInterface bindingSaver, MetadataEntry binding, Domain domain) { + this.bindingSaver = bindingSaver; this.binding = binding; this.domain = domain; } @@ -124,7 +124,7 @@ public void setDocStruct(LegacyDocStructHelperInterface docStruct) { @Deprecated public void setStringValue(String value) { this.value = value; - if (bindingSaveInterface != null) { + if (bindingSaver != null) { saveToBinding(); } } diff --git a/Kitodo/src/main/java/org/kitodo/production/metadata/MetadataEditor.java b/Kitodo/src/main/java/org/kitodo/production/metadata/MetadataEditor.java index 2350339b1e2..037fe7c1284 100644 --- a/Kitodo/src/main/java/org/kitodo/production/metadata/MetadataEditor.java +++ b/Kitodo/src/main/java/org/kitodo/production/metadata/MetadataEditor.java @@ -224,17 +224,17 @@ private static void addMultipleStructuresWithMetadataGroup(int number, String ty * inserted * @param position * relative insertion position - * @param metadataViewInterface - * interface of the metadata to be added + * @param metadataView + * view on the metadata to be added * @param metadataValue * value of the first metadata entry */ public static void addMultipleStructuresWithMetadata(int number, String type, Workpiece workpiece, LogicalDivision structure, - InsertionPosition position, MetadataViewInterface metadataViewInterface, String metadataValue) { + InsertionPosition position, MetadataViewInterface metadataView, String metadataValue) { - String metadataKey = metadataViewInterface.getId(); + String metadataKey = metadataView.getId(); - if (metadataViewInterface.isComplex()) { + if (metadataView.isComplex()) { addMultipleStructuresWithMetadataGroup(number, type, workpiece, structure, position, metadataKey); } else { addMultipleStructuresWithMetadataEntry(number, type, workpiece, structure, position, metadataKey, metadataValue); diff --git a/Kitodo/src/main/java/org/kitodo/production/services/command/CommandService.java b/Kitodo/src/main/java/org/kitodo/production/services/command/CommandService.java index 83c39986da1..4ce4a48a962 100644 --- a/Kitodo/src/main/java/org/kitodo/production/services/command/CommandService.java +++ b/Kitodo/src/main/java/org/kitodo/production/services/command/CommandService.java @@ -109,11 +109,8 @@ public CommandResult runCommand(File scriptFile) throws IOException { */ public void runCommandAsync(String script) { if (Objects.nonNull(script)) { - KitodoServiceLoader serviceLoader = new KitodoServiceLoader<>(CommandInterface.class); - CommandInterface commandInterface = serviceLoader.loadModule(); - Flowable source = Flowable.fromCallable(() -> - commandInterface.runCommand(random.nextInt(), script) + commandModule.runCommand(random.nextInt(), script) ); Flowable commandBackgroundWorker = source.subscribeOn(Schedulers.io()); diff --git a/Kitodo/src/main/java/org/kitodo/production/services/data/ImportService.java b/Kitodo/src/main/java/org/kitodo/production/services/data/ImportService.java index 676b51d19ea..d508e206198 100644 --- a/Kitodo/src/main/java/org/kitodo/production/services/data/ImportService.java +++ b/Kitodo/src/main/java/org/kitodo/production/services/data/ImportService.java @@ -1028,7 +1028,7 @@ public static boolean ensureNonEmptyTitles(LinkedList tempProcesses * @throws ProcessGenerationException thrown if process title cannot be created */ public static void processProcessChildren(Process mainProcess, LinkedList childProcesses, - RulesetManagementInterface managementInterface, String acquisitionStage, + RulesetManagementInterface rulesetManagement, String acquisitionStage, List priorityList) throws DataException, InvalidMetadataValueException, NoSuchMetadataFieldException, ProcessGenerationException, IOException { @@ -1037,7 +1037,7 @@ public static void processProcessChildren(Process mainProcess, LinkedList Skip!", childProcesses.indexOf(tempProcess) + 1); continue; } - processTempProcess(tempProcess, managementInterface, acquisitionStage, priorityList, null); + processTempProcess(tempProcess, rulesetManagement, acquisitionStage, priorityList, null); Process childProcess = tempProcess.getProcess(); ServiceManager.getProcessService().save(childProcess, true); ProcessService.setParentRelations(mainProcess, childProcess); @@ -1128,19 +1128,19 @@ public static void updateTasks(Process process) { * updating the process' tasks. * * @param tempProcess TempProcess that will be processed - * @param managementInterface RulesetManagementInterface to create metadata and tiff header + * @param rulesetManagement Ruleset management to create metadata and TIFF header * @param acquisitionStage String containing the acquisition stage * @param priorityList List of LanguageRange objects * @throws InvalidMetadataValueException thrown if the process contains invalid metadata * @throws NoSuchMetadataFieldException thrown if the process contains undefined metadata * @throws ProcessGenerationException thrown if process title could not be generated */ - public static void processTempProcess(TempProcess tempProcess, RulesetManagementInterface managementInterface, + public static void processTempProcess(TempProcess tempProcess, RulesetManagementInterface rulesetManagement, String acquisitionStage, List priorityList, TempProcess parentTempProcess) throws InvalidMetadataValueException, NoSuchMetadataFieldException, ProcessGenerationException, IOException { - List processDetails = ProcessHelper.transformToProcessDetails(tempProcess, managementInterface, + List processDetails = ProcessHelper.transformToProcessDetails(tempProcess, rulesetManagement, acquisitionStage, priorityList); String docType = tempProcess.getWorkpiece().getLogicalStructure().getType(); @@ -1149,7 +1149,7 @@ public static void processTempProcess(TempProcess tempProcess, RulesetManagement parentTempProcesses.add(parentTempProcess); } ProcessHelper.generateAtstslFields(tempProcess, processDetails, parentTempProcesses, docType, - managementInterface, acquisitionStage, priorityList); + rulesetManagement, acquisitionStage, priorityList); if (!ProcessValidator.isProcessTitleCorrect(tempProcess.getProcess().getTitle())) { throw new ProcessGenerationException("Unable to create process"); @@ -1353,24 +1353,24 @@ private HashMap getUrlParameters(ImportConfiguration importConfi /** * Check and return whether the functional metadata 'recordIdentifier' is configured for all top level doc struct * types in the given RulesetManagementInterface or not. - * @param rulesetManagementInterface RulesetManagementInterface to use + * @param rulesetManagement Ruleset management to use * @return whether 'recordIdentifier' is set for all doc struct types */ - public boolean isRecordIdentifierMetadataConfigured(RulesetManagementInterface rulesetManagementInterface) { + public boolean isRecordIdentifierMetadataConfigured(RulesetManagementInterface rulesetManagement) { User user = ServiceManager.getUserService().getCurrentUser(); String metadataLanguage = user.getMetadataLanguage(); List languages = Locale.LanguageRange.parse(metadataLanguage.isEmpty() ? Locale.ENGLISH.getCountry() : metadataLanguage); - Map structuralElements = rulesetManagementInterface.getStructuralElements(languages); - Collection recordIdentifierMetadata = rulesetManagementInterface + Map structuralElements = rulesetManagement.getStructuralElements(languages); + Collection recordIdentifierMetadata = rulesetManagement .getFunctionalKeys(FunctionalMetadata.RECORD_IDENTIFIER); String recordIdentifierLabels = recordIdentifierMetadata.stream() - .map(key -> rulesetManagementInterface.getTranslationForKey(key, languages).orElse(key)) + .map(key -> rulesetManagement.getTranslationForKey(key, languages).orElse(key)) .collect(Collectors.joining(", ")); recordIdentifierMissingDetails.clear(); boolean isConfigured = true; for (Map.Entry division : structuralElements.entrySet()) { - StructuralElementViewInterface divisionView = rulesetManagementInterface + StructuralElementViewInterface divisionView = rulesetManagement .getStructuralElementView(division.getKey(), ACQUISITION_STAGE_CREATE, languages); List allowedMetadataKeys = divisionView.getAllowedMetadata().stream() .map(MetadataViewInterface::getId).collect(Collectors.toList()); diff --git a/Kitodo/src/test/java/org/kitodo/production/helper/ProcessHelperIT.java b/Kitodo/src/test/java/org/kitodo/production/helper/ProcessHelperIT.java index 307d1a5be1e..8ae66989638 100644 --- a/Kitodo/src/test/java/org/kitodo/production/helper/ProcessHelperIT.java +++ b/Kitodo/src/test/java/org/kitodo/production/helper/ProcessHelperIT.java @@ -80,28 +80,28 @@ public void generateAtstslFields() throws DAOException, ProcessGenerationExcepti process.setProject(ServiceManager.getProjectService().getById(1)); process.setRuleset(ServiceManager.getRulesetService().getById(1)); TempProcess tempProcess = new TempProcess(process, new Workpiece()); - RulesetManagementInterface rulesetManagementInterface = ServiceManager.getRulesetService() + RulesetManagementInterface rulesetManagement = ServiceManager.getRulesetService() .openRuleset(tempProcess.getProcess().getRuleset()); - testGenerationOfAtstslByCurrentTempProcess(tempProcess, rulesetManagementInterface); + testGenerationOfAtstslByCurrentTempProcess(tempProcess, rulesetManagement); - testForceRegenerationOfAtstsl(tempProcess, rulesetManagementInterface); + testForceRegenerationOfAtstsl(tempProcess, rulesetManagement); - testForceRegenerationByTempProcessParents(tempProcess, rulesetManagementInterface); + testForceRegenerationByTempProcessParents(tempProcess, rulesetManagement); - testForceRegenerationByParentProcess(tempProcess, rulesetManagementInterface); + testForceRegenerationByParentProcess(tempProcess, rulesetManagement); } private void testForceRegenerationByParentProcess(TempProcess tempProcess, - RulesetManagementInterface rulesetManagementInterface) throws ProcessGenerationException, DAOException { + RulesetManagementInterface rulesetManagement) throws ProcessGenerationException, DAOException { ProcessHelper.generateAtstslFields(tempProcess, tempProcess.getProcessMetadata().getProcessDetailsElements(), - null, DOCTYPE, rulesetManagementInterface, ACQUISITION_STAGE_CREATE, priorityList, + null, DOCTYPE, rulesetManagement, ACQUISITION_STAGE_CREATE, priorityList, ServiceManager.getProcessService().getById(2), true); assertEquals("Secopr", tempProcess.getAtstsl()); } private void testForceRegenerationByTempProcessParents(TempProcess tempProcess, - RulesetManagementInterface rulesetManagementInterface) throws DAOException, ProcessGenerationException { + RulesetManagementInterface rulesetManagement) throws DAOException, ProcessGenerationException { TempProcess tempProcessParent = new TempProcess(ServiceManager.getProcessService().getById(2), new Workpiece()); tempProcess.getProcessMetadata().setProcessDetails(new ProcessFieldedMetadata() { { @@ -110,23 +110,23 @@ private void testForceRegenerationByTempProcessParents(TempProcess tempProcess, } }); ProcessHelper.generateAtstslFields(tempProcess, tempProcess.getProcessMetadata().getProcessDetailsElements(), - Collections.singletonList(tempProcessParent), DOCTYPE, rulesetManagementInterface, + Collections.singletonList(tempProcessParent), DOCTYPE, rulesetManagement, ACQUISITION_STAGE_CREATE, priorityList, null, true); assertEquals("Secopr", tempProcess.getAtstsl()); } private void testForceRegenerationOfAtstsl(TempProcess tempProcess, - RulesetManagementInterface rulesetManagementInterface) throws ProcessGenerationException { + RulesetManagementInterface rulesetManagement) throws ProcessGenerationException { ProcessHelper.generateAtstslFields(tempProcess, tempProcess.getProcessMetadata().getProcessDetailsElements(), - null, DOCTYPE, rulesetManagementInterface, ACQUISITION_STAGE_CREATE, priorityList, null, false); + null, DOCTYPE, rulesetManagement, ACQUISITION_STAGE_CREATE, priorityList, null, false); assertEquals("test", tempProcess.getAtstsl()); ProcessHelper.generateAtstslFields(tempProcess, tempProcess.getProcessMetadata().getProcessDetailsElements(), - null, DOCTYPE, rulesetManagementInterface, ACQUISITION_STAGE_CREATE, priorityList, null, true); + null, DOCTYPE, rulesetManagement, ACQUISITION_STAGE_CREATE, priorityList, null, true); assertEquals("test2", tempProcess.getAtstsl()); } private void testGenerationOfAtstslByCurrentTempProcess(TempProcess tempProcess, - RulesetManagementInterface rulesetManagementInterface) throws ProcessGenerationException { + RulesetManagementInterface rulesetManagement) throws ProcessGenerationException { tempProcess.getProcessMetadata().setProcessDetails(new ProcessFieldedMetadata() { { treeNode.getChildren() @@ -135,7 +135,7 @@ private void testGenerationOfAtstslByCurrentTempProcess(TempProcess tempProcess, }); assertNull(tempProcess.getAtstsl()); ProcessHelper.generateAtstslFields(tempProcess, tempProcess.getProcessMetadata().getProcessDetailsElements(), - null, DOCTYPE, rulesetManagementInterface, ACQUISITION_STAGE_CREATE, priorityList, null, false); + null, DOCTYPE, rulesetManagement, ACQUISITION_STAGE_CREATE, priorityList, null, false); assertEquals("test", tempProcess.getAtstsl()); tempProcess.getProcessMetadata().setProcessDetails(new ProcessFieldedMetadata() { { diff --git a/Kitodo/src/test/java/org/kitodo/production/process/ProcessValidatorIT.java b/Kitodo/src/test/java/org/kitodo/production/process/ProcessValidatorIT.java index 147ec62d0c1..c59bc6f126b 100644 --- a/Kitodo/src/test/java/org/kitodo/production/process/ProcessValidatorIT.java +++ b/Kitodo/src/test/java/org/kitodo/production/process/ProcessValidatorIT.java @@ -110,9 +110,9 @@ public void propertyShouldNotExist() throws Exception { private List createProcessDetailsList() throws IOException { Workpiece workpiece = new Workpiece(); workpiece.getLogicalStructure().setType("Monograph"); - RulesetManagementInterface rulesetManagementInterface = ServiceManager.getRulesetManagementService().getRulesetManagement(); - rulesetManagementInterface.load(new File("src/test/resources/rulesets/monograph.xml")); - StructuralElementViewInterface monograph = rulesetManagementInterface.getStructuralElementView( + RulesetManagementInterface rulesetManagement = ServiceManager.getRulesetManagementService().getRulesetManagement(); + rulesetManagement.load(new File("src/test/resources/rulesets/monograph.xml")); + StructuralElementViewInterface monograph = rulesetManagement.getStructuralElementView( "Monograph", "", Locale.LanguageRange.parse("en")); ProcessFieldedMetadata processDetails = new ProcessFieldedMetadata(workpiece.getLogicalStructure(), monograph); for (ProcessDetail detail : processDetails.getRows()) { diff --git a/Kitodo/src/test/java/org/kitodo/production/process/TitleGeneratorTest.java b/Kitodo/src/test/java/org/kitodo/production/process/TitleGeneratorTest.java index d5db365ed82..d27432d8781 100644 --- a/Kitodo/src/test/java/org/kitodo/production/process/TitleGeneratorTest.java +++ b/Kitodo/src/test/java/org/kitodo/production/process/TitleGeneratorTest.java @@ -102,9 +102,9 @@ public void shouldGenerateTitle() throws Exception { static List createProcessDetailsList() throws IOException { Workpiece workpiece = new Workpiece(); workpiece.getLogicalStructure().setType("Monograph"); - RulesetManagementInterface rulesetManagementInterface = ServiceManager.getRulesetManagementService().getRulesetManagement(); - rulesetManagementInterface.load(new File("src/test/resources/rulesets/monograph.xml")); - StructuralElementViewInterface monograph = rulesetManagementInterface.getStructuralElementView( + RulesetManagementInterface rulesetManagement = ServiceManager.getRulesetManagementService().getRulesetManagement(); + rulesetManagement.load(new File("src/test/resources/rulesets/monograph.xml")); + StructuralElementViewInterface monograph = rulesetManagement.getStructuralElementView( "Monograph", "", Locale.LanguageRange.parse("en")); ProcessFieldedMetadata processDetails = new ProcessFieldedMetadata(workpiece.getLogicalStructure(), monograph); for (ProcessDetail detail : processDetails.getRows()) { diff --git a/Kitodo/src/test/java/org/kitodo/utils/ProcessTestUtils.java b/Kitodo/src/test/java/org/kitodo/utils/ProcessTestUtils.java index 73d0ef4abd3..9c46bdc8348 100644 --- a/Kitodo/src/test/java/org/kitodo/utils/ProcessTestUtils.java +++ b/Kitodo/src/test/java/org/kitodo/utils/ProcessTestUtils.java @@ -42,9 +42,9 @@ public static DefaultTreeNode getTreeNode(String metadataId, String metadataKey, } private static SimpleMetadataViewInterface getSimpleMetadataView(String metadataId) { - SimpleMetadataViewInterface simpleMetadataViewInterface = mock(SimpleMetadataViewInterface.class); - when(simpleMetadataViewInterface.getId()).thenReturn(metadataId); - return simpleMetadataViewInterface; + SimpleMetadataViewInterface simpleMetadataView = mock(SimpleMetadataViewInterface.class); + when(simpleMetadataView.getId()).thenReturn(metadataId); + return simpleMetadataView; } } From 4e6dd2d8bc9bc8d42eb567871769b2271f8155f8 Mon Sep 17 00:00:00 2001 From: Arved Solth Date: Thu, 1 Jun 2023 16:33:24 +0200 Subject: [PATCH 28/72] Turn off auto width for pulldown menus --- .../includes/metadataEditor/dialogs/addDocStrucType.xhtml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Kitodo/src/main/webapp/WEB-INF/templates/includes/metadataEditor/dialogs/addDocStrucType.xhtml b/Kitodo/src/main/webapp/WEB-INF/templates/includes/metadataEditor/dialogs/addDocStrucType.xhtml index dbcfaacdb3b..5740ed557ae 100644 --- a/Kitodo/src/main/webapp/WEB-INF/templates/includes/metadataEditor/dialogs/addDocStrucType.xhtml +++ b/Kitodo/src/main/webapp/WEB-INF/templates/includes/metadataEditor/dialogs/addDocStrucType.xhtml @@ -113,6 +113,7 @@ disabled="#{DataEditorForm.addDocStrucTypeDialog.elementsToAddSpinnerValue gt 1}" class="input" value="#{DataEditorForm.addDocStrucTypeDialog.selectFirstPageOnAddNode}" + autoWidth="false" filter="true" filterMatchMode="contains"> Date: Thu, 1 Jun 2023 17:37:21 +0200 Subject: [PATCH 29/72] Improve scrolling with large number of images --- Kitodo/src/main/webapp/WEB-INF/resources/css/kitodo.css | 5 ++++- Kitodo/src/main/webapp/WEB-INF/resources/js/scroll.js | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Kitodo/src/main/webapp/WEB-INF/resources/css/kitodo.css b/Kitodo/src/main/webapp/WEB-INF/resources/css/kitodo.css index de14da398ea..36b26f2ba5f 100644 --- a/Kitodo/src/main/webapp/WEB-INF/resources/css/kitodo.css +++ b/Kitodo/src/main/webapp/WEB-INF/resources/css/kitodo.css @@ -3165,7 +3165,10 @@ Column content } #imagePreviewForm\:thumbnailWrapper .thumbnail-parent { - display: inline-block; + display: block; + margin-bottom: var(--group-margin); + margin-left: auto; + margin-right: auto; } #thumbnailStripeScrollableContent a { diff --git a/Kitodo/src/main/webapp/WEB-INF/resources/js/scroll.js b/Kitodo/src/main/webapp/WEB-INF/resources/js/scroll.js index d735d1d4453..cf42a63ef0e 100644 --- a/Kitodo/src/main/webapp/WEB-INF/resources/js/scroll.js +++ b/Kitodo/src/main/webapp/WEB-INF/resources/js/scroll.js @@ -157,7 +157,7 @@ function initializeStructureTreeScrolling() { } function scrollToPreviewThumbnail(thumbnail, scrollable) { - let thumbnailHeight = thumbnail.closest(".thumbnail-parent").height(); + let thumbnailHeight = thumbnail.closest(".thumbnail-parent").outerHeight(true); let selectedIndex = scrollable.find(".thumbnail + .thumbnail-container").index(thumbnail); if (selectedIndex >= 0) { scrollable.animate({ From f0e754774aa5cb610d708a2afd0122a9c935b4ba Mon Sep 17 00:00:00 2001 From: Henning Gerhardt Date: Fri, 5 May 2023 15:47:43 +0200 Subject: [PATCH 30/72] Fix async hierarchy export --- .../java/org/kitodo/export/ExportDms.java | 11 +++++----- .../helper/tasks/ExportDmsTask.java | 21 +++++++++++++++++-- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/Kitodo/src/main/java/org/kitodo/export/ExportDms.java b/Kitodo/src/main/java/org/kitodo/export/ExportDms.java index c6edd6386fe..93c38c3ee93 100644 --- a/Kitodo/src/main/java/org/kitodo/export/ExportDms.java +++ b/Kitodo/src/main/java/org/kitodo/export/ExportDms.java @@ -111,12 +111,11 @@ public boolean startExport(Process process) throws DataException { } boolean exportSuccessful = startExport(process, (URI) null); - if (exportSuccessful) { - if (Objects.nonNull(process.getParent())) { - startExport(process.getParent()); - } - } else if (wasNotAlreadyExported) { - process.setExported(false); + if (Objects.nonNull(process.getParent())) { + startExport(process.getParent()); + } + if (wasNotAlreadyExported) { + process.setExported(exportSuccessful); processService.save(process); } return exportSuccessful; diff --git a/Kitodo/src/main/java/org/kitodo/production/helper/tasks/ExportDmsTask.java b/Kitodo/src/main/java/org/kitodo/production/helper/tasks/ExportDmsTask.java index d42ba129a4c..e2a4603f6ac 100644 --- a/Kitodo/src/main/java/org/kitodo/production/helper/tasks/ExportDmsTask.java +++ b/Kitodo/src/main/java/org/kitodo/production/helper/tasks/ExportDmsTask.java @@ -14,10 +14,14 @@ import java.io.IOException; import java.util.Objects; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.kitodo.data.database.beans.Process; +import org.kitodo.data.database.beans.Task; import org.kitodo.data.database.exceptions.DAOException; import org.kitodo.data.exceptions.DataException; import org.kitodo.export.ExportDms; +import org.kitodo.production.services.ServiceManager; import org.kitodo.production.services.workflow.WorkflowControllerService; /** @@ -28,6 +32,8 @@ */ public class ExportDmsTask extends EmptyTask { + private static final Logger logger = LogManager.getLogger(ExportDmsTask.class); + private final ExportDms exportDms; private final Process process; @@ -67,14 +73,25 @@ private ExportDmsTask(ExportDmsTask source) { */ @Override public void run() { + boolean exportSuccessful; try { - boolean exportSuccessful = exportDms.startExport(process, this); - if (Objects.nonNull(exportDms.getWorkflowTask()) && exportSuccessful) { + exportSuccessful = exportDms.startExport(process, this); + Task workflowTask = exportDms.getWorkflowTask(); + if (Objects.nonNull(workflowTask) + && workflowTask.getProcess().getId().equals(process.getId()) + && exportSuccessful) { setProgress(100); new WorkflowControllerService().close(exportDms.getWorkflowTask()); } } catch (RuntimeException | DataException | IOException | DAOException e) { setException(e); + exportSuccessful = false; + } + try { + process.setExported(exportSuccessful); + ServiceManager.getProcessService().save(process); + } catch (DataException e) { + logger.error(e.getMessage(), e); } } From a53b0ce1b3fd60577e12477472a4fd52e64f48f9 Mon Sep 17 00:00:00 2001 From: Henning Gerhardt Date: Fri, 5 May 2023 16:32:14 +0200 Subject: [PATCH 31/72] Add an explanation which task should only be closed --- .../java/org/kitodo/production/helper/tasks/ExportDmsTask.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Kitodo/src/main/java/org/kitodo/production/helper/tasks/ExportDmsTask.java b/Kitodo/src/main/java/org/kitodo/production/helper/tasks/ExportDmsTask.java index e2a4603f6ac..c44fc5cc30f 100644 --- a/Kitodo/src/main/java/org/kitodo/production/helper/tasks/ExportDmsTask.java +++ b/Kitodo/src/main/java/org/kitodo/production/helper/tasks/ExportDmsTask.java @@ -77,6 +77,7 @@ public void run() { try { exportSuccessful = exportDms.startExport(process, this); Task workflowTask = exportDms.getWorkflowTask(); + // close only the task of the original process and not of other processes (parent process, other child processes) if (Objects.nonNull(workflowTask) && workflowTask.getProcess().getId().equals(process.getId()) && exportSuccessful) { From 4364fe8944a3db8c101aa87427318eb6ffd34a0b Mon Sep 17 00:00:00 2001 From: Henning Gerhardt Date: Wed, 10 May 2023 13:32:19 +0200 Subject: [PATCH 32/72] Replace old with new value for sortHelperStatus --- ...23__Replace_old_sorthelperstatus_value.sql | 21 ++++++++++ .../java/org/kitodo/export/ExportDms.java | 5 ++- .../kitodo/production/enums/ProcessState.java | 40 +++++++++++++++++++ .../helper/tasks/HierarchyMigrationTask.java | 3 +- .../migration/NewspaperProcessesMigrator.java | 3 +- .../services/data/ProcessService.java | 7 +++- .../workflow/WorkflowControllerService.java | 7 ++-- .../test/java/org/kitodo/MockDatabase.java | 3 +- .../services/data/ProcessServiceIT.java | 4 +- 9 files changed, 81 insertions(+), 12 deletions(-) create mode 100644 Kitodo-DataManagement/src/main/resources/db/migration/V2_123__Replace_old_sorthelperstatus_value.sql create mode 100644 Kitodo/src/main/java/org/kitodo/production/enums/ProcessState.java diff --git a/Kitodo-DataManagement/src/main/resources/db/migration/V2_123__Replace_old_sorthelperstatus_value.sql b/Kitodo-DataManagement/src/main/resources/db/migration/V2_123__Replace_old_sorthelperstatus_value.sql new file mode 100644 index 00000000000..1f7c26e00d5 --- /dev/null +++ b/Kitodo-DataManagement/src/main/resources/db/migration/V2_123__Replace_old_sorthelperstatus_value.sql @@ -0,0 +1,21 @@ +-- +-- (c) Kitodo. Key to digital objects e. V. +-- +-- This file is part of the Kitodo project. +-- +-- It is licensed under GNU General Public License version 3 or later. +-- +-- For the full copyright and license information, please read the +-- GPL3-License.txt file that was distributed with this source code. +-- + +-- 1. Disable safe updates +-- +SET SQL_SAFE_UPDATES = 0; + +-- 2. Replace old sortHelperStatus from "100000000" to "100000000000" +UPDATE process SET sortHelperStatus = "100000000000" WHERE sortHelperStatus = "100000000"; + +-- 3. Enable safe updates +-- +SET SQL_SAFE_UPDATES = 1; diff --git a/Kitodo/src/main/java/org/kitodo/export/ExportDms.java b/Kitodo/src/main/java/org/kitodo/export/ExportDms.java index c6edd6386fe..f3c7d9d25d7 100644 --- a/Kitodo/src/main/java/org/kitodo/export/ExportDms.java +++ b/Kitodo/src/main/java/org/kitodo/export/ExportDms.java @@ -35,6 +35,7 @@ import org.kitodo.data.exceptions.DataException; import org.kitodo.exceptions.ExportException; import org.kitodo.exceptions.MetadataException; +import org.kitodo.production.enums.ProcessState; import org.kitodo.production.helper.Helper; import org.kitodo.production.helper.VariableReplacer; import org.kitodo.production.helper.metadata.legacytypeimplementations.LegacyDocStructHelperInterface; @@ -54,7 +55,6 @@ public class ExportDms extends ExportMets { private static final Logger logger = LogManager.getLogger(ExportDms.class); - private static final String COMPLETED = "100000000000"; private static final String EXPORT_DIR_DELETE = "errorDirectoryDeleting"; private static final String ERROR_EXPORT = "errorExport"; @@ -210,7 +210,8 @@ private boolean startExport(Process process, LegacyMetsModsDigitalDocumentHelper private boolean exportCompletedChildren(List children) throws DataException { for (Process child:children) { - if (ProcessConverter.getCombinedProgressAsString(child, false).equals(COMPLETED) && !child.isExported()) { + if (ProcessConverter.getCombinedProgressAsString(child, false).equals(ProcessState.COMPLETED.getValue()) + && !child.isExported()) { if (!startExport(child)) { return false; } diff --git a/Kitodo/src/main/java/org/kitodo/production/enums/ProcessState.java b/Kitodo/src/main/java/org/kitodo/production/enums/ProcessState.java new file mode 100644 index 00000000000..e7ed7c9fe1e --- /dev/null +++ b/Kitodo/src/main/java/org/kitodo/production/enums/ProcessState.java @@ -0,0 +1,40 @@ +/* + * (c) Kitodo. Key to digital objects e. V. + * + * This file is part of the Kitodo project. + * + * It is licensed under GNU General Public License version 3 or later. + * + * For the full copyright and license information, please read the + * GPL3-License.txt file that was distributed with this source code. + */ + +package org.kitodo.production.enums; + +public enum ProcessState { + + /** + * Use this enum for completed processes. + */ + COMPLETED("100000000000"), + + /** + * Do not use this enum except you need to stay compatible with Kitodo.Production 2.x values. + */ + COMPLETED20("100000000"); + + private final String value; + + private ProcessState(String value) { + this.value = value; + } + + /** + * Get the value of used enum entry. + * + * @return value of used enum entry + */ + public String getValue() { + return value; + } +} diff --git a/Kitodo/src/main/java/org/kitodo/production/helper/tasks/HierarchyMigrationTask.java b/Kitodo/src/main/java/org/kitodo/production/helper/tasks/HierarchyMigrationTask.java index 973e86ae016..e2f28c86990 100644 --- a/Kitodo/src/main/java/org/kitodo/production/helper/tasks/HierarchyMigrationTask.java +++ b/Kitodo/src/main/java/org/kitodo/production/helper/tasks/HierarchyMigrationTask.java @@ -35,6 +35,7 @@ import org.kitodo.data.database.exceptions.DAOException; import org.kitodo.exceptions.CommandException; import org.kitodo.exceptions.ProcessGenerationException; +import org.kitodo.production.enums.ProcessState; import org.kitodo.production.helper.Helper; import org.kitodo.production.metadata.MetadataEditor; import org.kitodo.production.process.ProcessGenerator; @@ -272,7 +273,7 @@ private void checkTaskAndId(Process parentProcess) throws IOException { workpiece.setId(parentProcess.getId().toString()); ServiceManager.getMetsService().saveWorkpiece(workpiece,parentMetadataFilePath); if (WorkflowControllerService.allChildrenClosed(parentProcess)) { - parentProcess.setSortHelperStatus("100000000"); + parentProcess.setSortHelperStatus(ProcessState.COMPLETED.getValue()); } } diff --git a/Kitodo/src/main/java/org/kitodo/production/migration/NewspaperProcessesMigrator.java b/Kitodo/src/main/java/org/kitodo/production/migration/NewspaperProcessesMigrator.java index 6570f675f77..9df3d199a44 100644 --- a/Kitodo/src/main/java/org/kitodo/production/migration/NewspaperProcessesMigrator.java +++ b/Kitodo/src/main/java/org/kitodo/production/migration/NewspaperProcessesMigrator.java @@ -54,6 +54,7 @@ import org.kitodo.data.exceptions.DataException; import org.kitodo.exceptions.CommandException; import org.kitodo.exceptions.ProcessGenerationException; +import org.kitodo.production.enums.ProcessState; import org.kitodo.production.helper.tasks.NewspaperMigrationTask; import org.kitodo.production.helper.tasks.TaskManager; import org.kitodo.production.metadata.MetadataEditor; @@ -658,7 +659,7 @@ public void createNextYearProcess() throws ProcessGenerationException, IOExcepti processService.saveToDatabase(child); } if (WorkflowControllerService.allChildrenClosed(yearProcess)) { - yearProcess.setSortHelperStatus("100000000"); + yearProcess.setSortHelperStatus(ProcessState.COMPLETED.getValue()); } processService.saveToDatabase(yearProcess); addToBatch(yearProcess); diff --git a/Kitodo/src/main/java/org/kitodo/production/services/data/ProcessService.java b/Kitodo/src/main/java/org/kitodo/production/services/data/ProcessService.java index 22569a97916..31f4218826d 100644 --- a/Kitodo/src/main/java/org/kitodo/production/services/data/ProcessService.java +++ b/Kitodo/src/main/java/org/kitodo/production/services/data/ProcessService.java @@ -137,6 +137,7 @@ import org.kitodo.production.dto.PropertyDTO; import org.kitodo.production.dto.TaskDTO; import org.kitodo.production.enums.ObjectType; +import org.kitodo.production.enums.ProcessState; import org.kitodo.production.helper.Helper; import org.kitodo.production.helper.SearchResultGeneration; import org.kitodo.production.helper.WebDav; @@ -856,8 +857,10 @@ List findByProjectIds(Set projectIds, boolean related) thro */ public QueryBuilder getQueryForClosedProcesses() { BoolQueryBuilder query = new BoolQueryBuilder(); - query.should(createSimpleQuery(ProcessTypeField.SORT_HELPER_STATUS.getKey(), "100000000", true)); - query.should(createSimpleQuery(ProcessTypeField.SORT_HELPER_STATUS.getKey(), "100000000000", true)); + query.should(createSimpleQuery( + ProcessTypeField.SORT_HELPER_STATUS.getKey(), ProcessState.COMPLETED20.getValue(), true)); + query.should(createSimpleQuery( + ProcessTypeField.SORT_HELPER_STATUS.getKey(), ProcessState.COMPLETED.getValue(), true)); return query; } diff --git a/Kitodo/src/main/java/org/kitodo/production/services/workflow/WorkflowControllerService.java b/Kitodo/src/main/java/org/kitodo/production/services/workflow/WorkflowControllerService.java index 0ee053fc5fb..67bb3726fcf 100644 --- a/Kitodo/src/main/java/org/kitodo/production/services/workflow/WorkflowControllerService.java +++ b/Kitodo/src/main/java/org/kitodo/production/services/workflow/WorkflowControllerService.java @@ -43,6 +43,7 @@ import org.kitodo.data.database.exceptions.DAOException; import org.kitodo.data.elasticsearch.index.converter.ProcessConverter; import org.kitodo.data.exceptions.DataException; +import org.kitodo.production.enums.ProcessState; import org.kitodo.production.helper.Helper; import org.kitodo.production.helper.VariableReplacer; import org.kitodo.production.helper.WebDav; @@ -263,8 +264,8 @@ public static boolean allChildrenClosed(Process process) { if (!process.getChildren().isEmpty()) { boolean allChildrenClosed = true; for (Process child : process.getChildren()) { - allChildrenClosed &= "100000000".equals(child.getSortHelperStatus()) - || "100000000000".equals(child.getSortHelperStatus()); + allChildrenClosed &= ProcessState.COMPLETED20.getValue().equals(child.getSortHelperStatus()) + || ProcessState.COMPLETED.getValue().equals(child.getSortHelperStatus()); } return allChildrenClosed; } @@ -455,7 +456,7 @@ private void activateTasksForClosedTask(Task closedTask) throws DataException, I private void closeParent(Process process) throws DataException { if (Objects.nonNull(process.getParent()) && allChildrenClosed(process.getParent())) { - process.getParent().setSortHelperStatus("100000000"); + process.getParent().setSortHelperStatus(ProcessState.COMPLETED.getValue()); ServiceManager.getProcessService().save(process.getParent()); closeParent(process.getParent()); } diff --git a/Kitodo/src/test/java/org/kitodo/MockDatabase.java b/Kitodo/src/test/java/org/kitodo/MockDatabase.java index 392ec336c77..d4ebf69ca5e 100644 --- a/Kitodo/src/test/java/org/kitodo/MockDatabase.java +++ b/Kitodo/src/test/java/org/kitodo/MockDatabase.java @@ -96,6 +96,7 @@ import org.kitodo.data.exceptions.DataException; import org.kitodo.exceptions.WorkflowException; import org.kitodo.production.enums.ObjectType; +import org.kitodo.production.enums.ProcessState; import org.kitodo.production.helper.Helper; import org.kitodo.production.process.ProcessGenerator; import org.kitodo.production.security.password.SecurityPasswordEncoder; @@ -618,7 +619,7 @@ private static void insertProcesses() throws DAOException, DataException { Project projectTwo = ServiceManager.getProjectService().getById(2); Process thirdProcess = new Process(); thirdProcess.setTitle("DBConnectionTest"); - thirdProcess.setSortHelperStatus("100000000"); + thirdProcess.setSortHelperStatus(ProcessState.COMPLETED.getValue()); thirdProcess.setProject(projectTwo); ServiceManager.getProcessService().save(thirdProcess); } diff --git a/Kitodo/src/test/java/org/kitodo/production/services/data/ProcessServiceIT.java b/Kitodo/src/test/java/org/kitodo/production/services/data/ProcessServiceIT.java index db60058fc05..7dc7b63b582 100644 --- a/Kitodo/src/test/java/org/kitodo/production/services/data/ProcessServiceIT.java +++ b/Kitodo/src/test/java/org/kitodo/production/services/data/ProcessServiceIT.java @@ -28,7 +28,6 @@ import java.util.Collections; import java.util.HashSet; import java.util.List; -import java.util.Set; import org.apache.commons.lang3.SystemUtils; import org.elasticsearch.index.query.Operator; @@ -58,6 +57,7 @@ import org.kitodo.data.elasticsearch.index.converter.ProcessConverter; import org.kitodo.data.exceptions.DataException; import org.kitodo.production.dto.ProcessDTO; +import org.kitodo.production.enums.ProcessState; import org.kitodo.production.helper.metadata.legacytypeimplementations.LegacyMetsModsDigitalDocumentHelper; import org.kitodo.production.helper.metadata.legacytypeimplementations.LegacyPrefsHelper; import org.kitodo.production.metadata.MetadataLock; @@ -451,7 +451,7 @@ public void testGetQueryForClosedProcesses() throws DataException, DAOException ProcessService processService = ServiceManager.getProcessService(); Process secondProcess = processService.getById(2); final String sortHelperStatusOld = secondProcess.getSortHelperStatus(); - secondProcess.setSortHelperStatus("100000000"); + secondProcess.setSortHelperStatus(ProcessState.COMPLETED.getValue()); processService.save(secondProcess); QueryBuilder querySortHelperStatusTrue = processService.getQueryForClosedProcesses(); From 4a9a8a70a658074647ef34cc2f911c0b062b2173 Mon Sep 17 00:00:00 2001 From: Arved Solth Date: Tue, 6 Jun 2023 15:50:56 +0200 Subject: [PATCH 33/72] Do not re-check boolean checkbox after adding metadata --- .../forms/createprocess/ProcessBooleanMetadata.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Kitodo/src/main/java/org/kitodo/production/forms/createprocess/ProcessBooleanMetadata.java b/Kitodo/src/main/java/org/kitodo/production/forms/createprocess/ProcessBooleanMetadata.java index 66fcc3c15b8..b006b43764f 100644 --- a/Kitodo/src/main/java/org/kitodo/production/forms/createprocess/ProcessBooleanMetadata.java +++ b/Kitodo/src/main/java/org/kitodo/production/forms/createprocess/ProcessBooleanMetadata.java @@ -18,6 +18,7 @@ import java.util.Optional; import java.util.function.BiConsumer; +import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.Pair; import org.kitodo.api.Metadata; import org.kitodo.api.MetadataEntry; @@ -47,7 +48,11 @@ public class ProcessBooleanMetadata extends ProcessSimpleMetadata implements Ser */ ProcessBooleanMetadata(ProcessFieldedMetadata container, SimpleMetadataViewInterface settings, MetadataEntry data) { super(container, settings, settings.getLabel()); - this.active = Objects.nonNull(data) || settings.getBooleanDefaultValue(); + if (Objects.isNull(data)) { + this.active = settings.getBooleanDefaultValue(); + } else { + this.active = StringUtils.isNotBlank(data.getValue()); + } } private ProcessBooleanMetadata(ProcessBooleanMetadata template) { From 5644d5413513aa94bb7bab98a6d8911e5c709263 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6hr?= Date: Mon, 12 Jun 2023 16:42:26 +0200 Subject: [PATCH 34/72] Fix order of logical and physical divisions when physical divisions are assigned multiple times --- .../forms/dataeditor/AddDocStrucTypeDialog.java | 2 -- .../production/forms/dataeditor/StructurePanel.java | 8 ++++++++ .../org/kitodo/production/metadata/MetadataEditor.java | 4 ++-- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/Kitodo/src/main/java/org/kitodo/production/forms/dataeditor/AddDocStrucTypeDialog.java b/Kitodo/src/main/java/org/kitodo/production/forms/dataeditor/AddDocStrucTypeDialog.java index ebbcf0cf41a..5a16e7b4bf2 100644 --- a/Kitodo/src/main/java/org/kitodo/production/forms/dataeditor/AddDocStrucTypeDialog.java +++ b/Kitodo/src/main/java/org/kitodo/production/forms/dataeditor/AddDocStrucTypeDialog.java @@ -136,8 +136,6 @@ public void addDocStruc(boolean preview) { dataEditor.getGalleryPanel().setGalleryViewMode(LIST_MODE); } try { - dataEditor.getStructurePanel().preserve(); - dataEditor.refreshStructurePanel(); dataEditor.getPaginationPanel().show(); } catch (UnknownTreeNodeDataException e) { Helper.setErrorMessage(e.getMessage()); diff --git a/Kitodo/src/main/java/org/kitodo/production/forms/dataeditor/StructurePanel.java b/Kitodo/src/main/java/org/kitodo/production/forms/dataeditor/StructurePanel.java index 39e18de7d1e..d5bcbb5e67c 100644 --- a/Kitodo/src/main/java/org/kitodo/production/forms/dataeditor/StructurePanel.java +++ b/Kitodo/src/main/java/org/kitodo/production/forms/dataeditor/StructurePanel.java @@ -1488,6 +1488,14 @@ private LogicalDivision preserveLogicalAndPhysicalRecursive(TreeNode treeNode) t } } } + /* + PhysicalDivisions assigned to multiple LogicalDivisions may lead to wrong order value. The order will be + incremented for each occurrence and not just the last one. The LogicalDivisions containing those + PhysicalDivisions must be set to the order value of their first PhysicalDivision. + */ + if (!structure.getViews().isEmpty()) { + structure.setOrder(structure.getViews().getFirst().getPhysicalDivision().getOrder()); + } return structure; } diff --git a/Kitodo/src/main/java/org/kitodo/production/metadata/MetadataEditor.java b/Kitodo/src/main/java/org/kitodo/production/metadata/MetadataEditor.java index 2350339b1e2..d15447e5e0a 100644 --- a/Kitodo/src/main/java/org/kitodo/production/metadata/MetadataEditor.java +++ b/Kitodo/src/main/java/org/kitodo/production/metadata/MetadataEditor.java @@ -329,8 +329,8 @@ private static void handlePosition(Workpiece workpiece, LogicalDivision logicalD List siblingOrderValues = Stream.concat(logicalDivision.getChildren().stream() .map(Division::getOrder), Stream.of(structureOrder)).sorted().collect(Collectors.toList()); - // new order must be set at correction location between existing siblings - logicalDivision.getChildren().add(siblingOrderValues.indexOf(structureOrder), newStructure); + // new order must be set at correct location between existing siblings + logicalDivision.getChildren().add(siblingOrderValues.lastIndexOf(structureOrder), newStructure); } break; case FIRST_CHILD_OF_CURRENT_ELEMENT: From a9ce01894b0447b569ec45924c6866fd6f30b979 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6hr?= Date: Thu, 6 Jul 2023 16:54:57 +0200 Subject: [PATCH 35/72] Improve layout of parsed filters --- Kitodo/src/main/webapp/WEB-INF/resources/css/kitodo.css | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Kitodo/src/main/webapp/WEB-INF/resources/css/kitodo.css b/Kitodo/src/main/webapp/WEB-INF/resources/css/kitodo.css index 36b26f2ba5f..3202d144c8d 100644 --- a/Kitodo/src/main/webapp/WEB-INF/resources/css/kitodo.css +++ b/Kitodo/src/main/webapp/WEB-INF/resources/css/kitodo.css @@ -920,6 +920,13 @@ label.ui-outputlabel[for] { #parsedFiltersForm\:parsedFilters .ui-datalist-data { padding-right: var(--group-margin); + overflow-x: hidden; + overflow-y: hidden; + white-space: nowrap; +} + +#parsedFiltersForm\:parsedFilters .ui-datalist-data:hover { + overflow-x: scroll; } #parsedFiltersForm\:parsedFilters .ui-datalist-empty-message { From b379c3ae32b0841a84727c30b277a68e4fec5ac8 Mon Sep 17 00:00:00 2001 From: Matthias Ronge Date: Thu, 13 Jul 2023 09:34:51 +0200 Subject: [PATCH 36/72] Better explain the use of English --- .../org/kitodo/dataeditor/ruleset/RulesetManagement.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/RulesetManagement.java b/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/RulesetManagement.java index d3592ef87ee..31afb58a4a3 100644 --- a/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/RulesetManagement.java +++ b/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/RulesetManagement.java @@ -52,7 +52,10 @@ public class RulesetManagement implements RulesetManagementInterface { private static final Logger logger = LogManager.getLogger(RulesetManagement.class); /** - * Language used internally in places where language does not matter. + * English, the only language understood by the System user. This value is + * passed when a method requests a language of the user in order to display + * labels in this language, but the labels are not required from the result + * and the language passed is therefore irrelevant at this point. */ private static final List ENGLISH = LanguageRange.parse("en"); From 370c019ef762680dd4acab38a80b490f160516c6 Mon Sep 17 00:00:00 2001 From: Matthias Ronge Date: Thu, 13 Jul 2023 09:39:29 +0200 Subject: [PATCH 37/72] Update Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/ReimportMetadata.java Co-authored-by: Arved Solth --- .../java/org/kitodo/dataeditor/ruleset/ReimportMetadata.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/ReimportMetadata.java b/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/ReimportMetadata.java index 8a309a33d38..951523c8b0a 100644 --- a/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/ReimportMetadata.java +++ b/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/ReimportMetadata.java @@ -29,7 +29,7 @@ class ReimportMetadata implements Supplier> { private final String key; // existing metadata for this key before reimport - private Collection currentEntries; + private final Collection currentEntries; // configured reimport behavior private Reimport reimport; From 2177480758816fb36646203ed9b39cb60c1e7fce Mon Sep 17 00:00:00 2001 From: Matthias Ronge Date: Thu, 13 Jul 2023 09:39:46 +0200 Subject: [PATCH 38/72] Update Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/ReimportMetadata.java Co-authored-by: Arved Solth --- .../java/org/kitodo/dataeditor/ruleset/ReimportMetadata.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/ReimportMetadata.java b/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/ReimportMetadata.java index 951523c8b0a..e1599c843c3 100644 --- a/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/ReimportMetadata.java +++ b/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/ReimportMetadata.java @@ -35,7 +35,7 @@ class ReimportMetadata implements Supplier> { private Reimport reimport; // metadata fetched on reimport - private Collection updateEntries; + private final Collection updateEntries; // the maximum amount of metadata applicable here for this key private int maxOccurs; From 599eaebbd3903b05f0c495ffcda85435d328d166 Mon Sep 17 00:00:00 2001 From: Matthias Ronge Date: Thu, 13 Jul 2023 09:40:04 +0200 Subject: [PATCH 39/72] Update Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/xml/Reimport.java Co-authored-by: Arved Solth --- .../main/java/org/kitodo/dataeditor/ruleset/xml/Reimport.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/xml/Reimport.java b/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/xml/Reimport.java index c022ee69c08..2a5c102620c 100644 --- a/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/xml/Reimport.java +++ b/Kitodo-DataEditor/src/main/java/org/kitodo/dataeditor/ruleset/xml/Reimport.java @@ -20,7 +20,7 @@ * This class is a backing bean for the XML attribute reimport in the ruleset. * With it, JAXB can map the attribute to an enum. */ -@XmlEnum(String.class) +@XmlEnum() public enum Reimport { /** * The metadata should be added. From 32b1469c3e4b13b2c771ef2a81e11923eba4e1ab Mon Sep 17 00:00:00 2001 From: Matthias Ronge Date: Thu, 13 Jul 2023 09:40:17 +0200 Subject: [PATCH 40/72] Update Kitodo/src/main/java/org/kitodo/production/forms/createprocess/ProcessFieldedMetadata.java Co-authored-by: Arved Solth --- .../production/forms/createprocess/ProcessFieldedMetadata.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Kitodo/src/main/java/org/kitodo/production/forms/createprocess/ProcessFieldedMetadata.java b/Kitodo/src/main/java/org/kitodo/production/forms/createprocess/ProcessFieldedMetadata.java index 7bc2b464ab6..73e297d65c2 100644 --- a/Kitodo/src/main/java/org/kitodo/production/forms/createprocess/ProcessFieldedMetadata.java +++ b/Kitodo/src/main/java/org/kitodo/production/forms/createprocess/ProcessFieldedMetadata.java @@ -145,7 +145,7 @@ public int addMetadataIfNotExists(Collection potentialMetadataItems) throws InvalidMetadataValueException, NoSuchMetadataFieldException { preserve(); - int count = rulesetService.updateMetadata(division.getType() ,metadata, "create", potentialMetadataItems); + int count = rulesetService.updateMetadata(division.getType(), metadata, "create", potentialMetadataItems); buildTreeNodeAndCreateMetadataTable(); return count; } From 3cf10838cf00fcc938bec8f07a589e2d4d5080a5 Mon Sep 17 00:00:00 2001 From: Arved Solth Date: Fri, 14 Jul 2023 11:38:46 +0200 Subject: [PATCH 41/72] Improve layout of 'upload media' dialog --- .../resources/messages/messages_de.properties | 1 + .../resources/messages/messages_en.properties | 2 + .../webapp/WEB-INF/resources/css/kitodo.css | 24 ++-- .../metadataEditor/dialogs/uploadFile.xhtml | 116 +++++++++--------- .../includes/metadataEditor/gallery.xhtml | 4 +- .../metadataEditor/logicalStructure.xhtml | 2 +- 6 files changed, 82 insertions(+), 67 deletions(-) diff --git a/Kitodo/src/main/resources/messages/messages_de.properties b/Kitodo/src/main/resources/messages/messages_de.properties index 6279e82f39d..23abe9e57bc 100644 --- a/Kitodo/src/main/resources/messages/messages_de.properties +++ b/Kitodo/src/main/resources/messages/messages_de.properties @@ -1132,6 +1132,7 @@ uploadFile=Datei hochladen uploadImport=Dateiupload-Import uploadMedia=Medien hochladen uploadMediaCompleted=Hochladen und Generieren neuer Medien wurde erfolgreich beendet. +uploadMediaFileLimit=Maximal erlaubte Anzahl an Dateien \u00FCberschritten uriMalformed=Der URI hat ein falsches Format. url=URL useExistingWorkflow=Bestehenden Workflow verwenden diff --git a/Kitodo/src/main/resources/messages/messages_en.properties b/Kitodo/src/main/resources/messages/messages_en.properties index 40ca9181f3e..c8f8e4b61f1 100644 --- a/Kitodo/src/main/resources/messages/messages_en.properties +++ b/Kitodo/src/main/resources/messages/messages_en.properties @@ -331,6 +331,7 @@ dataEditor.undefinedStructure=The division isn't defined in the ruleset dataEditor.undefinedKey=The key isn't defined in the ruleset dataEditor.unlinkedMediaTree=Unlinked media dataEditor.unstructuredMedia=Unstructured media + dataEditor.validation.state.error=Validation error dataEditor.validation.state.warning=Validation warning dataEditor.validation.state.success=Validation successful @@ -1132,6 +1133,7 @@ uploadFile=upload file uploadImport=file upload import uploadMedia=Upload media uploadMediaCompleted=Uploading and generating new media has been completed successfully. +uploadMediaFileLimit=Maximum number of files exceeded uriMalformed=The URI is malformed. url=URL useExistingWorkflow=Use existing workflow diff --git a/Kitodo/src/main/webapp/WEB-INF/resources/css/kitodo.css b/Kitodo/src/main/webapp/WEB-INF/resources/css/kitodo.css index 36b26f2ba5f..f6073782bf1 100644 --- a/Kitodo/src/main/webapp/WEB-INF/resources/css/kitodo.css +++ b/Kitodo/src/main/webapp/WEB-INF/resources/css/kitodo.css @@ -2315,14 +2315,11 @@ form#metadata div label, } #uploadFileDialog { - padding: 20px; max-height: 550px; } #uploadFileDialog_content { box-sizing: border-box; - overflow: visible; - padding: 0; } #uploadFileDialog .ui-fileupload-buttonbar { @@ -2330,10 +2327,6 @@ form#metadata div label, text-align: right; } -#uploadFileDialog .dialogButtonWrapper { - margin-bottom: 10px; -} - #uploadFileDialogForm\:progressBar .ui-progressbar-value { background: #85b2cb; } @@ -2354,6 +2347,23 @@ form#metadata div label, height: 90%; } +.ui-fileupload-buttonbar { + margin-bottom: var(--default-full-size); +} + +.ui-dialog .ui-panelgrid-cell div.ui-fileupload-content, +.ui-dialog .ui-panelgrid-cell div.ui-fileupload-files { + color: var(--blue); + width: 100%; +} + +.ui-dialog .ui-panelgrid-cell div.ui-fileupload-content, +.ui-dialog .ui-panelgrid-cell div.ui-fileupload-files, +.ui-dialog .ui-panelgrid-cell div.ui-fileupload-files div { + margin: 0; +} + + #metadataAccordion\:metadata .ui-treetable-indent, #metadataAccordion\:metadata .ui-treetable-toggler { float: left; diff --git a/Kitodo/src/main/webapp/WEB-INF/templates/includes/metadataEditor/dialogs/uploadFile.xhtml b/Kitodo/src/main/webapp/WEB-INF/templates/includes/metadataEditor/dialogs/uploadFile.xhtml index 4ab1895a6e1..c05c025697f 100644 --- a/Kitodo/src/main/webapp/WEB-INF/templates/includes/metadataEditor/dialogs/uploadFile.xhtml +++ b/Kitodo/src/main/webapp/WEB-INF/templates/includes/metadataEditor/dialogs/uploadFile.xhtml @@ -20,73 +20,75 @@ +

#{msgs.uploadMedia}

- - -

#{msgs.uploadMedia}

-
- - - - - -
-
- -
- -
- - - - - -
+ + + +
+ + + + + +
+
+ +
+ +
+
+
+ + +