From 87557d904b245e00ba2e6ec29dcf8cd33c3cd97f Mon Sep 17 00:00:00 2001 From: anw822 Date: Mon, 19 Jul 2021 19:38:45 -0400 Subject: [PATCH 1/3] Add implementation of: https://ocfl.github.io/extensions/0006-flat-omit-prefix-storage-layout.html --- .../layout/FlatOmitPrefixLayoutExtension.java | 111 +++++++++++++++++ .../config/FlatOmitPrefixLayoutConfig.java | 98 +++++++++++++++ .../FlatOmitPrefixLayoutExtensionTest.java | 115 ++++++++++++++++++ 3 files changed, 324 insertions(+) create mode 100644 ocfl-java-core/src/main/java/edu/wisc/library/ocfl/core/extension/storage/layout/FlatOmitPrefixLayoutExtension.java create mode 100644 ocfl-java-core/src/main/java/edu/wisc/library/ocfl/core/extension/storage/layout/config/FlatOmitPrefixLayoutConfig.java create mode 100644 ocfl-java-core/src/test/java/edu/wisc/library/ocfl/core/extension/storage/layout/FlatOmitPrefixLayoutExtensionTest.java diff --git a/ocfl-java-core/src/main/java/edu/wisc/library/ocfl/core/extension/storage/layout/FlatOmitPrefixLayoutExtension.java b/ocfl-java-core/src/main/java/edu/wisc/library/ocfl/core/extension/storage/layout/FlatOmitPrefixLayoutExtension.java new file mode 100644 index 00000000..31163989 --- /dev/null +++ b/ocfl-java-core/src/main/java/edu/wisc/library/ocfl/core/extension/storage/layout/FlatOmitPrefixLayoutExtension.java @@ -0,0 +1,111 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 University of Wisconsin Board of Regents + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package edu.wisc.library.ocfl.core.extension.storage.layout; + +import edu.wisc.library.ocfl.core.extension.OcflExtensionConfig; +import edu.wisc.library.ocfl.core.extension.storage.layout.config.FlatOmitPrefixLayoutConfig; + +/** + * Implementation of the + * Flat Omit Prefix Storage Layout extension. + * + * @author awoods + * @since 2021-06-22 + */ +public class FlatOmitPrefixLayoutExtension implements OcflStorageLayoutExtension { + + public static final String EXTENSION_NAME = "NNNN-flat-omit-prefix-storage-layout"; + + private FlatOmitPrefixLayoutConfig config; + + /** + * {@inheritDoc} + */ + @Override + public String getExtensionName() { + return EXTENSION_NAME; + } + + /** + * {@inheritDoc} + */ + @Override + public String getDescription() { + return "The OCFL object identifiers are expected to contain prefixes which are removed in the mapping to " + + "directory names. The OCFL object identifier prefix is defined as all characters before and including a " + + "configurable delimiter."; + } + + /** + * {@inheritDoc} + */ + @Override + public synchronized void init(OcflExtensionConfig config) { + // Only set this.config if it is uninitialized + if (this.config == null) { + + // Is arg config null? + if (config == null) { + throw new IllegalArgumentException("Arg config must not be null!"); + } + + if (!(config instanceof FlatOmitPrefixLayoutConfig)) { + throw new IllegalArgumentException(String.format("This extension only supports %s configuration. Received: %s", + getExtensionConfigClass(), config)); + } + + FlatOmitPrefixLayoutConfig castConfig = (FlatOmitPrefixLayoutConfig) config; + + validateConfig(castConfig); + this.config = castConfig; + } + } + + private static void validateConfig(FlatOmitPrefixLayoutConfig config) { + if (config != null) { + String delimiter = config.getDelimiter(); + if (delimiter == null || delimiter.isBlank()) { + throw new RuntimeException("Digest configuration must not be empty!"); + } + } + } + + @Override + public Class getExtensionConfigClass() { + return FlatOmitPrefixLayoutConfig.class; + } + + /** + * {@inheritDoc} + */ + @Override + public String mapObjectId(String objectId) { + if (config == null) { + throw new RuntimeException("This extension must be initialized before it can be used."); + } + + String[] parts = objectId.split(config.getDelimiter()); + return parts[parts.length - 1]; + } +} \ No newline at end of file diff --git a/ocfl-java-core/src/main/java/edu/wisc/library/ocfl/core/extension/storage/layout/config/FlatOmitPrefixLayoutConfig.java b/ocfl-java-core/src/main/java/edu/wisc/library/ocfl/core/extension/storage/layout/config/FlatOmitPrefixLayoutConfig.java new file mode 100644 index 00000000..86fdfab9 --- /dev/null +++ b/ocfl-java-core/src/main/java/edu/wisc/library/ocfl/core/extension/storage/layout/config/FlatOmitPrefixLayoutConfig.java @@ -0,0 +1,98 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 University of Wisconsin Board of Regents + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package edu.wisc.library.ocfl.core.extension.storage.layout.config; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import edu.wisc.library.ocfl.api.util.Enforce; +import edu.wisc.library.ocfl.core.extension.OcflExtensionConfig; +import edu.wisc.library.ocfl.core.extension.storage.layout.FlatOmitPrefixLayoutExtension; + +import java.util.Objects; + +/** + * Configuration for the + * Flat Omit Prefix Storage Layout extension. + * + * @author awoods + * @since 2021-06-22 + */ +public class FlatOmitPrefixLayoutConfig implements OcflExtensionConfig { + + private String delimiter; + + @JsonIgnore + @Override + public String getExtensionName() { + return FlatOmitPrefixLayoutExtension.EXTENSION_NAME; + } + + @JsonIgnore + @Override + public boolean hasParameters() { + return true; + } + + /** + * @return the delimiter marking end of prefix + */ + public String getDelimiter() { + return delimiter; + } + + /** + * The case-insensitive, delimiter marking the end of the OCFL object identifier prefix; MUST consist of a + * character string of length one or greater. If the delimiter is found multiple times in the OCFL object + * identifier, its last occurence (right-most) will be used to select the termination of the prefix. + * + * @param delimiter marking the end of prefix + */ + public FlatOmitPrefixLayoutConfig setDelimiter(String delimiter) { + Enforce.notNull(delimiter, "delimiter cannot be null"); + if (delimiter.isBlank()) { + throw new IllegalArgumentException("Arg must not be empty or null: 'delimiter'"); + } + this.delimiter = delimiter; + return this; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + FlatOmitPrefixLayoutConfig that = (FlatOmitPrefixLayoutConfig) o; + return delimiter.equals(that.delimiter); + } + + @Override + public int hashCode() { + return Objects.hash(delimiter); + } + + @Override + public String toString() { + return "FlatOmitPrefixLayoutConfig{ delimiter='" + delimiter + "' }"; + } + + +} diff --git a/ocfl-java-core/src/test/java/edu/wisc/library/ocfl/core/extension/storage/layout/FlatOmitPrefixLayoutExtensionTest.java b/ocfl-java-core/src/test/java/edu/wisc/library/ocfl/core/extension/storage/layout/FlatOmitPrefixLayoutExtensionTest.java new file mode 100644 index 00000000..03ead457 --- /dev/null +++ b/ocfl-java-core/src/test/java/edu/wisc/library/ocfl/core/extension/storage/layout/FlatOmitPrefixLayoutExtensionTest.java @@ -0,0 +1,115 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 University of Wisconsin Board of Regents + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package edu.wisc.library.ocfl.core.extension.storage.layout; + +import edu.wisc.library.ocfl.api.exception.OcflInputException; +import edu.wisc.library.ocfl.core.extension.storage.layout.config.FlatOmitPrefixLayoutConfig; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +/** + * @author awoods + * @since 2021-06-23 + */ +public class FlatOmitPrefixLayoutExtensionTest { + + private FlatOmitPrefixLayoutExtension ext; + private FlatOmitPrefixLayoutConfig config; + + @BeforeEach + public void setUp() { + ext = new FlatOmitPrefixLayoutExtension(); + config = new FlatOmitPrefixLayoutConfig(); + } + + @Test + public void testNullDelimiter() { + assertThrows(OcflInputException.class, () -> config.setDelimiter(null), + "Expected OcflInputException"); + } + + @Test + public void testEmptyDelimiter() { + assertThrows(IllegalArgumentException.class, () -> config.setDelimiter(""), + "Expected IllegalArgumentException"); + } + + @Test + public void testDelimiterNotFound() { + config.setDelimiter("/"); + ext.init(config); + + String result = ext.mapObjectId("namespace:12887296"); + assertEquals("namespace:12887296", result); + } + + @Test + public void testOneOccurrenceOfSingleCharDelimiter() { + config.setDelimiter(":"); + ext.init(config); + + String result = ext.mapObjectId("namespace:12887296"); + assertEquals("12887296", result); + } + + @Test + public void testTwoOccurrencesOfSingleCharDelimiter() { + config.setDelimiter(":"); + ext.init(config); + + String result = ext.mapObjectId("urn:uuid:6e8bc430-9c3a-11d9-9669-0800200c9a66"); + assertEquals("6e8bc430-9c3a-11d9-9669-0800200c9a66", result); + } + + @Test + public void testTwoOccurrencesOfSingleCharDelimiterDRS() { + config.setDelimiter(":"); + ext.init(config); + + String result = ext.mapObjectId("urn-3:HUL.DRS.OBJECT:12887296"); + assertEquals("12887296", result); + } + + @Test + public void testOneOccurrenceOfMultiCharDelimiter() { + config.setDelimiter("edu/"); + ext.init(config); + + String result = ext.mapObjectId("https://institution.edu/3448793"); + assertEquals("3448793", result); + } + + @Test + public void testTwoOccurrencesOfMultiCharDelimiter() { + config.setDelimiter("edu/"); + ext.init(config); + + String result = ext.mapObjectId("https://institution.edu/abc/edu/f8.05v"); + assertEquals("f8.05v", result); + } + +} From f07da96c9e1ca3925df3d1565dbdb2d048dba146 Mon Sep 17 00:00:00 2001 From: anw822 Date: Thu, 22 Jul 2021 19:48:10 -0400 Subject: [PATCH 2/3] code review --- .../layout/FlatOmitPrefixLayoutExtension.java | 34 ++++- .../config/FlatOmitPrefixLayoutConfig.java | 6 +- .../0006-flat-omit-prefix-storage-layout.md | 141 ++++++++++++++++++ 3 files changed, 170 insertions(+), 11 deletions(-) create mode 100644 ocfl-java-core/src/main/resources/ocfl-specs/0006-flat-omit-prefix-storage-layout.md diff --git a/ocfl-java-core/src/main/java/edu/wisc/library/ocfl/core/extension/storage/layout/FlatOmitPrefixLayoutExtension.java b/ocfl-java-core/src/main/java/edu/wisc/library/ocfl/core/extension/storage/layout/FlatOmitPrefixLayoutExtension.java index 31163989..84d4287d 100644 --- a/ocfl-java-core/src/main/java/edu/wisc/library/ocfl/core/extension/storage/layout/FlatOmitPrefixLayoutExtension.java +++ b/ocfl-java-core/src/main/java/edu/wisc/library/ocfl/core/extension/storage/layout/FlatOmitPrefixLayoutExtension.java @@ -23,11 +23,13 @@ */ package edu.wisc.library.ocfl.core.extension.storage.layout; +import edu.wisc.library.ocfl.api.OcflConstants; +import edu.wisc.library.ocfl.api.exception.OcflExtensionException; import edu.wisc.library.ocfl.core.extension.OcflExtensionConfig; import edu.wisc.library.ocfl.core.extension.storage.layout.config.FlatOmitPrefixLayoutConfig; /** - * Implementation of the + * Implementation of the * Flat Omit Prefix Storage Layout extension. * * @author awoods @@ -35,9 +37,10 @@ */ public class FlatOmitPrefixLayoutExtension implements OcflStorageLayoutExtension { - public static final String EXTENSION_NAME = "NNNN-flat-omit-prefix-storage-layout"; + public static final String EXTENSION_NAME = "0006-flat-omit-prefix-storage-layout"; private FlatOmitPrefixLayoutConfig config; + private boolean isCaseSensitive = true; // The spec does not provide for configuring this /** * {@inheritDoc} @@ -71,7 +74,7 @@ public synchronized void init(OcflExtensionConfig config) { } if (!(config instanceof FlatOmitPrefixLayoutConfig)) { - throw new IllegalArgumentException(String.format("This extension only supports %s configuration. Received: %s", + throw new OcflExtensionException(String.format("This extension only supports %s configuration. Received: %s", getExtensionConfigClass(), config)); } @@ -85,8 +88,8 @@ public synchronized void init(OcflExtensionConfig config) { private static void validateConfig(FlatOmitPrefixLayoutConfig config) { if (config != null) { String delimiter = config.getDelimiter(); - if (delimiter == null || delimiter.isBlank()) { - throw new RuntimeException("Digest configuration must not be empty!"); + if (delimiter == null || delimiter.isEmpty()) { + throw new OcflExtensionException("Digest configuration must not be empty!"); } } } @@ -102,10 +105,25 @@ public Class getExtensionConfigClass() { @Override public String mapObjectId(String objectId) { if (config == null) { - throw new RuntimeException("This extension must be initialized before it can be used."); + throw new OcflExtensionException("This extension must be initialized before it can be used."); } - String[] parts = objectId.split(config.getDelimiter()); - return parts[parts.length - 1]; + // Use lowercase of delimiter and objectId if configured for case-sensitivity (default) + String delim = config.getDelimiter(); + String id = objectId; + if (isCaseSensitive) { + delim = delim.toLowerCase(); + id = id.toLowerCase(); + } + + int index = id.lastIndexOf(delim); + String dir = objectId.substring(index + delim.length()); + + if (OcflConstants.EXTENSIONS_DIR.equals(dir) || dir.isEmpty()) { + throw new OcflExtensionException(String.format("The object id <%s> is incompatible with layout extension " + + "%s because it is empty or conflicts with the extensions directory.", objectId, EXTENSION_NAME)); + } + + return dir; } } \ No newline at end of file diff --git a/ocfl-java-core/src/main/java/edu/wisc/library/ocfl/core/extension/storage/layout/config/FlatOmitPrefixLayoutConfig.java b/ocfl-java-core/src/main/java/edu/wisc/library/ocfl/core/extension/storage/layout/config/FlatOmitPrefixLayoutConfig.java index 86fdfab9..2f24d5bf 100644 --- a/ocfl-java-core/src/main/java/edu/wisc/library/ocfl/core/extension/storage/layout/config/FlatOmitPrefixLayoutConfig.java +++ b/ocfl-java-core/src/main/java/edu/wisc/library/ocfl/core/extension/storage/layout/config/FlatOmitPrefixLayoutConfig.java @@ -31,7 +31,7 @@ import java.util.Objects; /** - * Configuration for the + * Configuration for the * Flat Omit Prefix Storage Layout extension. * * @author awoods @@ -69,8 +69,8 @@ public String getDelimiter() { */ public FlatOmitPrefixLayoutConfig setDelimiter(String delimiter) { Enforce.notNull(delimiter, "delimiter cannot be null"); - if (delimiter.isBlank()) { - throw new IllegalArgumentException("Arg must not be empty or null: 'delimiter'"); + if (delimiter.isEmpty()) { + throw new IllegalArgumentException("Arg must not be empty: 'delimiter'"); } this.delimiter = delimiter; return this; diff --git a/ocfl-java-core/src/main/resources/ocfl-specs/0006-flat-omit-prefix-storage-layout.md b/ocfl-java-core/src/main/resources/ocfl-specs/0006-flat-omit-prefix-storage-layout.md new file mode 100644 index 00000000..12e510b2 --- /dev/null +++ b/ocfl-java-core/src/main/resources/ocfl-specs/0006-flat-omit-prefix-storage-layout.md @@ -0,0 +1,141 @@ +# OCFL Community Extension 0006: Flat Omit Prefix Storage Layout + +* **Extension Name:** 0006-flat-omit-prefix-storage-layout +* **Authors:** Andrew Woods +* **Minimum OCFL Version:** 1.0 +* **OCFL Community Extensions Version:** 1.0 +* **Obsoletes:** n/a +* **Obsoleted by:** n/a + +## Overview + +This storage root extension describes a flat OCFL storage layout. The OCFL object directories are direct children of +the OCFL storage root directory. +The OCFL object identifiers are expected to contain prefixes which are removed in the mapping to directory names. The +OCFL object identifier prefix is defined as all characters before and including a configurable delimiter. + +The limitations of this layout are filesystem dependent, but are generally as follows: + +* The size of object identifiers, minus the length of the prefix, cannot exceed the maximum allowed directory name size + (eg. 255 characters) +* Object identifiers cannot include characters that are illegal in directory names +* Performance may degrade as the size of a repository increases because every object is a direct child of the storage root + +## Parameters + +### Summary + +* **Name:** `delimiter` + * **Description:** The case-insensitive, delimiter marking the end of the OCFL object identifier prefix; MUST consist + of a character string of length one or greater. If the delimiter is found multiple times in the OCFL object + identifier, its last occurence (right-most) will be used to select the termination of the prefix. + * **Type:** string + * **Constraints:** Must not be empty + * **Default:** + +## Examples + +### Example 1 + +This example demonstrates mappings where the single-character delimiter is found one or more times in the OCFL object +identifier. + +#### Parameters + +There is no default configuration; therefore, configuration parameters must be provided. + +```json +{ + "extensionName": "0006-flat-omit-prefix-storage-layout", + "delimiter": ":" +} +``` + +#### Mappings + +| Object ID | Object Root Path | +| --- | --- | +| namespace:12887296 | `12887296` | +| urn:uuid:6e8bc430-9c3a-11d9-9669-0800200c9a66 | `6e8bc430-9c3a-11d9-9669-0800200c9a66` | + +#### Storage Hierarchy + +``` +[storage_root]/ +├── 0=ocfl_1.0 +├── ocfl_layout.json +├── 12887296/ +│ ├── 0=ocfl_object_1.0 +│ ├── inventory.json +│ ├── inventory.json.sha512 +│ └── v1 [...] +└── 6e8bc430-9c3a-11d9-9669-0800200c9a66/ + ├── 0=ocfl_object_1.0 + ├── inventory.json + ├── inventory.json.sha512 + └── v1 [...] +``` + +### Example 2 + +This example demonstrates mappings where the multi-character delimiter is found one or more times in the OCFL object +identifier. + +#### Parameters + +There is no default configuration; therefore, configuration parameters must be provided. + +```json +{ + "extensionName": "0006-flat-omit-prefix-storage-layout", + "delimiter": "edu/" +} +``` + +#### Mappings + +| Object ID | Object Root Path | +| --- | --- | +| https://institution.edu/3448793 | `3448793` | +| https://institution.edu/abc/edu/f8.05v | `f8.05v` | + +#### Storage Hierarchy + +``` +[storage_root]/ +├── 0=ocfl_1.0 +├── ocfl_layout.json +├── 3448793/ +│ ├── 0=ocfl_object_1.0 +│ ├── inventory.json +│ ├── inventory.json.sha512 +│ └── v1 [...] +└── f8.05v/ + ├── 0=ocfl_object_1.0 + ├── inventory.json + ├── inventory.json.sha512 + └── v1 [...] +``` + +### Example 3 + +This example demonstrates mappings that produce directory names that are invalid on unix filesystems; therefore this +layout cannot be used in a repository that needs to be able to store objects with identifiers like these. + +#### Parameters + +There is no default configuration; therefore, configuration parameters must be provided. + +```json +{ + "extensionName": "0006-flat-omit-prefix-storage-layout", + "delimiter": "info:" +} +``` + +#### Mappings + +| Object ID | Object Root Path | +| --- | --- | +| info:fedora/object-01 | `fedora/object-01` | +| https://example.org/info:/12345/x54xz321/s3/f8.05v | `/12345/x54xz321/s3/f8.05v` | \ No newline at end of file From c2424ef855a2e7498690504d0eeedd9b08751b79 Mon Sep 17 00:00:00 2001 From: anw822 Date: Fri, 23 Jul 2021 10:00:38 -0400 Subject: [PATCH 3/3] code review --- .../core/extension/OcflExtensionRegistry.java | 6 +++--- .../layout/FlatOmitPrefixLayoutExtension.java | 18 ++++++------------ 2 files changed, 9 insertions(+), 15 deletions(-) diff --git a/ocfl-java-core/src/main/java/edu/wisc/library/ocfl/core/extension/OcflExtensionRegistry.java b/ocfl-java-core/src/main/java/edu/wisc/library/ocfl/core/extension/OcflExtensionRegistry.java index 7356d16c..a3a4b652 100644 --- a/ocfl-java-core/src/main/java/edu/wisc/library/ocfl/core/extension/OcflExtensionRegistry.java +++ b/ocfl-java-core/src/main/java/edu/wisc/library/ocfl/core/extension/OcflExtensionRegistry.java @@ -24,10 +24,10 @@ package edu.wisc.library.ocfl.core.extension; -import edu.wisc.library.ocfl.api.OcflConstants; import edu.wisc.library.ocfl.api.exception.OcflExtensionException; import edu.wisc.library.ocfl.api.util.Enforce; import edu.wisc.library.ocfl.core.extension.storage.layout.FlatLayoutExtension; +import edu.wisc.library.ocfl.core.extension.storage.layout.FlatOmitPrefixLayoutExtension; import edu.wisc.library.ocfl.core.extension.storage.layout.HashedNTupleIdEncapsulationLayoutExtension; import edu.wisc.library.ocfl.core.extension.storage.layout.HashedNTupleLayoutExtension; import org.slf4j.Logger; @@ -36,7 +36,6 @@ import java.util.HashMap; import java.util.Map; import java.util.Optional; -import java.util.Set; /** * Registry for mapping extensions to their implementations. The following out-of-the-box extensions are pre-registered @@ -55,7 +54,8 @@ public final class OcflExtensionRegistry { private static final Map> REGISTRY = new HashMap<>(Map.of( HashedNTupleLayoutExtension.EXTENSION_NAME, HashedNTupleLayoutExtension.class, HashedNTupleIdEncapsulationLayoutExtension.EXTENSION_NAME, HashedNTupleIdEncapsulationLayoutExtension.class, - FlatLayoutExtension.EXTENSION_NAME, FlatLayoutExtension.class + FlatLayoutExtension.EXTENSION_NAME, FlatLayoutExtension.class, + FlatOmitPrefixLayoutExtension.EXTENSION_NAME, FlatOmitPrefixLayoutExtension.class )); private OcflExtensionRegistry() { diff --git a/ocfl-java-core/src/main/java/edu/wisc/library/ocfl/core/extension/storage/layout/FlatOmitPrefixLayoutExtension.java b/ocfl-java-core/src/main/java/edu/wisc/library/ocfl/core/extension/storage/layout/FlatOmitPrefixLayoutExtension.java index 84d4287d..4eb15b82 100644 --- a/ocfl-java-core/src/main/java/edu/wisc/library/ocfl/core/extension/storage/layout/FlatOmitPrefixLayoutExtension.java +++ b/ocfl-java-core/src/main/java/edu/wisc/library/ocfl/core/extension/storage/layout/FlatOmitPrefixLayoutExtension.java @@ -39,8 +39,7 @@ public class FlatOmitPrefixLayoutExtension implements OcflStorageLayoutExtension public static final String EXTENSION_NAME = "0006-flat-omit-prefix-storage-layout"; - private FlatOmitPrefixLayoutConfig config; - private boolean isCaseSensitive = true; // The spec does not provide for configuring this + private String delim; /** * {@inheritDoc} @@ -66,7 +65,7 @@ public String getDescription() { @Override public synchronized void init(OcflExtensionConfig config) { // Only set this.config if it is uninitialized - if (this.config == null) { + if (this.delim == null) { // Is arg config null? if (config == null) { @@ -81,7 +80,7 @@ public synchronized void init(OcflExtensionConfig config) { FlatOmitPrefixLayoutConfig castConfig = (FlatOmitPrefixLayoutConfig) config; validateConfig(castConfig); - this.config = castConfig; + this.delim = castConfig.getDelimiter().toLowerCase(); } } @@ -104,17 +103,12 @@ public Class getExtensionConfigClass() { */ @Override public String mapObjectId(String objectId) { - if (config == null) { + if (delim == null) { throw new OcflExtensionException("This extension must be initialized before it can be used."); } - // Use lowercase of delimiter and objectId if configured for case-sensitivity (default) - String delim = config.getDelimiter(); - String id = objectId; - if (isCaseSensitive) { - delim = delim.toLowerCase(); - id = id.toLowerCase(); - } + // Use lowercase of delimiter and objectId, per specification + String id = objectId.toLowerCase(); int index = id.lastIndexOf(delim); String dir = objectId.substring(index + delim.length());