Skip to content

Commit d86a9b6

Browse files
sebhofmannkkrebs
authored andcommitted
Added edition editor mask and shelf mark db mapping
1 parent 7ad8891 commit d86a9b6

36 files changed

Lines changed: 27405 additions & 194 deletions

digital-edition-archive-cli/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<parent>
55
<groupId>de.gbv.dea</groupId>
66
<artifactId>digital-edition-archive</artifactId>
7-
<version>2023.06.01-SNAPSHOT</version>
7+
<version>2023.06-SNAPSHOT</version>
88
</parent>
99
<artifactId>digital-edition-archive-cli</artifactId>
1010
<packaging>pom</packaging>

digital-edition-archive-module/pom.xml

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<parent>
66
<groupId>de.gbv.dea</groupId>
77
<artifactId>digital-edition-archive</artifactId>
8-
<version>2023.06.01-SNAPSHOT</version>
8+
<version>2023.06-SNAPSHOT</version>
99
</parent>
1010
<artifactId>digital-edition-archive-module</artifactId>
1111
<name>digital-edition-archive: Application Module</name>
@@ -138,5 +138,24 @@
138138
<groupId>org.mycore</groupId>
139139
<artifactId>mycore-webtools</artifactId>
140140
</dependency>
141+
<dependency>
142+
<groupId>org.mycore</groupId>
143+
<artifactId>mycore-classifications</artifactId>
144+
</dependency>
145+
<dependency>
146+
<groupId>org.mycore</groupId>
147+
<artifactId>mycore-base</artifactId>
148+
<scope>test</scope>
149+
<type>test-jar</type>
150+
</dependency>
151+
<dependency>
152+
<groupId>com.h2database</groupId>
153+
<artifactId>h2</artifactId>
154+
<scope>test</scope>
155+
</dependency>
156+
<dependency>
157+
<groupId>org.mycore</groupId>
158+
<artifactId>mycore-wcms2</artifactId>
159+
</dependency>
141160
</dependencies>
142161
</project>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<objecttype name="tei" isChild="false" isParent="false" hasDerivates="true" xmlns:xs="http://www.w3.org/2001/XMLSchema"
2+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xmlns:tei="http://www.tei-c.org/ns/1.0"
4+
xsi:noNamespaceSchemaLocation="datamodel.xsd">
5+
<xsd>
6+
<xs:import namespace="http://www.tei-c.org/ns/1.0" schemaLocation="schema/tei_edition.xsd" />
7+
</xsd>
8+
<metadata>
9+
<element name="teiContainer" type="xml" style="dontknow" notinherit="true" heritable="false">
10+
<xs:sequence>
11+
<xs:element ref="tei:teiHeader" />
12+
</xs:sequence>
13+
</element>
14+
</metadata>
15+
</objecttype>

digital-edition-archive-module/src/main/java/de/gbv/dea/DEATEIUploadHandler.java renamed to digital-edition-archive-module/src/main/java/de/gbv/dea/BlumenbachTEIUploadHandler.java

Lines changed: 36 additions & 148 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,14 @@
44

55
import java.io.IOException;
66
import java.io.InputStream;
7-
import java.io.OutputStream;
87
import java.net.URI;
98
import java.net.URISyntaxException;
109
import java.nio.file.Files;
11-
import java.nio.file.NoSuchFileException;
1210
import java.nio.file.Path;
1311
import java.util.List;
1412
import java.util.Map;
1513
import java.util.Objects;
14+
import java.util.Optional;
1615
import java.util.UUID;
1716
import java.util.regex.Matcher;
1817
import java.util.regex.Pattern;
@@ -21,25 +20,22 @@
2120

2221
import org.apache.logging.log4j.LogManager;
2322
import org.apache.logging.log4j.Logger;
23+
import org.jdom2.Attribute;
2424
import org.jdom2.Document;
2525
import org.jdom2.Element;
2626
import org.jdom2.JDOMException;
2727
import org.jdom2.input.SAXBuilder;
28-
import org.jdom2.output.Format;
29-
import org.jdom2.output.XMLOutputter;
3028
import org.mycore.access.MCRAccessException;
29+
import org.mycore.common.MCRConstants;
3130
import org.mycore.common.MCRException;
32-
import org.mycore.datamodel.metadata.MCRDerivate;
3331
import org.mycore.datamodel.metadata.MCRMetaClassification;
3432
import org.mycore.datamodel.metadata.MCRMetadataManager;
3533
import org.mycore.datamodel.metadata.MCRObject;
3634
import org.mycore.datamodel.metadata.MCRObjectID;
3735
import org.mycore.datamodel.metadata.validator.MCREditorOutValidator;
3836
import org.mycore.datamodel.niofs.MCRPath;
39-
import org.mycore.datamodel.niofs.utils.MCRRecursiveDeleter;
40-
import org.mycore.datamodel.niofs.utils.MCRTreeCopier;
4137
import org.mycore.frontend.MCRFrontendUtil;
42-
import org.mycore.frontend.fileupload.MCRUploadHelper;
38+
import org.mycore.services.i18n.MCRTranslation;
4339
import org.mycore.webtools.upload.MCRDefaultUploadHandler;
4440
import org.mycore.webtools.upload.MCRFileUploadBucket;
4541
import org.mycore.webtools.upload.MCRUploadHandler;
@@ -50,37 +46,46 @@
5046
import org.mycore.webtools.upload.exception.MCRUploadForbiddenException;
5147
import org.mycore.webtools.upload.exception.MCRUploadServerException;
5248

53-
public class DEATEIUploadHandler implements MCRUploadHandler {
49+
import de.gbv.dea.shelfmark.ShelfMarkMappingManager;
5450

55-
private static final Logger LOGGER = LogManager.getLogger();
56-
public static final String FILE_NAME_PATTERN = "(?<number>[0-9]{6}).*\\.xml";
51+
public class BlumenbachTEIUploadHandler implements MCRUploadHandler {
5752

58-
private static final String DERIVATE_TYPES_CLASS = "derivate_types";
59-
private static final String DERIVATE_TYPES_CONTENT = "content";
60-
private static final String DERIVATE_TYPES_ORIGINAL = "original";
53+
public static final String FILE_NAME_PATTERN = "(?<number>[0-9]{6}).*\\.xml";
54+
private static final Logger LOGGER = LogManager.getLogger();
6155

6256
public MCRObjectID traverse(Path fileOrDirectory, String project, List<MCRMetaClassification> classifications)
63-
throws MCRUploadServerException, MCRInvalidFileException, IOException {
57+
throws MCRUploadServerException, MCRInvalidFileException, IOException {
58+
Objects.requireNonNull(project, () -> MCRTranslation.translate("fileupload.tei.project.missing"));
6459
try {
6560
if (Files.isDirectory(fileOrDirectory)) {
6661
// file is a directory and should be named like 000001, 000002, 000003, ...
6762
// and should contain a file named 000001*.xml
6863
// and should contain a directory name images
69-
MCRObjectID objectID = getObjectIDFromDirectory(fileOrDirectory, project);
7064
Path teiFile = findTEIFile(fileOrDirectory);
65+
Document parsedTEI = parseTEI(teiFile);
66+
String shelfmark = getShelfmarkFromTEIFile(parsedTEI).orElseThrow(
67+
() -> new MCRInvalidFileException(teiFile.toString(), "fileupload.tei.file.missingShelfmark", true,
68+
teiFile.toString()));
69+
70+
MCRObjectID objectID = ShelfMarkMappingManager.getMappedMycoreID(shelfmark, project)
71+
.map(MCRObjectID::getInstance)
72+
.orElseGet(()-> MCRMetadataManager.getMCRObjectIDGenerator().getNextFreeId(project,"tei"));
73+
74+
7175
Document tei = importOrUpdateTEIMyCoReObject(teiFile, objectID, classifications);
7276

7377
Path imagesDirectory = findImagesDirectory(fileOrDirectory, objectID);
74-
MCRObjectID contentDerivate = createDerivateIfNotExists(objectID, DERIVATE_TYPES_CONTENT);
78+
MCRObjectID contentDerivate = DEAUtils.createDerivateIfNotExists(objectID,
79+
DEAUtils.DERIVATE_TYPES_CONTENT);
7580

7681
LOGGER.info("Processing object " + objectID);
7782
if (imagesDirectory != null) {
78-
importImages(imagesDirectory, contentDerivate);
83+
DEAUtils.importImages(imagesDirectory, contentDerivate);
7984
} else {
8085
LOGGER.warn("No images directory found for object " + objectID);
8186
}
8287

83-
splitTEIFileToDerivate(tei, objectID, MCRPath.getPath(contentDerivate.toString(), "/"));
88+
DEAUtils.splitTEIFileToDerivate(tei, objectID, MCRPath.getPath(contentDerivate.toString(), "/"));
8489

8590
return objectID;
8691
} else if (Files.isRegularFile(fileOrDirectory)) {
@@ -103,58 +108,13 @@ public MCRObjectID traverse(Path fileOrDirectory, String project, List<MCRMetaCl
103108
return null;
104109
}
105110

106-
private void importImages(Path imagesDirectory, MCRObjectID derivateId) throws MCRUploadServerException {
107-
MCRPath root = MCRPath.getPath(derivateId.toString(), "/");
108-
try {
109-
Files.createDirectories(root);
110-
} catch (IOException e) {
111-
throw new MCRUploadServerException("mcr.upload.import.failed", e);
112-
}
113-
final MCRTreeCopier copier;
114-
try {
115-
copier = new MCRTreeCopier(imagesDirectory, root, false, true);
116-
} catch (NoSuchFileException e) {
117-
throw new MCRException(e);
118-
}
119-
120-
try {
121-
Files.walkFileTree(imagesDirectory, copier);
122-
} catch (IOException e) {
123-
throw new MCRUploadServerException("mcr.upload.import.failed", e);
124-
}
125-
126-
MCRDerivate theDerivate = MCRMetadataManager.retrieveMCRDerivate(derivateId);
127-
128-
String mainDoc = theDerivate.getDerivate().getInternals().getMainDoc();
129-
if (mainDoc == null || mainDoc.isEmpty()) {
130-
MCRDefaultUploadHandler.setDefaultMainFile(theDerivate);
131-
}
132-
}
133-
134-
private static MCRObjectID createDerivateIfNotExists(MCRObjectID objectID, String contentType) {
135-
if (!MCRMetadataManager.exists(objectID)) {
136-
return null;
137-
}
138-
MCRObject object = MCRMetadataManager.retrieveMCRObject(objectID);
139-
140-
String ctName = DERIVATE_TYPES_CLASS + ":" + contentType;
141-
var derivates = object.getStructure().getDerivates().stream()
142-
.filter(link -> link.getClassifications().stream()
143-
.anyMatch(classification -> classification.toString().equals(ctName)))
144-
.toList();
145-
146-
if(derivates.size() == 1) {
147-
return derivates.get(0).getXLinkHrefID();
148-
} else if(derivates.size() > 1) {
149-
throw new MCRException("Object " + objectID + " has more than one derivate of type " + contentType);
150-
} else {
151-
try {
152-
var contentTypeClass = MCRUploadHelper.getClassifications(ctName);
153-
return MCRUploadHelper.createDerivate(objectID, contentTypeClass).getId();
154-
} catch (MCRAccessException e) {
155-
throw new MCRException("Error while creating derivate for object " + objectID, e);
156-
}
111+
public Optional<String> getShelfmarkFromTEIFile(Document tei) {
112+
Attribute idAttr = tei.getRootElement().getChild("teiHeader", TEI_NS).getChild("fileDesc", TEI_NS)
113+
.getAttribute("id", MCRConstants.XML_NAMESPACE);
114+
if (idAttr != null) {
115+
return Optional.of(idAttr.getValue());
157116
}
117+
return Optional.empty();
158118
}
159119

160120
private Path findImagesDirectory(Path fileOrDirectory, MCRObjectID objectID) {
@@ -169,32 +129,13 @@ private Path findImagesDirectory(Path fileOrDirectory, MCRObjectID objectID) {
169129
public Path findTEIFile(Path directory) {
170130
try {
171131
return Files.find(directory, 1,
172-
(path, basicFileAttributes) -> path.getFileName().toString().matches(FILE_NAME_PATTERN))
132+
(path, basicFileAttributes) -> path.getFileName().toString().matches(FILE_NAME_PATTERN))
173133
.findFirst().orElse(null);
174134
} catch (IOException e) {
175135
throw new RuntimeException(e);
176136
}
177137
}
178138

179-
180-
public MCRObjectID getObjectIDFromDirectory(Path path, String project) throws IllegalArgumentException {
181-
// path is a directory and should be named like 000001
182-
if (!Files.isDirectory(path)) {
183-
throw new IllegalArgumentException("Path is not a directory.");
184-
}
185-
186-
String file = path.getFileName().toString();
187-
if (!file.matches("[0-9]{6}")) {
188-
throw new IllegalArgumentException("Name " + file + " does not consist of 6 digits.");
189-
190-
}
191-
192-
int number = Integer.parseInt(file);
193-
String formattedIDString = MCRObjectID.formatID(project + "_tei_", number);
194-
return MCRObjectID.getInstance(formattedIDString);
195-
196-
}
197-
198139
public MCRObjectID getObjectIDFromFile(Path file, String project) throws IllegalArgumentException {
199140
if (!Files.isRegularFile(file)) {
200141
throw new IllegalArgumentException("File is not a regular file.");
@@ -217,7 +158,8 @@ public MCRObjectID getObjectIDFromFile(Path file, String project) throws Illegal
217158
}
218159

219160
public Document importOrUpdateTEIMyCoReObject(Path teiFile, MCRObjectID objectID,
220-
List<MCRMetaClassification> classifications) throws IOException, MCRInvalidFileException {
161+
List<MCRMetaClassification> classifications) throws IOException,
162+
MCRInvalidFileException {
221163
boolean exists = MCRMetadataManager.exists(objectID);
222164
Document teiDocument = parseTEI(teiFile);
223165

@@ -242,7 +184,7 @@ public Document importOrUpdateTEIMyCoReObject(Path teiFile, MCRObjectID objectID
242184
try {
243185
MCREditorOutValidator ev = new MCREditorOutValidator(object.createXML(), objectID);
244186
ev.generateValidMyCoReObject();
245-
} catch (RuntimeException|JDOMException e) {
187+
} catch (RuntimeException | JDOMException e) {
246188
String fileName = teiFile.getFileName().toString();
247189
throw new MCRInvalidFileException(fileName, "fileupload.tei.file.invalid", true, fileName, e.getMessage());
248190
}
@@ -253,39 +195,11 @@ public Document importOrUpdateTEIMyCoReObject(Path teiFile, MCRObjectID objectID
253195
throw new MCRException("Error while updating object " + objectID, e);
254196
}
255197

256-
storeFileInOriginalDerivate(teiFile, objectID);
198+
DEAUtils.storeFileInOriginalDerivate(teiFile, objectID);
257199

258200
return teiDocument;
259201
}
260202

261-
/**
262-
* Due to the fact that the original tei file is seperated in to several files, the original tei file is stored in
263-
* the original derivate.
264-
*
265-
* This method stores the given TEI file in the original derivate of the given object. If the derivate does not
266-
* exist, it will be created. If it exists, all files will be deleted. The given file will be stored as main
267-
* document.
268-
* @param teiFile the TEI file to store
269-
* @param objectID the object id of the object to store the TEI file in
270-
* @throws IOException if an I/O error occurs
271-
*/
272-
private static void storeFileInOriginalDerivate(Path teiFile, MCRObjectID objectID) throws IOException {
273-
// create or use existing derivate to store the original TEI file
274-
MCRObjectID originalDerivate = createDerivateIfNotExists(objectID, DERIVATE_TYPES_ORIGINAL);
275-
Path fileName = teiFile.getFileName();
276-
MCRPath originalDerivatePath = MCRPath.getPath(originalDerivate.toString(), "/");
277-
Files.walkFileTree(originalDerivatePath, MCRRecursiveDeleter.instance());
278-
Path fn = originalDerivatePath.resolve(fileName.toString());
279-
Files.copy(teiFile, fn);
280-
MCRDerivate mcrDerivate = MCRMetadataManager.retrieveMCRDerivate(originalDerivate);
281-
mcrDerivate.getDerivate().getInternals().setMainDoc(fileName.toString());
282-
try {
283-
MCRMetadataManager.update(mcrDerivate);
284-
} catch (MCRAccessException e) {
285-
throw new MCRException("Error while updating derivate " + originalDerivate, e);
286-
}
287-
}
288-
289203
public Document parseTEI(Path teiFile) {
290204
SAXBuilder saxBuilder = new SAXBuilder();
291205
try (InputStream is = Files.newInputStream(teiFile)) {
@@ -295,32 +209,6 @@ public Document parseTEI(Path teiFile) {
295209
}
296210
}
297211

298-
public static void splitTEIFileToDerivate(Document tei, MCRObjectID objectID, MCRPath root) {
299-
Path transcriptionFolderPath = root.resolve("tei/").resolve("transcription");
300-
if (!Files.exists(transcriptionFolderPath)) {
301-
try {
302-
Files.createDirectories(transcriptionFolderPath);
303-
} catch (IOException e) {
304-
throw new MCRException(e);
305-
}
306-
}
307-
DEATEISplitter splitter = new DEATEISplitter(new DEATEISplitter.TeiFile(objectID.toString(), tei));
308-
List<DEATEISplitter.TeiFile> split = splitter.split();
309-
split.stream()
310-
.filter(file -> file.name() != null)
311-
.forEach(teiFile -> {
312-
String name = teiFile.name();
313-
314-
try (OutputStream os = Files.newOutputStream(transcriptionFolderPath.resolve(name + ".xml"))) {
315-
XMLOutputter xmlOutputter = new XMLOutputter(Format.getRawFormat());
316-
xmlOutputter.output(teiFile.doc(), os);
317-
} catch (IOException e) {
318-
throw new MCRException(e);
319-
}
320-
321-
});
322-
}
323-
324212
@Override
325213
public String begin(Map<String, List<String>> parameters) throws MCRUploadForbiddenException,
326214
MCRUploadServerException, MCRMissingParameterException, MCRInvalidUploadParameterException {
@@ -336,7 +224,7 @@ public String begin(Map<String, List<String>> parameters) throws MCRUploadForbid
336224

337225
try {
338226
MCRMetadataManager.checkCreatePrivilege(
339-
MCRObjectID.getInstance(MCRObjectID.formatID(project, "tei", 0)));
227+
MCRObjectID.getInstance(MCRObjectID.formatID(project, "tei", 0)));
340228
} catch (MCRAccessException e) {
341229
throw new MCRUploadForbiddenException("mcr.upload.forbidden");
342230
}

digital-edition-archive-module/src/main/java/de/gbv/dea/DEAImportCommands.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public class DEAImportCommands {
2222

2323
private static final Logger LOGGER = LogManager.getLogger(DEAImportCommands.class);
2424

25-
@MCRCommand(syntax = "import tei folders from root {0}", order = 1)
25+
@MCRCommand(syntax = "import blumenbach tei folders from root {0}", order = 1)
2626
public static void importTEIFolders(String rootPath) throws MCRUploadServerException, IOException {
2727
LOGGER.info("Importing TEI folders from root {}", rootPath);
2828

@@ -32,7 +32,7 @@ public static void importTEIFolders(String rootPath) throws MCRUploadServerExcep
3232
throw new IllegalArgumentException("Path " + rootPath + " does not exist");
3333
}
3434

35-
DEATEIUploadHandler uploader = new DEATEIUploadHandler();
35+
BlumenbachTEIUploadHandler uploader = new BlumenbachTEIUploadHandler();
3636

3737
MCRCategoryID id = MCRCategoryID.fromString("derivate_types:content");
3838
MCRMetaClassification classification = new MCRMetaClassification("classification", 0, null,

0 commit comments

Comments
 (0)