Skip to content

Commit

Permalink
Merge pull request kitodo#6297 from effective-webwork/ead-import
Browse files Browse the repository at this point in the history
Add EAD collection import
  • Loading branch information
solth authored Nov 15, 2024
2 parents 1c6a99a + 75dd227 commit d84f92c
Show file tree
Hide file tree
Showing 33 changed files with 2,683 additions and 363 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public enum MetadataFormat {
MODS,
MARC,
PICA,
EAD,
OTHER,
KITODO;

Expand Down
12 changes: 12 additions & 0 deletions Kitodo-API/src/main/java/org/kitodo/constants/StringConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,17 @@ public class StringConstants {
public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";

// acquisition stages
public static final String CREATE = "create";
public static final String EDIT = "edit";

// EAD string constants
public static final String EAD = "ead";
public static final String LEVEL = "level";
public static final String C_TAG_NAME = "c";
// EAD levels
public static final String COLLECTION = "collection";
public static final String CLASS = "class";
public static final String SERIES = "series";
public static final String FILE = "file";
public static final String ITEM = "item";
}
14 changes: 13 additions & 1 deletion Kitodo/src/main/java/org/kitodo/config/enums/ParameterCore.java
Original file line number Diff line number Diff line change
Expand Up @@ -655,7 +655,19 @@ public enum ParameterCore implements ParameterInterface {
/* Optional parameter can be used to limit the number of processes for which media renaming can be conducted as a
* list function. Values different from positive integers are interpreted as "unlimited".
*/
MAX_NUMBER_OF_PROCESSES_FOR_MEDIA_RENAMING(new Parameter<>("maxNumberOfProcessesForMediaRenaming", -1));
MAX_NUMBER_OF_PROCESSES_FOR_MEDIA_RENAMING(new Parameter<>("maxNumberOfProcessesForMediaRenaming", -1)),

/*
* Optional parameter controlling how many processes are to be displayed and processed in the metadata import mask.
* When more data records are imported the import process is moved to a background task. Default value is 5.
*/
MAX_NUMBER_OF_PROCESSES_FOR_IMPORT_MASK(new Parameter<>("maxNumberOfProcessesForImportMask", 5)),

/*
* Optional parameter controlling whether the import of all elements from an uploaded EAD XML file should be
* canceled when an exception occurs or not. Defaults to 'false'.
*/
STOP_EAD_COLLECTION_IMPORT_ON_EXCEPTION(new Parameter<>("stopEadCollectionImportOnException", false));

private final Parameter<?> parameter;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

import javax.faces.context.FacesContext;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.stream.XMLStreamException;
import javax.xml.transform.TransformerException;
import javax.xml.xpath.XPathExpressionException;

Expand All @@ -29,7 +30,9 @@
import org.apache.logging.log4j.Logger;
import org.kitodo.api.dataeditor.rulesetmanagement.FunctionalMetadata;
import org.kitodo.api.externaldatamanagement.SingleHit;
import org.kitodo.api.schemaconverter.DataRecord;
import org.kitodo.api.schemaconverter.ExemplarRecord;
import org.kitodo.api.schemaconverter.MetadataFormat;
import org.kitodo.data.database.beans.ImportConfiguration;
import org.kitodo.data.database.exceptions.DAOException;
import org.kitodo.exceptions.CatalogException;
Expand All @@ -53,7 +56,7 @@

public class CatalogImportDialog extends MetadataImportDialog implements Serializable {
private static final Logger logger = LogManager.getLogger(CatalogImportDialog.class);
private final LazyHitModel hitModel = new LazyHitModel();
private final LazyHitModel hitModel;

private static final String ID_PARAMETER_NAME = "ID";
private static final String HITSTABLE_NAME = "hitlistDialogForm:hitlistDialogTable";
Expand All @@ -64,6 +67,10 @@ public class CatalogImportDialog extends MetadataImportDialog implements Serial
private int numberOfChildren = 0;
private String opacErrorMessage = "";
private boolean additionalImport = false;
private String selectedField = "";
private String searchTerm = "";
private int importDepth = 2;


/**
* Standard constructor.
Expand All @@ -72,6 +79,7 @@ public class CatalogImportDialog extends MetadataImportDialog implements Serial
*/
CatalogImportDialog(CreateProcessForm createProcessForm) {
super(createProcessForm);
this.hitModel = new LazyHitModel(this);
}

/**
Expand All @@ -87,11 +95,11 @@ public void getSelectedRecord() {
* @return list of search fields
*/
public List<String> getSearchFields() {
if (Objects.isNull(hitModel.getImportConfiguration())) {
if (Objects.isNull(createProcessForm.getCurrentImportConfiguration())) {
return new LinkedList<>();
} else {
try {
return ServiceManager.getImportService().getAvailableSearchFields(hitModel.getImportConfiguration());
return ServiceManager.getImportService().getAvailableSearchFields(createProcessForm.getCurrentImportConfiguration());
} catch (IllegalArgumentException e) {
Helper.setErrorMessage(e.getLocalizedMessage(), logger, e);
return new LinkedList<>();
Expand All @@ -104,8 +112,8 @@ public List<String> getSearchFields() {
*/
public void search() {
try {
if (skipHitList(hitModel.getImportConfiguration(), hitModel.getSelectedField())) {
getRecordById(hitModel.getSearchTerm());
if (skipHitList(createProcessForm.getCurrentImportConfiguration(), getSelectedField())) {
getRecordById(getSearchTerm());
} else {
List<?> hits = hitModel.load(0, 10, null, SortOrder.ASCENDING, Collections.EMPTY_MAP);
if (hits.size() == 1) {
Expand Down Expand Up @@ -175,16 +183,21 @@ public void getRecordHierarchy() {
createProcessForm.setChildProcesses(new LinkedList<>());
int projectId = this.createProcessForm.getProject().getId();
int templateId = this.createProcessForm.getTemplate().getId();
ImportConfiguration importConfiguration = this.hitModel.getImportConfiguration();

// import current and ancestors
LinkedList<TempProcess> processes = ServiceManager.getImportService().importProcessHierarchy(
currentRecordId, importConfiguration, projectId, templateId, hitModel.getImportDepth(),
createProcessForm.getRulesetManagement().getFunctionalKeys(
FunctionalMetadata.HIGHERLEVEL_IDENTIFIER));
// import children
if (this.importChildren) {
importChildren(projectId, templateId, importConfiguration, processes);
ImportConfiguration importConfiguration = createProcessForm.getCurrentImportConfiguration();

LinkedList<TempProcess> processes;
if (MetadataFormat.EAD.name().equals(importConfiguration.getMetadataFormat())) {
processes = createEadProcesses(importConfiguration);
} else {
// import current and ancestors
processes = ServiceManager.getImportService().importProcessHierarchy(currentRecordId,
importConfiguration, projectId, templateId, getImportDepth(),
createProcessForm.getRulesetManagement().getFunctionalKeys(
FunctionalMetadata.HIGHERLEVEL_IDENTIFIER));
// import children
if (this.importChildren) {
importChildren(projectId, templateId, importConfiguration, processes);
}
}

if (!createProcessForm.getProcesses().isEmpty() && additionalImport) {
Expand All @@ -196,15 +209,39 @@ public void getRecordHierarchy() {
attachToExistingParentAndGenerateAtstslIfNotExist(currentTempProcess);
showMessageAndRecord(importConfiguration, processes);
}

} catch (IOException | ProcessGenerationException | XPathExpressionException | URISyntaxException
| ParserConfigurationException | UnsupportedFormatException | SAXException | DAOException
| ConfigException | TransformerException | NoRecordFoundException | InvalidMetadataValueException
| NoSuchMetadataFieldException e) {
| ParserConfigurationException | UnsupportedFormatException | SAXException | DAOException
| ConfigException | TransformerException | NoRecordFoundException | InvalidMetadataValueException
| NoSuchMetadataFieldException | XMLStreamException e) {
throw new CatalogException(e.getLocalizedMessage());
}
}
}

private LinkedList<TempProcess> createEadProcesses(ImportConfiguration importConfiguration) throws NoRecordFoundException,
XPathExpressionException, IOException, ParserConfigurationException, SAXException, XMLStreamException,
UnsupportedFormatException, ProcessGenerationException, URISyntaxException, InvalidMetadataValueException,
TransformerException, NoSuchMetadataFieldException {
LinkedList<TempProcess> processes = new LinkedList<>();
DataRecord externalRecord = ServiceManager.getImportService()
.importExternalDataRecord(importConfiguration, this.currentRecordId, false);
createProcessForm.setXmlString(externalRecord.getOriginalData().toString());
if (createProcessForm.limitExceeded(externalRecord.getOriginalData().toString())) {
createProcessForm.calculateNumberOfEadElements();
Ajax.update("maxNumberOfRecordsExceededDialog");
PrimeFaces.current().executeScript("PF('maxNumberOfRecordsExceededDialog').show();");
} else {
LinkedList<TempProcess> eadProcesses = ServiceManager.getImportService()
.parseImportedEADCollection(externalRecord, importConfiguration,
createProcessForm.getProject().getId(), createProcessForm.getTemplate().getId(),
createProcessForm.getSelectedEadLevel(), createProcessForm.getSelectedParentEadLevel());
createProcessForm.setChildProcesses(new LinkedList<>(eadProcesses.subList(1, eadProcesses.size() - 1)));
processes = new LinkedList<>(Collections.singletonList(eadProcesses.get(0)));
}
return processes;
}

private void showMessageAndRecord(ImportConfiguration importConfiguration, LinkedList<TempProcess> processes) {
String summary = Helper.getTranslation("newProcess.catalogueSearch.importSuccessfulSummary");
String detail = Helper.getTranslation("newProcess.catalogueSearch.importSuccessfulDetail",
Expand Down Expand Up @@ -238,7 +275,7 @@ private void getRecordById(String recordId) {
try {
if (this.importChildren) {
this.numberOfChildren = ServiceManager.getImportService().getNumberOfChildren(
this.hitModel.getImportConfiguration(), this.currentRecordId);
createProcessForm.getCurrentImportConfiguration(), this.currentRecordId);
}
if (this.importChildren && this.numberOfChildren > NUMBER_OF_CHILDREN_WARNING_THRESHOLD) {
Ajax.update("manyChildrenWarningDialog");
Expand Down Expand Up @@ -294,7 +331,7 @@ public LinkedList<ExemplarRecord> getExemplarRecords() {
*/
public void setSelectedExemplarRecord(ExemplarRecord selectedExemplarRecord) {
try {
ImportService.setSelectedExemplarRecord(selectedExemplarRecord, this.hitModel.getImportConfiguration(),
ImportService.setSelectedExemplarRecord(selectedExemplarRecord, createProcessForm.getCurrentImportConfiguration(),
this.createProcessForm.getProcessMetadata().getProcessDetailsElements());
String summary = Helper.getTranslation("newProcess.catalogueSearch.exemplarRecordSelectedSummary");
String detail = Helper.getTranslation("newProcess.catalogueSearch.exemplarRecordSelectedDetail",
Expand All @@ -303,7 +340,7 @@ public void setSelectedExemplarRecord(ExemplarRecord selectedExemplarRecord) {
Ajax.update(FORM_CLIENTID);
} catch (ParameterNotFoundException e) {
Helper.setErrorMessage("newProcess.catalogueSearch.exemplarRecordParameterNotFoundError",
new Object[] {e.getMessage(), this.hitModel.getImportConfiguration().getTitle() });
new Object[] {e.getMessage(), createProcessForm.getCurrentImportConfiguration().getTitle() });
}
}

Expand All @@ -314,8 +351,8 @@ public void setSelectedExemplarRecord(ExemplarRecord selectedExemplarRecord) {
*/
public boolean isParentIdSearchFieldConfigured() {
try {
return Objects.nonNull(this.hitModel.getImportConfiguration()) && ServiceManager.getImportService()
.isParentIdSearchFieldConfigured(this.hitModel.getImportConfiguration());
return Objects.nonNull(createProcessForm.getCurrentImportConfiguration()) && ServiceManager.getImportService()
.isParentIdSearchFieldConfigured(createProcessForm.getCurrentImportConfiguration());
} catch (ConfigException e) {
return false;
}
Expand Down Expand Up @@ -360,4 +397,59 @@ public void setAdditionalImport(boolean additionalImport) {
this.additionalImport = additionalImport;
}


/**
* Get searchTerm.
*
* @return value of searchTerm
*/
public String getSearchTerm() {
return this.searchTerm;
}

/**
* Set searchTerm.
*
* @param searchTerm as java.lang.String
*/
public void setSearchTerm(String searchTerm) {
this.searchTerm = searchTerm;
}

/**
* Get selectedField.
*
* @return value of selectedField
*/
public String getSelectedField() {
return this.selectedField;
}

/**
* Set selectedField.
*
* @param field as String
*/
public void setSelectedField(String field) {
this.selectedField = field;
}

/**
* Get import depth.
*
* @return import depth
*/
public int getImportDepth() {
return importDepth;
}

/**
* Set import depth.
*
* @param depth import depth
*/
public void setImportDepth(int depth) {
importDepth = depth;
}

}
Loading

0 comments on commit d84f92c

Please sign in to comment.