Skip to content

Commit d84f92c

Browse files
authored
Merge pull request kitodo#6297 from effective-webwork/ead-import
Add EAD collection import
2 parents 1c6a99a + 75dd227 commit d84f92c

33 files changed

+2683
-363
lines changed

Kitodo-API/src/main/java/org/kitodo/api/schemaconverter/MetadataFormat.java

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ public enum MetadataFormat {
1515
MODS,
1616
MARC,
1717
PICA,
18+
EAD,
1819
OTHER,
1920
KITODO;
2021

Kitodo-API/src/main/java/org/kitodo/constants/StringConstants.java

+12
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,17 @@ public class StringConstants {
2121
public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
2222

2323
// acquisition stages
24+
public static final String CREATE = "create";
2425
public static final String EDIT = "edit";
26+
27+
// EAD string constants
28+
public static final String EAD = "ead";
29+
public static final String LEVEL = "level";
30+
public static final String C_TAG_NAME = "c";
31+
// EAD levels
32+
public static final String COLLECTION = "collection";
33+
public static final String CLASS = "class";
34+
public static final String SERIES = "series";
35+
public static final String FILE = "file";
36+
public static final String ITEM = "item";
2537
}

Kitodo/src/main/java/org/kitodo/config/enums/ParameterCore.java

+13-1
Original file line numberDiff line numberDiff line change
@@ -655,7 +655,19 @@ public enum ParameterCore implements ParameterInterface {
655655
/* Optional parameter can be used to limit the number of processes for which media renaming can be conducted as a
656656
* list function. Values different from positive integers are interpreted as "unlimited".
657657
*/
658-
MAX_NUMBER_OF_PROCESSES_FOR_MEDIA_RENAMING(new Parameter<>("maxNumberOfProcessesForMediaRenaming", -1));
658+
MAX_NUMBER_OF_PROCESSES_FOR_MEDIA_RENAMING(new Parameter<>("maxNumberOfProcessesForMediaRenaming", -1)),
659+
660+
/*
661+
* Optional parameter controlling how many processes are to be displayed and processed in the metadata import mask.
662+
* When more data records are imported the import process is moved to a background task. Default value is 5.
663+
*/
664+
MAX_NUMBER_OF_PROCESSES_FOR_IMPORT_MASK(new Parameter<>("maxNumberOfProcessesForImportMask", 5)),
665+
666+
/*
667+
* Optional parameter controlling whether the import of all elements from an uploaded EAD XML file should be
668+
* canceled when an exception occurs or not. Defaults to 'false'.
669+
*/
670+
STOP_EAD_COLLECTION_IMPORT_ON_EXCEPTION(new Parameter<>("stopEadCollectionImportOnException", false));
659671

660672
private final Parameter<?> parameter;
661673

Kitodo/src/main/java/org/kitodo/production/forms/createprocess/CatalogImportDialog.java

+115-23
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
import javax.faces.context.FacesContext;
2323
import javax.xml.parsers.ParserConfigurationException;
24+
import javax.xml.stream.XMLStreamException;
2425
import javax.xml.transform.TransformerException;
2526
import javax.xml.xpath.XPathExpressionException;
2627

@@ -29,7 +30,9 @@
2930
import org.apache.logging.log4j.Logger;
3031
import org.kitodo.api.dataeditor.rulesetmanagement.FunctionalMetadata;
3132
import org.kitodo.api.externaldatamanagement.SingleHit;
33+
import org.kitodo.api.schemaconverter.DataRecord;
3234
import org.kitodo.api.schemaconverter.ExemplarRecord;
35+
import org.kitodo.api.schemaconverter.MetadataFormat;
3336
import org.kitodo.data.database.beans.ImportConfiguration;
3437
import org.kitodo.data.database.exceptions.DAOException;
3538
import org.kitodo.exceptions.CatalogException;
@@ -53,7 +56,7 @@
5356

5457
public class CatalogImportDialog extends MetadataImportDialog implements Serializable {
5558
private static final Logger logger = LogManager.getLogger(CatalogImportDialog.class);
56-
private final LazyHitModel hitModel = new LazyHitModel();
59+
private final LazyHitModel hitModel;
5760

5861
private static final String ID_PARAMETER_NAME = "ID";
5962
private static final String HITSTABLE_NAME = "hitlistDialogForm:hitlistDialogTable";
@@ -64,6 +67,10 @@ public class CatalogImportDialog extends MetadataImportDialog implements Serial
6467
private int numberOfChildren = 0;
6568
private String opacErrorMessage = "";
6669
private boolean additionalImport = false;
70+
private String selectedField = "";
71+
private String searchTerm = "";
72+
private int importDepth = 2;
73+
6774

6875
/**
6976
* Standard constructor.
@@ -72,6 +79,7 @@ public class CatalogImportDialog extends MetadataImportDialog implements Serial
7279
*/
7380
CatalogImportDialog(CreateProcessForm createProcessForm) {
7481
super(createProcessForm);
82+
this.hitModel = new LazyHitModel(this);
7583
}
7684

7785
/**
@@ -87,11 +95,11 @@ public void getSelectedRecord() {
8795
* @return list of search fields
8896
*/
8997
public List<String> getSearchFields() {
90-
if (Objects.isNull(hitModel.getImportConfiguration())) {
98+
if (Objects.isNull(createProcessForm.getCurrentImportConfiguration())) {
9199
return new LinkedList<>();
92100
} else {
93101
try {
94-
return ServiceManager.getImportService().getAvailableSearchFields(hitModel.getImportConfiguration());
102+
return ServiceManager.getImportService().getAvailableSearchFields(createProcessForm.getCurrentImportConfiguration());
95103
} catch (IllegalArgumentException e) {
96104
Helper.setErrorMessage(e.getLocalizedMessage(), logger, e);
97105
return new LinkedList<>();
@@ -104,8 +112,8 @@ public List<String> getSearchFields() {
104112
*/
105113
public void search() {
106114
try {
107-
if (skipHitList(hitModel.getImportConfiguration(), hitModel.getSelectedField())) {
108-
getRecordById(hitModel.getSearchTerm());
115+
if (skipHitList(createProcessForm.getCurrentImportConfiguration(), getSelectedField())) {
116+
getRecordById(getSearchTerm());
109117
} else {
110118
List<?> hits = hitModel.load(0, 10, null, SortOrder.ASCENDING, Collections.EMPTY_MAP);
111119
if (hits.size() == 1) {
@@ -175,16 +183,21 @@ public void getRecordHierarchy() {
175183
createProcessForm.setChildProcesses(new LinkedList<>());
176184
int projectId = this.createProcessForm.getProject().getId();
177185
int templateId = this.createProcessForm.getTemplate().getId();
178-
ImportConfiguration importConfiguration = this.hitModel.getImportConfiguration();
179-
180-
// import current and ancestors
181-
LinkedList<TempProcess> processes = ServiceManager.getImportService().importProcessHierarchy(
182-
currentRecordId, importConfiguration, projectId, templateId, hitModel.getImportDepth(),
183-
createProcessForm.getRulesetManagement().getFunctionalKeys(
184-
FunctionalMetadata.HIGHERLEVEL_IDENTIFIER));
185-
// import children
186-
if (this.importChildren) {
187-
importChildren(projectId, templateId, importConfiguration, processes);
186+
ImportConfiguration importConfiguration = createProcessForm.getCurrentImportConfiguration();
187+
188+
LinkedList<TempProcess> processes;
189+
if (MetadataFormat.EAD.name().equals(importConfiguration.getMetadataFormat())) {
190+
processes = createEadProcesses(importConfiguration);
191+
} else {
192+
// import current and ancestors
193+
processes = ServiceManager.getImportService().importProcessHierarchy(currentRecordId,
194+
importConfiguration, projectId, templateId, getImportDepth(),
195+
createProcessForm.getRulesetManagement().getFunctionalKeys(
196+
FunctionalMetadata.HIGHERLEVEL_IDENTIFIER));
197+
// import children
198+
if (this.importChildren) {
199+
importChildren(projectId, templateId, importConfiguration, processes);
200+
}
188201
}
189202

190203
if (!createProcessForm.getProcesses().isEmpty() && additionalImport) {
@@ -196,15 +209,39 @@ public void getRecordHierarchy() {
196209
attachToExistingParentAndGenerateAtstslIfNotExist(currentTempProcess);
197210
showMessageAndRecord(importConfiguration, processes);
198211
}
212+
199213
} catch (IOException | ProcessGenerationException | XPathExpressionException | URISyntaxException
200-
| ParserConfigurationException | UnsupportedFormatException | SAXException | DAOException
201-
| ConfigException | TransformerException | NoRecordFoundException | InvalidMetadataValueException
202-
| NoSuchMetadataFieldException e) {
214+
| ParserConfigurationException | UnsupportedFormatException | SAXException | DAOException
215+
| ConfigException | TransformerException | NoRecordFoundException | InvalidMetadataValueException
216+
| NoSuchMetadataFieldException | XMLStreamException e) {
203217
throw new CatalogException(e.getLocalizedMessage());
204218
}
205219
}
206220
}
207221

222+
private LinkedList<TempProcess> createEadProcesses(ImportConfiguration importConfiguration) throws NoRecordFoundException,
223+
XPathExpressionException, IOException, ParserConfigurationException, SAXException, XMLStreamException,
224+
UnsupportedFormatException, ProcessGenerationException, URISyntaxException, InvalidMetadataValueException,
225+
TransformerException, NoSuchMetadataFieldException {
226+
LinkedList<TempProcess> processes = new LinkedList<>();
227+
DataRecord externalRecord = ServiceManager.getImportService()
228+
.importExternalDataRecord(importConfiguration, this.currentRecordId, false);
229+
createProcessForm.setXmlString(externalRecord.getOriginalData().toString());
230+
if (createProcessForm.limitExceeded(externalRecord.getOriginalData().toString())) {
231+
createProcessForm.calculateNumberOfEadElements();
232+
Ajax.update("maxNumberOfRecordsExceededDialog");
233+
PrimeFaces.current().executeScript("PF('maxNumberOfRecordsExceededDialog').show();");
234+
} else {
235+
LinkedList<TempProcess> eadProcesses = ServiceManager.getImportService()
236+
.parseImportedEADCollection(externalRecord, importConfiguration,
237+
createProcessForm.getProject().getId(), createProcessForm.getTemplate().getId(),
238+
createProcessForm.getSelectedEadLevel(), createProcessForm.getSelectedParentEadLevel());
239+
createProcessForm.setChildProcesses(new LinkedList<>(eadProcesses.subList(1, eadProcesses.size() - 1)));
240+
processes = new LinkedList<>(Collections.singletonList(eadProcesses.get(0)));
241+
}
242+
return processes;
243+
}
244+
208245
private void showMessageAndRecord(ImportConfiguration importConfiguration, LinkedList<TempProcess> processes) {
209246
String summary = Helper.getTranslation("newProcess.catalogueSearch.importSuccessfulSummary");
210247
String detail = Helper.getTranslation("newProcess.catalogueSearch.importSuccessfulDetail",
@@ -238,7 +275,7 @@ private void getRecordById(String recordId) {
238275
try {
239276
if (this.importChildren) {
240277
this.numberOfChildren = ServiceManager.getImportService().getNumberOfChildren(
241-
this.hitModel.getImportConfiguration(), this.currentRecordId);
278+
createProcessForm.getCurrentImportConfiguration(), this.currentRecordId);
242279
}
243280
if (this.importChildren && this.numberOfChildren > NUMBER_OF_CHILDREN_WARNING_THRESHOLD) {
244281
Ajax.update("manyChildrenWarningDialog");
@@ -294,7 +331,7 @@ public LinkedList<ExemplarRecord> getExemplarRecords() {
294331
*/
295332
public void setSelectedExemplarRecord(ExemplarRecord selectedExemplarRecord) {
296333
try {
297-
ImportService.setSelectedExemplarRecord(selectedExemplarRecord, this.hitModel.getImportConfiguration(),
334+
ImportService.setSelectedExemplarRecord(selectedExemplarRecord, createProcessForm.getCurrentImportConfiguration(),
298335
this.createProcessForm.getProcessMetadata().getProcessDetailsElements());
299336
String summary = Helper.getTranslation("newProcess.catalogueSearch.exemplarRecordSelectedSummary");
300337
String detail = Helper.getTranslation("newProcess.catalogueSearch.exemplarRecordSelectedDetail",
@@ -303,7 +340,7 @@ public void setSelectedExemplarRecord(ExemplarRecord selectedExemplarRecord) {
303340
Ajax.update(FORM_CLIENTID);
304341
} catch (ParameterNotFoundException e) {
305342
Helper.setErrorMessage("newProcess.catalogueSearch.exemplarRecordParameterNotFoundError",
306-
new Object[] {e.getMessage(), this.hitModel.getImportConfiguration().getTitle() });
343+
new Object[] {e.getMessage(), createProcessForm.getCurrentImportConfiguration().getTitle() });
307344
}
308345
}
309346

@@ -314,8 +351,8 @@ public void setSelectedExemplarRecord(ExemplarRecord selectedExemplarRecord) {
314351
*/
315352
public boolean isParentIdSearchFieldConfigured() {
316353
try {
317-
return Objects.nonNull(this.hitModel.getImportConfiguration()) && ServiceManager.getImportService()
318-
.isParentIdSearchFieldConfigured(this.hitModel.getImportConfiguration());
354+
return Objects.nonNull(createProcessForm.getCurrentImportConfiguration()) && ServiceManager.getImportService()
355+
.isParentIdSearchFieldConfigured(createProcessForm.getCurrentImportConfiguration());
319356
} catch (ConfigException e) {
320357
return false;
321358
}
@@ -360,4 +397,59 @@ public void setAdditionalImport(boolean additionalImport) {
360397
this.additionalImport = additionalImport;
361398
}
362399

400+
401+
/**
402+
* Get searchTerm.
403+
*
404+
* @return value of searchTerm
405+
*/
406+
public String getSearchTerm() {
407+
return this.searchTerm;
408+
}
409+
410+
/**
411+
* Set searchTerm.
412+
*
413+
* @param searchTerm as java.lang.String
414+
*/
415+
public void setSearchTerm(String searchTerm) {
416+
this.searchTerm = searchTerm;
417+
}
418+
419+
/**
420+
* Get selectedField.
421+
*
422+
* @return value of selectedField
423+
*/
424+
public String getSelectedField() {
425+
return this.selectedField;
426+
}
427+
428+
/**
429+
* Set selectedField.
430+
*
431+
* @param field as String
432+
*/
433+
public void setSelectedField(String field) {
434+
this.selectedField = field;
435+
}
436+
437+
/**
438+
* Get import depth.
439+
*
440+
* @return import depth
441+
*/
442+
public int getImportDepth() {
443+
return importDepth;
444+
}
445+
446+
/**
447+
* Set import depth.
448+
*
449+
* @param depth import depth
450+
*/
451+
public void setImportDepth(int depth) {
452+
importDepth = depth;
453+
}
454+
363455
}

0 commit comments

Comments
 (0)