/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE file at the root of the source
* tree and available online at
*
* https://github.com/keeps/roda
*/
package org.roda.core.plugins.misc;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.roda.core.RodaCoreFactory;
import org.roda.core.data.common.RodaConstants;
import org.roda.core.data.common.RodaConstants.PreservationEventType;
import org.roda.core.data.exceptions.AlreadyExistsException;
import org.roda.core.data.exceptions.AuthorizationDeniedException;
import org.roda.core.data.exceptions.GenericException;
import org.roda.core.data.exceptions.InvalidParameterException;
import org.roda.core.data.exceptions.NotFoundException;
import org.roda.core.data.exceptions.RODAException;
import org.roda.core.data.exceptions.RequestNotValidException;
import org.roda.core.data.utils.JsonUtils;
import org.roda.core.data.v2.LiteOptionalWithCause;
import org.roda.core.data.v2.ip.AIP;
import org.roda.core.data.v2.ip.AIPLink;
import org.roda.core.data.v2.ip.AIPState;
import org.roda.core.data.v2.ip.DIP;
import org.roda.core.data.v2.ip.Representation;
import org.roda.core.data.v2.ip.StoragePath;
import org.roda.core.data.v2.ip.metadata.DescriptiveMetadata;
import org.roda.core.data.v2.jobs.Job;
import org.roda.core.data.v2.jobs.PluginParameter;
import org.roda.core.data.v2.jobs.PluginParameter.PluginParameterType;
import org.roda.core.data.v2.jobs.PluginType;
import org.roda.core.data.v2.jobs.Report;
import org.roda.core.data.v2.jobs.Report.PluginState;
import org.roda.core.index.IndexService;
import org.roda.core.model.ModelService;
import org.roda.core.model.utils.ModelUtils;
import org.roda.core.plugins.AbstractPlugin;
import org.roda.core.plugins.Plugin;
import org.roda.core.plugins.PluginException;
import org.roda.core.plugins.RODAObjectProcessingLogic;
import org.roda.core.plugins.orchestrate.JobPluginInfo;
import org.roda.core.plugins.orchestrate.SimpleJobPluginInfo;
import org.roda.core.plugins.plugins.PluginHelper;
import org.roda.core.storage.DefaultStoragePath;
import org.roda.core.storage.StorageService;
import org.roda.core.storage.StringContentPayload;
import org.roda.core.storage.fs.FSUtils;
import org.roda.core.storage.fs.FileStorageService;
import org.roda.core.util.IdUtils;
import org.roda_project.commons_ip.model.ParseException;
import org.roda_project.commons_ip.model.impl.eark.EARKAIP;
import org.roda_project.commons_ip.utils.IPEnums.IPType;
import org.roda_project.commons_ip.utils.IPException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.databind.JsonNode;
/**
* Plugin that generates E-ARK DIP manifest files (METS.xml) from the exiting
* AIP information in the storage layer.
*/
public class CreateMetsDIPPlugin extends AbstractPlugin<AIP> {
private static final Logger LOGGER = LoggerFactory.getLogger(CreateMetsDIPPlugin.class);
private static final String VERSION = "1.0";
private boolean includeSelectedDescriptiveMetadata = false;
private String selectedDescriptiveMetadata = "";
private boolean includeAllPreservationMetadata = false;
private boolean includeSelectedOtherMetadata = false;
private String selectedOtherMetadata = "";
private boolean includeSelectedRepresentations = false;
private String selectedRepresentations = "";
private boolean includeSchemas = true;
private boolean includeDocumentation = true;
private static Map<String, PluginParameter> pluginParameters = new HashMap<>();
static {
pluginParameters.put(RodaConstants.PLUGIN_PARAMS_INCLUDE_SELECTED_DESCRIPTIVE_METADATA,
new PluginParameter(RodaConstants.PLUGIN_PARAMS_INCLUDE_SELECTED_DESCRIPTIVE_METADATA,
"Include only selected descriptive metadata", PluginParameterType.BOOLEAN, "false", false, false,
"Include only selected descriptive metadata on the following parameter."));
pluginParameters.put(RodaConstants.PLUGIN_PARAMS_SELECTED_DESCRIPTIVE_METADATA,
new PluginParameter(RodaConstants.PLUGIN_PARAMS_SELECTED_DESCRIPTIVE_METADATA,
"Selected descriptive metadata (type_version)", PluginParameterType.STRING, "ead_3, dc_2002, ead_2002", true,
false, "The selected descriptive metadata to filter with types and versions."));
pluginParameters.put(RodaConstants.PLUGIN_PARAMS_INCLUDE_ALL_PRESERVATION_METADATA,
new PluginParameter(RodaConstants.PLUGIN_PARAMS_INCLUDE_ALL_PRESERVATION_METADATA,
"Include all preservation metadata", PluginParameterType.BOOLEAN, "true", false, false,
"Include all preservation metadata inside the AIP."));
pluginParameters.put(RodaConstants.PLUGIN_PARAMS_INCLUDE_SELECTED_OTHER_METADATA,
new PluginParameter(RodaConstants.PLUGIN_PARAMS_INCLUDE_SELECTED_OTHER_METADATA,
"Include only selected other metadata", PluginParameterType.BOOLEAN, "false", false, false,
"Include only selected other metadata on the following parameter."));
pluginParameters.put(RodaConstants.PLUGIN_PARAMS_SELECTED_OTHER_METADATA,
new PluginParameter(RodaConstants.PLUGIN_PARAMS_SELECTED_OTHER_METADATA, "Selected other metadata (type)",
PluginParameterType.STRING, "Siegfried, Tika", true, false,
"The selected other metadata to filter with types."));
pluginParameters.put(RodaConstants.PLUGIN_PARAMS_INCLUDE_SELECTED_REPRESENTATIONS,
new PluginParameter(RodaConstants.PLUGIN_PARAMS_INCLUDE_SELECTED_REPRESENTATIONS,
"Include only selected representations", PluginParameterType.BOOLEAN, "false", false, false,
"Include only selected representations on the following parameter."));
pluginParameters.put(RodaConstants.PLUGIN_PARAMS_SELECTED_REPRESENTATIONS,
new PluginParameter(RodaConstants.PLUGIN_PARAMS_SELECTED_REPRESENTATIONS, "Selected representations (type)",
PluginParameterType.STRING, "pdfa, MIXED", true, false, "The selected representations to filter with types."));
pluginParameters.put(RodaConstants.PLUGIN_PARAMS_INCLUDE_SCHEMAS,
new PluginParameter(RodaConstants.PLUGIN_PARAMS_INCLUDE_SCHEMAS, "Include schemas folder",
PluginParameterType.BOOLEAN, "true", false, false,
"Include schemas folder contained on AIP and representations."));
pluginParameters.put(RodaConstants.PLUGIN_PARAMS_INCLUDE_DOCUMENTATION,
new PluginParameter(RodaConstants.PLUGIN_PARAMS_INCLUDE_DOCUMENTATION, "Include documentation folder",
PluginParameterType.BOOLEAN, "true", false, false,
"Include documentation folder contained on AIP and representations."));
}
@Override
public void init() throws PluginException {
// do nothing
}
@Override
public void shutdown() {
// do nothing
}
@Override
public String getName() {
return "Create E-ARK DIP manifest files (METS.xml)";
}
@Override
public String getDescription() {
return "Plugin that generates E-ARK DIP manifest files (\"METS.xml\") from "
+ "existing AIP information in the storage layer. This plugin only works with filesystem as the storage service.";
}
@Override
public String getVersionImpl() {
return VERSION;
}
@Override
public Plugin<AIP> cloneMe() {
return new CreateMetsDIPPlugin();
}
@Override
public PluginType getType() {
return PluginType.MISC;
}
@Override
public List<PluginParameter> getParameters() {
ArrayList<PluginParameter> parameters = new ArrayList<>();
parameters.add(pluginParameters.get(RodaConstants.PLUGIN_PARAMS_INCLUDE_SELECTED_DESCRIPTIVE_METADATA));
parameters.add(pluginParameters.get(RodaConstants.PLUGIN_PARAMS_SELECTED_DESCRIPTIVE_METADATA));
parameters.add(pluginParameters.get(RodaConstants.PLUGIN_PARAMS_INCLUDE_ALL_PRESERVATION_METADATA));
parameters.add(pluginParameters.get(RodaConstants.PLUGIN_PARAMS_INCLUDE_SELECTED_OTHER_METADATA));
parameters.add(pluginParameters.get(RodaConstants.PLUGIN_PARAMS_SELECTED_OTHER_METADATA));
parameters.add(pluginParameters.get(RodaConstants.PLUGIN_PARAMS_INCLUDE_SELECTED_REPRESENTATIONS));
parameters.add(pluginParameters.get(RodaConstants.PLUGIN_PARAMS_SELECTED_REPRESENTATIONS));
parameters.add(pluginParameters.get(RodaConstants.PLUGIN_PARAMS_INCLUDE_SCHEMAS));
parameters.add(pluginParameters.get(RodaConstants.PLUGIN_PARAMS_INCLUDE_DOCUMENTATION));
return parameters;
}
@Override
public void setParameterValues(Map<String, String> parameters) throws InvalidParameterException {
super.setParameterValues(parameters);
if (parameters.containsKey(RodaConstants.PLUGIN_PARAMS_INCLUDE_SELECTED_DESCRIPTIVE_METADATA)) {
includeSelectedDescriptiveMetadata = Boolean
.parseBoolean(parameters.get(RodaConstants.PLUGIN_PARAMS_INCLUDE_SELECTED_DESCRIPTIVE_METADATA));
}
if (parameters.containsKey(RodaConstants.PLUGIN_PARAMS_SELECTED_DESCRIPTIVE_METADATA)) {
selectedDescriptiveMetadata = parameters.get(RodaConstants.PLUGIN_PARAMS_SELECTED_DESCRIPTIVE_METADATA);
}
if (parameters.containsKey(RodaConstants.PLUGIN_PARAMS_INCLUDE_ALL_PRESERVATION_METADATA)) {
includeAllPreservationMetadata = Boolean
.parseBoolean(parameters.get(RodaConstants.PLUGIN_PARAMS_INCLUDE_ALL_PRESERVATION_METADATA));
}
if (parameters.containsKey(RodaConstants.PLUGIN_PARAMS_INCLUDE_SELECTED_OTHER_METADATA)) {
includeSelectedOtherMetadata = Boolean
.parseBoolean(parameters.get(RodaConstants.PLUGIN_PARAMS_INCLUDE_SELECTED_OTHER_METADATA));
}
if (parameters.containsKey(RodaConstants.PLUGIN_PARAMS_SELECTED_OTHER_METADATA)) {
selectedOtherMetadata = parameters.get(RodaConstants.PLUGIN_PARAMS_SELECTED_OTHER_METADATA);
}
if (parameters.containsKey(RodaConstants.PLUGIN_PARAMS_INCLUDE_SELECTED_REPRESENTATIONS)) {
includeSelectedRepresentations = Boolean
.parseBoolean(parameters.get(RodaConstants.PLUGIN_PARAMS_INCLUDE_SELECTED_REPRESENTATIONS));
}
if (parameters.containsKey(RodaConstants.PLUGIN_PARAMS_SELECTED_REPRESENTATIONS)) {
selectedRepresentations = parameters.get(RodaConstants.PLUGIN_PARAMS_SELECTED_REPRESENTATIONS);
}
if (parameters.containsKey(RodaConstants.PLUGIN_PARAMS_INCLUDE_SCHEMAS)) {
includeSchemas = Boolean.parseBoolean(parameters.get(RodaConstants.PLUGIN_PARAMS_INCLUDE_SCHEMAS));
}
if (parameters.containsKey(RodaConstants.PLUGIN_PARAMS_INCLUDE_DOCUMENTATION)) {
includeDocumentation = Boolean.parseBoolean(parameters.get(RodaConstants.PLUGIN_PARAMS_INCLUDE_DOCUMENTATION));
}
}
@Override
public boolean areParameterValuesValid() {
return true;
}
@Override
public PreservationEventType getPreservationEventType() {
return PreservationEventType.RISK_MANAGEMENT;
}
@Override
public String getPreservationEventDescription() {
return "TODO: Preservation event description";
}
@Override
public String getPreservationEventSuccessMessage() {
return "Success";
}
@Override
public String getPreservationEventFailureMessage() {
return "Failure";
}
@Override
public Report beforeAllExecute(final IndexService index, final ModelService model, final StorageService storage)
throws PluginException {
// do nothing
return null;
}
@Override
public Report afterAllExecute(final IndexService index, final ModelService model, final StorageService storage)
throws PluginException {
// do nothing
return null;
}
@Override
public List<String> getCategories() {
return Collections.singletonList(RodaConstants.PLUGIN_CATEGORY_DISSEMINATION);
}
@Override
public List<Class<AIP>> getObjectClasses() {
return Collections.singletonList(AIP.class);
}
@Override
public Report execute(final IndexService index, final ModelService model, final StorageService storage,
final List<LiteOptionalWithCause> liteList) throws PluginException {
return PluginHelper.processObjects(this, new RODAObjectProcessingLogic<AIP>() {
@Override
public void process(IndexService index, ModelService model, StorageService storage, Report report, Job cachedJob,
SimpleJobPluginInfo jobPluginInfo, Plugin<AIP> plugin, AIP object) {
executeOnAip(object, index, model, storage, jobPluginInfo, report, cachedJob);
}
}, index, model, storage, liteList);
}
/**
* Execute on a single {@link AIP}.
*
* @param aip
* the {@link AIP}.
* @param index
* the {@link IndexService}.
* @param model
* the {@link ModelService}.
* @param storage
* the {@link StorageService}.
* @param jobPluginInfo
* the {@link JobPluginInfo}
* @param report
* the {@link Report}.
* @param job
*/
private void executeOnAip(final AIP aip, final IndexService index, final ModelService model,
final StorageService storage, final JobPluginInfo jobPluginInfo, final Report report, final Job job) {
LOGGER.debug("Processing AIP {}", aip.getId());
final Report reportItem = PluginHelper.initPluginReportItem(this, aip.getId(), AIP.class, AIPState.ACTIVE);
PluginHelper.updatePartialJobReport(this, model, reportItem, false, job);
// FIXME 20170118 nvieira condition should be removed when build is not
// depending on FS
if (storage instanceof FileStorageService) {
try {
AIPLink aipLink = new AIPLink(aip.getId());
List<AIPLink> links = new ArrayList<>();
links.add(aipLink);
DIP dip = new DIP();
dip.setId(IdUtils.createUUID());
dip.setAipIds(links);
dip.setPermissions(aip.getPermissions());
dip.setTitle("EARK-DIP");
dip.setDescription("EARK-DIP generated and filtered based on an AIP");
dip.setType(RodaConstants.DIP_TYPE_CONVERSION);
dip = model.createDIP(dip, true);
StoragePath aipPath = ModelUtils.getAIPStoragePath(aip.getId());
StoragePath dipDataPath = ModelUtils.getDIPDataStoragePath(dip.getId());
StoragePath aipOnDIPPath = DefaultStoragePath.parse(dipDataPath, aip.getId());
storage.createDirectory(aipOnDIPPath);
// filter AIP structure using plugin parameters
copyAndFilterAIP(storage, aip, aipPath, aipOnDIPPath);
// create mets files
Path fsPath = FSUtils.getEntityPath(RodaCoreFactory.getStoragePath(), aipOnDIPPath);
EARKAIP earkAIPonDIP = new EARKAIP(RodaFolderAIP.parse(fsPath));
earkAIPonDIP.setType(IPType.DIP);
earkAIPonDIP.build(fsPath.getParent(), true);
// delete aip.json
storage.deleteResource(DefaultStoragePath.parse(aipOnDIPPath, RodaConstants.STORAGE_AIP_METADATA_FILENAME));
model.updateDIP(dip);
jobPluginInfo.incrementObjectsProcessedWithSuccess();
reportItem.setPluginState(PluginState.SUCCESS);
} catch (RODAException | ParseException | IPException | InterruptedException e) {
String message = String.format("Error creating manifest files for AIP %s. Cause: %s.", aip.getId(),
e.getMessage());
LOGGER.debug(message, e);
jobPluginInfo.incrementObjectsProcessedWithFailure();
reportItem.setPluginState(PluginState.FAILURE).setPluginDetails(message);
}
} else {
jobPluginInfo.incrementObjectsProcessedWithFailure();
reportItem.setPluginState(PluginState.FAILURE).setPluginDetails("Storage service type used is not supported");
}
report.addReport(reportItem);
PluginHelper.updatePartialJobReport(this, model, reportItem, true, job);
}
private void copyAndFilterAIP(StorageService storage, AIP aip, StoragePath aipPath, StoragePath aipOnDIPPath)
throws RequestNotValidException, AlreadyExistsException, GenericException, NotFoundException,
AuthorizationDeniedException {
LOGGER.info("Copying AIP to a new DIP");
copyAIPBaseFiles(storage, aipPath, aipOnDIPPath);
List<String> representationIds = copyRepresentationsAndItsMetadata(storage, aip, aipPath, aipOnDIPPath);
copyPreservationMetadata(storage, aipPath, aipOnDIPPath);
copyOtherMetadata(storage, aipPath, aipOnDIPPath);
copyAndUpdateAIPJson(storage, aip, aipOnDIPPath, representationIds);
}
private void copyAIPBaseFiles(StorageService storage, StoragePath aipPath, StoragePath aipOnDIPPath)
throws RequestNotValidException, AlreadyExistsException, GenericException, NotFoundException,
AuthorizationDeniedException {
StoragePath schemasPath = DefaultStoragePath.parse(aipPath, RodaConstants.STORAGE_DIRECTORY_SCHEMAS);
if (includeSchemas && storage.hasDirectory(schemasPath)) {
storage.copy(storage, schemasPath,
DefaultStoragePath.parse(aipOnDIPPath, RodaConstants.STORAGE_DIRECTORY_SCHEMAS));
}
StoragePath documentationPath = DefaultStoragePath.parse(aipPath, RodaConstants.STORAGE_DIRECTORY_DOCUMENTATION);
if (includeDocumentation && storage.hasDirectory(documentationPath)) {
storage.copy(storage, documentationPath,
DefaultStoragePath.parse(aipOnDIPPath, RodaConstants.STORAGE_DIRECTORY_DOCUMENTATION));
}
}
private List<String> copyRepresentationsAndItsMetadata(StorageService storage, AIP aip, StoragePath aipPath,
StoragePath aipOnDIPPath) throws RequestNotValidException, AlreadyExistsException, GenericException,
NotFoundException, AuthorizationDeniedException {
List<String> representationTypes = Arrays.asList(selectedRepresentations.toLowerCase().split(",\\s*"));
List<String> representationIds = new ArrayList<>();
for (Representation representation : aip.getRepresentations()) {
String representationId = representation.getId();
LOGGER.info("Testing if representation '{}' with type '{}' should be copied", representationId,
representation.getType());
if (!includeSelectedRepresentations
|| (includeSelectedRepresentations && representationTypes.contains(representation.getType().toLowerCase()))) {
representationIds.add(representationId);
StoragePath representationPath = DefaultStoragePath.parse(aipPath,
RodaConstants.STORAGE_DIRECTORY_REPRESENTATIONS, representationId);
if (storage.hasDirectory(representationPath)) {
StoragePath representationDIPPath = DefaultStoragePath.parse(aipOnDIPPath,
RodaConstants.STORAGE_DIRECTORY_REPRESENTATIONS, representationId);
StoragePath representationDataPath = DefaultStoragePath.parse(representationPath,
RodaConstants.STORAGE_DIRECTORY_DATA);
if (storage.hasDirectory(representationDataPath)) {
storage.copy(storage, representationDataPath,
DefaultStoragePath.parse(representationDIPPath, RodaConstants.STORAGE_DIRECTORY_DATA));
}
StoragePath representationSchemasPath = DefaultStoragePath.parse(representationPath,
RodaConstants.STORAGE_DIRECTORY_SCHEMAS);
if (includeSchemas && storage.hasDirectory(representationSchemasPath)) {
storage.copy(storage, representationSchemasPath,
DefaultStoragePath.parse(representationDIPPath, RodaConstants.STORAGE_DIRECTORY_SCHEMAS));
}
StoragePath representationDocPath = DefaultStoragePath.parse(representationPath,
RodaConstants.STORAGE_DIRECTORY_DOCUMENTATION);
if (includeDocumentation && storage.hasDirectory(representationDocPath)) {
storage.copy(storage, representationDocPath,
DefaultStoragePath.parse(representationDIPPath, RodaConstants.STORAGE_DIRECTORY_DOCUMENTATION));
}
for (DescriptiveMetadata dm : representation.getDescriptiveMetadata()) {
copyDescriptiveMetadata(storage, dm, representationPath, representationDIPPath);
}
copyPreservationMetadata(storage, representationPath, representationDIPPath);
copyOtherMetadata(storage, representationPath, representationDIPPath);
}
}
}
return representationIds;
}
private String copyDescriptiveMetadata(StorageService storage, DescriptiveMetadata dm, StoragePath sourcePath,
StoragePath targetPath) throws RequestNotValidException, AlreadyExistsException, GenericException,
NotFoundException, AuthorizationDeniedException {
List<String> metadataTypes = Arrays.asList(selectedDescriptiveMetadata.toLowerCase().split(",\\s*"));
String versionType = dm.getType() + RodaConstants.METADATA_VERSION_SEPARATOR + dm.getVersion();
String dmId = dm.getId();
if (!includeSelectedDescriptiveMetadata || metadataTypes.contains(versionType.toLowerCase())) {
StoragePath oldMetadataPath = DefaultStoragePath.parse(sourcePath, RodaConstants.STORAGE_DIRECTORY_METADATA,
RodaConstants.STORAGE_DIRECTORY_DESCRIPTIVE, dmId);
if (storage.hasBinary(oldMetadataPath)) {
StoragePath newMetadataPath = DefaultStoragePath.parse(targetPath, RodaConstants.STORAGE_DIRECTORY_METADATA,
RodaConstants.STORAGE_DIRECTORY_DESCRIPTIVE, dmId);
storage.copy(storage, oldMetadataPath, newMetadataPath);
return dmId;
}
}
return null;
}
private void copyPreservationMetadata(StorageService storage, StoragePath sourcePath, StoragePath targetPath)
throws RequestNotValidException, AlreadyExistsException, GenericException, NotFoundException,
AuthorizationDeniedException {
if (includeAllPreservationMetadata) {
StoragePath oldMetadataPath = DefaultStoragePath.parse(sourcePath, RodaConstants.STORAGE_DIRECTORY_METADATA,
RodaConstants.STORAGE_DIRECTORY_PRESERVATION);
if (storage.hasDirectory(oldMetadataPath)) {
StoragePath newMetadataPath = DefaultStoragePath.parse(targetPath, RodaConstants.STORAGE_DIRECTORY_METADATA,
RodaConstants.STORAGE_DIRECTORY_PRESERVATION);
storage.copy(storage, oldMetadataPath, newMetadataPath);
}
}
}
private void copyOtherMetadata(StorageService storage, StoragePath sourcePath, StoragePath targetPath) {
List<String> metadataTypes = Arrays.asList(selectedOtherMetadata.split(",\\s*"));
if (includeSelectedOtherMetadata) {
for (String type : metadataTypes) {
try {
StoragePath oldMetadataPath = DefaultStoragePath.parse(sourcePath, RodaConstants.STORAGE_DIRECTORY_METADATA,
RodaConstants.STORAGE_DIRECTORY_OTHER, type);
if (storage.hasDirectory(oldMetadataPath)) {
StoragePath newMetadataPath = DefaultStoragePath.parse(targetPath, RodaConstants.STORAGE_DIRECTORY_METADATA,
RodaConstants.STORAGE_DIRECTORY_OTHER, type);
storage.copy(storage, oldMetadataPath, newMetadataPath);
}
} catch (RequestNotValidException | AlreadyExistsException | GenericException | NotFoundException
| AuthorizationDeniedException e) {
LOGGER.error("Error copying other metadata type '{}' when creating EARK-DIP", type, e);
}
}
} else {
try {
StoragePath oldMetadataPath = DefaultStoragePath.parse(sourcePath, RodaConstants.STORAGE_DIRECTORY_METADATA,
RodaConstants.STORAGE_DIRECTORY_OTHER);
if (storage.hasDirectory(oldMetadataPath)) {
StoragePath newMetadataPath = DefaultStoragePath.parse(targetPath, RodaConstants.STORAGE_DIRECTORY_METADATA,
RodaConstants.STORAGE_DIRECTORY_OTHER);
storage.copy(storage, oldMetadataPath, newMetadataPath);
}
} catch (RequestNotValidException | AlreadyExistsException | GenericException | NotFoundException
| AuthorizationDeniedException e) {
LOGGER.error("Error copying other metadata '{}' when creating EARK-DIP", e);
}
}
}
private void copyAndUpdateAIPJson(StorageService storage, AIP aip, StoragePath aipOnDIPPath,
List<String> representationIds) throws GenericException, RequestNotValidException, AlreadyExistsException,
AuthorizationDeniedException, NotFoundException {
String json = JsonUtils.getJsonFromObject(aip);
JsonNode parseJson = JsonUtils.parseJson(json);
JsonNode representationList = parseJson.get(RodaConstants.AIP_REPRESENTATIONS);
for (Iterator<JsonNode> representationIt = representationList.elements(); representationIt.hasNext();) {
JsonNode representation = representationIt.next();
if (!representationIds.contains(representation.get("id").asText())) {
representationIt.remove();
}
}
JsonNode metadataList = parseJson.get(RodaConstants.AIP_DESCRIPTIVE_METADATA);
for (Iterator<JsonNode> descriptiveMetadataIt = metadataList.elements(); descriptiveMetadataIt.hasNext();) {
JsonNode descriptiveMetadata = descriptiveMetadataIt.next();
if (!representationIds.contains(descriptiveMetadata.get("id").asText())) {
descriptiveMetadataIt.remove();
}
}
String updatedJson = parseJson.toString();
StringContentPayload content = new StringContentPayload(updatedJson);
StoragePath aipJson = DefaultStoragePath.parse(aipOnDIPPath, RodaConstants.STORAGE_AIP_METADATA_FILENAME);
storage.createBinary(aipJson, content, false);
}
}