-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add implementation of: https://ocfl.github.io/extensions/0006-flat-om… (
#43) * Add implementation of: https://ocfl.github.io/extensions/0006-flat-omit-prefix-storage-layout.html Co-authored-by: anw822 <andrew_woods@harvard.edu>
- Loading branch information
Showing
5 changed files
with
480 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
123 changes: 123 additions & 0 deletions
123
...va/edu/wisc/library/ocfl/core/extension/storage/layout/FlatOmitPrefixLayoutExtension.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
/* | ||
* 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.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 <a href="https://ocfl.github.io/extensions/0006-flat-omit-prefix-storage-layout.html"> | ||
* Flat Omit Prefix Storage Layout</a> extension. | ||
* | ||
* @author awoods | ||
* @since 2021-06-22 | ||
*/ | ||
public class FlatOmitPrefixLayoutExtension implements OcflStorageLayoutExtension { | ||
|
||
public static final String EXTENSION_NAME = "0006-flat-omit-prefix-storage-layout"; | ||
|
||
private String delim; | ||
|
||
/** | ||
* {@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.delim == null) { | ||
|
||
// Is arg config null? | ||
if (config == null) { | ||
throw new IllegalArgumentException("Arg config must not be null!"); | ||
} | ||
|
||
if (!(config instanceof FlatOmitPrefixLayoutConfig)) { | ||
throw new OcflExtensionException(String.format("This extension only supports %s configuration. Received: %s", | ||
getExtensionConfigClass(), config)); | ||
} | ||
|
||
FlatOmitPrefixLayoutConfig castConfig = (FlatOmitPrefixLayoutConfig) config; | ||
|
||
validateConfig(castConfig); | ||
this.delim = castConfig.getDelimiter().toLowerCase(); | ||
} | ||
} | ||
|
||
private static void validateConfig(FlatOmitPrefixLayoutConfig config) { | ||
if (config != null) { | ||
String delimiter = config.getDelimiter(); | ||
if (delimiter == null || delimiter.isEmpty()) { | ||
throw new OcflExtensionException("Digest configuration must not be empty!"); | ||
} | ||
} | ||
} | ||
|
||
@Override | ||
public Class<? extends OcflExtensionConfig> getExtensionConfigClass() { | ||
return FlatOmitPrefixLayoutConfig.class; | ||
} | ||
|
||
/** | ||
* {@inheritDoc} | ||
*/ | ||
@Override | ||
public String mapObjectId(String objectId) { | ||
if (delim == null) { | ||
throw new OcflExtensionException("This extension must be initialized before it can be used."); | ||
} | ||
|
||
// Use lowercase of delimiter and objectId, per specification | ||
String id = objectId.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; | ||
} | ||
} |
98 changes: 98 additions & 0 deletions
98
...du/wisc/library/ocfl/core/extension/storage/layout/config/FlatOmitPrefixLayoutConfig.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 <a href="https://ocfl.github.io/extensions/0006-flat-omit-prefix-storage-layout.html"> | ||
* Flat Omit Prefix Storage Layout</a> 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.isEmpty()) { | ||
throw new IllegalArgumentException("Arg must not be empty: '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 + "' }"; | ||
} | ||
|
||
|
||
} |
141 changes: 141 additions & 0 deletions
141
...java-core/src/main/resources/ocfl-specs/0006-flat-omit-prefix-storage-layout.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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` | |
Oops, something went wrong.