Skip to content

Commit

Permalink
Fixed history reversion methods for representation descriptive metada…
Browse files Browse the repository at this point in the history
…ta (#3249)

Signed-off-by: sugarylump <[email protected]>
  • Loading branch information
SugaryLump authored Jul 5, 2024
1 parent b7097bf commit eb6a640
Show file tree
Hide file tree
Showing 8 changed files with 155 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -859,7 +859,8 @@ public BinaryVersion revertDescriptiveMetadataVersion(String aipId, String repre
BinaryVersion currentVersion = storage.createBinaryVersion(binaryPath, properties);
storage.revertBinaryVersion(binaryPath, versionId);

notifyDescriptiveMetadataUpdated(retrieveDescriptiveMetadata(aipId, descriptiveMetadataId)).failOnError();
notifyDescriptiveMetadataUpdated(retrieveDescriptiveMetadata(aipId, representationId, descriptiveMetadataId))
.failOnError();

return currentVersion;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ core.permissions.org.roda.wui.api.v2.controller.AIPController.retrieveRepresenta
core.permissions.org.roda.wui.api.v2.controller.AIPController.createRepresentationDescriptiveMetadata = CREATE
core.permissions.org.roda.wui.api.v2.controller.AIPController.isAIPMetadataSimilar = READ
core.permissions.org.roda.wui.api.v2.controller.AIPController.isRepresentationMetadataSimilar = READ
core.permissions.org.roda.wui.api.v2.controller.AIPController.retrieveAIPDescriptiveMetadataVersions = READ
core.permissions.org.roda.wui.api.v2.controller.AIPController.revertAIPDescriptiveMetadataVersion = UPDATE
core.permissions.org.roda.wui.api.v2.controller.AIPController.retrieveRepresentationDescriptiveMetadataVersions = READ
core.permissions.org.roda.wui.api.v2.controller.AIPController.revertRepresentationDescriptiveMetadataVersion = UPDATE

# Representation permissions
core.permissions.org.roda.wui.api.v2.controller.RepresentationController.createRepresentation = CREATE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,11 @@ core.roles.org.roda.wui.api.v2.controller.AIPController.createRepresentationDesc
core.roles.org.roda.wui.api.v2.controller.AIPController.updateAIPDescriptiveMetadataFile = descriptive_metadata.update
core.roles.org.roda.wui.api.v2.controller.AIPController.updateRepresentationDescriptiveMetadataFile = descriptive_metadata.update
core.roles.org.roda.wui.api.v2.controller.AIPController.retrieveRepresentationDescriptiveMetadataVersions = descriptive_metadata.read
core.roles.org.roda.wui.api.v2.controller.AIPController.revertRepresentationDescriptiveMetadataVersion = descriptive_metadata.update
core.roles.org.roda.wui.api.v2.controller.AIPController.isAIPMetadataSimilar = descriptive_metadata.read
core.roles.org.roda.wui.api.v2.controller.AIPController.isRepresentationMetadataSimilar = descriptive_metadata.read

core.roles.org.roda.wui.api.v2.controller.AIPController.retrieveAIPDescriptiveMetadataVersions = descriptive_metadata.read
core.roles.org.roda.wui.api.v2.controller.AIPController.revertAIPDescriptiveMetadataVersion = descriptive_metadata.update

# Transferred resource roles
core.roles.org.roda.wui.api.v2.controller.TransferredResourceController.createTransferredResourcesFolder = transfer.create
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ public List<String> suggest(@RequestBody SuggestRequest suggestRequest) {
return indexService.suggest(suggestRequest, IndexedAIP.class, requestContext);
}

@GetMapping(path = "/{id}/representation/{representation-id}/download", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
@GetMapping(path = "/{id}/representations/{representation-id}/download", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
@Operation(summary = "Downloads representation", description = "Download a particular representation", responses = {
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = ResponseEntity.class))),
@ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class))),
Expand Down Expand Up @@ -386,46 +386,6 @@ ResponseEntity<StreamingResponseBody> retrieveAIPDescriptiveMetadataHTML(
}
}

@GetMapping(path = "/{id}/representations/{representation-id}/metadata/descriptive/{descriptive-metadata-id}/html", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
@Operation(summary = "Retrieves descriptive metadata result", responses = {
@ApiResponse(responseCode = "200", description = "Returns an object ", content = @Content(schema = @Schema(implementation = ResponseEntity.class))),
@ApiResponse(responseCode = "401", description = "Unauthorized access", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class))),
@ApiResponse(responseCode = "403", description = "Forbidden", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class))),
@ApiResponse(responseCode = "404", description = "Not found", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class))),})
ResponseEntity<StreamingResponseBody> retrieveRepresentationDescriptiveMetadataHTML(
@Parameter(description = "The AIP identifier", required = true) @PathVariable(name = "id") String aipId,
@Parameter(description = "The representation identifier", required = true) @PathVariable(name = "representation-id") String representationId,
@Parameter(description = "The descriptive metadata identifier", required = true) @PathVariable(name = "descriptive-metadata-id") String descriptiveMetadataId,
@Parameter(description = "The language to be used for internationalization", content = @Content(schema = @Schema(defaultValue = "en", implementation = String.class))) @RequestParam(name = "lang", defaultValue = "en", required = false) String localeString) {
ControllerAssistant controllerAssistant = new ControllerAssistant() {};
RequestContext requestContext = RequestUtils.parseHTTPRequest(request);
LogEntryState state = LogEntryState.SUCCESS;

try {
// check user permissions
controllerAssistant.checkRoles(requestContext.getUser());

IndexedRepresentation representation = RodaCoreFactory.getIndexService().retrieve(IndexedRepresentation.class,
IdUtils.getRepresentationId(aipId, representationId), RodaConstants.REPRESENTATION_FIELDS_TO_RETURN);
controllerAssistant.checkObjectPermissions(requestContext.getUser(), representation);

// delegate
StreamResponse streamResponse = representationService.retrieveRepresentationDescriptiveMetadata(aipId,
representationId, descriptiveMetadataId, localeString);
return ApiUtils.okResponse(streamResponse, null);
} catch (AuthorizationDeniedException e) {
state = LogEntryState.UNAUTHORIZED;
throw new RESTException(e);
} catch (RequestNotValidException | GenericException | NotFoundException e) {
state = LogEntryState.FAILURE;
throw new RESTException(e);
} finally {
controllerAssistant.registerAction(requestContext, state, RodaConstants.CONTROLLER_AIP_ID_PARAM, aipId,
RodaConstants.CONTROLLER_REPRESENTATION_ID_PARAM, representationId, RodaConstants.CONTROLLER_METADATA_ID_PARAM,
descriptiveMetadataId);
}
}

@GetMapping(path = "{id}/download/documentation", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
@Operation(summary = "Downloads documentation", description = "Download AIP documentation", responses = {
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = ResponseEntity.class))),
Expand Down Expand Up @@ -596,6 +556,89 @@ public ResponseEntity<StreamingResponseBody> downloadAIP(
}
}

@GetMapping(path = "/{id}/representations/{representation-id}/metadata/descriptive/{descriptive-metadata-id}/download", produces = MediaType.APPLICATION_XML_VALUE)
@Operation(summary = "Retrieves representation's descriptive metadata", description = "Retrieves the representation's XML descriptive metadata", responses = {
@ApiResponse(responseCode = "200", description = "Returns an object ", content = @Content(schema = @Schema(implementation = ResponseEntity.class))),
@ApiResponse(responseCode = "401", description = "Unauthorized access", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class))),
@ApiResponse(responseCode = "403", description = "Forbidden", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class))),
@ApiResponse(responseCode = "404", description = "Not found", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class))),})
ResponseEntity<StreamingResponseBody> downloadRepresentationDescriptiveMetadata(
@Parameter(description = "The AIP identifier", required = true) @PathVariable(name = "id") String aipId,
@Parameter(description = "The AIP's representation identifier", required = true) @PathVariable(name = "representation-id") String representationId,
@Parameter(description = "The descriptive metadata identifier", required = true) @PathVariable(name = "descriptive-metadata-id") String descriptiveMetadataId,
@Parameter(description = "The version identifier") @RequestParam(name = "version-id", required = false) String versionId) {
ControllerAssistant controllerAssistant = new ControllerAssistant() {};
RequestContext requestContext = RequestUtils.parseHTTPRequest(request);
LogEntryState state = LogEntryState.SUCCESS;

try {
// check user permissions
controllerAssistant.checkRoles(requestContext.getUser());

// check object permissions
IndexedRepresentation indexedRepresentation = RodaCoreFactory.getIndexService().retrieve(
IndexedRepresentation.class, IdUtils.getRepresentationId(aipId, representationId),
RodaConstants.REPRESENTATION_FIELDS_TO_RETURN);
controllerAssistant.checkObjectPermissions(requestContext.getUser(), indexedRepresentation);

// delegate
StreamResponse streamResponse = aipService.downloadRepresentationDescriptiveMetadata(aipId, representationId,
descriptiveMetadataId, versionId);
return ApiUtils.okResponse(streamResponse);
} catch (AuthorizationDeniedException e) {
state = LogEntryState.UNAUTHORIZED;
throw new RESTException(e);
} catch (RequestNotValidException | GenericException | NotFoundException e) {
state = LogEntryState.FAILURE;
throw new RESTException(e);
} finally {
controllerAssistant.registerAction(requestContext, state, RodaConstants.CONTROLLER_AIP_ID_PARAM, aipId,
RodaConstants.CONTROLLER_METADATA_ID_PARAM, descriptiveMetadataId);
}
}

@GetMapping(path = "/{id}/representations/{representation-id}/metadata/descriptive/{descriptive-metadata-id}/html", produces = MediaType.TEXT_HTML_VALUE)
@Operation(summary = "Retrieves representation's descriptive metadata", description = "Retrieves the representation's descriptive metadata with the visualization template applied and internationalized", responses = {
@ApiResponse(responseCode = "200", description = "Returns an object ", content = @Content(schema = @Schema(implementation = ResponseEntity.class))),
@ApiResponse(responseCode = "401", description = "Unauthorized access", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class))),
@ApiResponse(responseCode = "403", description = "Forbidden", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class))),
@ApiResponse(responseCode = "404", description = "Not found", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class))),})
ResponseEntity<StreamingResponseBody> retrieveRepresentationDescriptiveMetadataHTML(
@Parameter(description = "The AIP identifier", required = true) @PathVariable(name = "id") String aipId,
@Parameter(description = "The AIP's representation identifier", required = true) @PathVariable(name = "representation-id") String representationId,
@Parameter(description = "The representation's descriptive metadata identifier", required = true) @PathVariable(name = "descriptive-metadata-id") String descriptiveMetadataId,
@Parameter(description = "The version identifier") @RequestParam(name = "version-id", required = false) String versionId,
@Parameter(description = "The language to be used for internationalization", content = @Content(schema = @Schema(defaultValue = "en", implementation = String.class))) @RequestParam(name = "lang", defaultValue = "en", required = false) String localeString) {
ControllerAssistant controllerAssistant = new ControllerAssistant() {};
RequestContext requestContext = RequestUtils.parseHTTPRequest(request);
LogEntryState state = LogEntryState.SUCCESS;

try {
// check user permissions
controllerAssistant.checkRoles(requestContext.getUser());

// check object permissions
IndexedRepresentation indexedRepresentation = RodaCoreFactory.getIndexService().retrieve(
IndexedRepresentation.class, IdUtils.getRepresentationId(aipId, representationId),
RodaConstants.REPRESENTATION_FIELDS_TO_RETURN);
controllerAssistant.checkObjectPermissions(requestContext.getUser(), indexedRepresentation);

// delegate
StreamResponse streamResponse = aipService.retrieveRepresentationDescriptiveMetadata(aipId, representationId,
descriptiveMetadataId, versionId, localeString);
return ApiUtils.okResponse(streamResponse);
} catch (AuthorizationDeniedException e) {
state = LogEntryState.UNAUTHORIZED;
throw new RESTException(e);
} catch (RequestNotValidException | GenericException | NotFoundException e) {
state = LogEntryState.FAILURE;
throw new RESTException(e);
} finally {
controllerAssistant.registerAction(requestContext, state, RodaConstants.CONTROLLER_AIP_ID_PARAM, aipId,
RodaConstants.CONTROLLER_METADATA_ID_PARAM, descriptiveMetadataId);
}
}

@Override
public DescriptiveMetadata createRepresentationDescriptiveMetadata(String aipId, String representationId,
@RequestBody CreateDescriptiveMetadataRequest createDescriptiveMetadataRequest) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,52 @@ public StreamResponse retrieveAIPDescriptiveMetadata(String aipId, String metada
return new StreamResponse(stream);
}

public StreamResponse downloadRepresentationDescriptiveMetadata(String aipId, String representationId,
String metadataId, String versionId)
throws AuthorizationDeniedException, RequestNotValidException, NotFoundException, GenericException {
ModelService modelService = RodaCoreFactory.getModelService();
Binary descriptiveMetadataBinary;
if (versionId == null) {
descriptiveMetadataBinary = modelService.retrieveDescriptiveMetadataBinary(aipId, representationId, metadataId);

} else {
StoragePath storagePath = ModelUtils.getDescriptiveMetadataStoragePath(aipId, representationId, metadataId);
BinaryVersion binaryVersion = modelService.getStorage().getBinaryVersion(storagePath, versionId);
descriptiveMetadataBinary = binaryVersion.getBinary();
}

return new StreamResponse(
new BinaryConsumesOutputStream(descriptiveMetadataBinary, RodaConstants.MEDIA_TYPE_APPLICATION_XML));
}

public StreamResponse retrieveRepresentationDescriptiveMetadata(String aipId, String representationId,
String metadataId, String versionId, String localeString)
throws AuthorizationDeniedException, RequestNotValidException, NotFoundException, GenericException {
ModelService model = RodaCoreFactory.getModelService();
Binary descriptiveMetadataBinary;
if (versionId != null) {
StoragePath storagePath = ModelUtils.getDescriptiveMetadataStoragePath(aipId, representationId, metadataId);
BinaryVersion binaryVersion = model.getStorage().getBinaryVersion(storagePath, versionId);
descriptiveMetadataBinary = binaryVersion.getBinary();
} else {
descriptiveMetadataBinary = model.retrieveDescriptiveMetadataBinary(aipId, representationId, metadataId);
}

String filename = descriptiveMetadataBinary.getStoragePath().getName() + HTML_EXT;
DescriptiveMetadata descriptiveMetadata = model.retrieveDescriptiveMetadata(aipId, representationId, metadataId);
String htmlDescriptive = HTMLUtils.descriptiveMetadataToHtml(descriptiveMetadataBinary,
descriptiveMetadata.getType(), descriptiveMetadata.getVersion(), ServerTools.parseLocale(localeString));

ConsumesOutputStream stream = new DefaultConsumesOutputStream(filename, RodaConstants.MEDIA_TYPE_APPLICATION_XML,
out -> {
PrintStream printStream = new PrintStream(out);
printStream.print(htmlDescriptive);
printStream.close();
});

return new StreamResponse(stream);
}

public List<IndexedAIP> getAncestors(IndexedAIP indexedAIP, User user) throws GenericException {
return RodaCoreFactory.getIndexService().retrieveAncestors(indexedAIP, user, new ArrayList<>());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ public void resolve(List<String> historyTokens, final AsyncCallback<Widget> call
if (throwable != null) {
AsyncCallbackUtils.defaultFailureTreatment(throwable);
} else {
DescriptiveMetadataHistory widget = new DescriptiveMetadataHistory(aipId, null,
DescriptiveMetadataHistory widget = new DescriptiveMetadataHistory(aipId, representationId,
descriptiveMetadataId, result);
callback.onSuccess(widget);
}
Expand Down Expand Up @@ -284,7 +284,7 @@ private void getDescriptiveMetadata(final String aipId, final String representat
SafeUri uri;
if (inHTML) {
if (representationId != null) {
uri = RestUtils.createRepresentationDescriptiveMetadataHTMLUri(aipId, representationId, descId);
uri = RestUtils.createRepresentationDescriptiveMetadataHTMLUri(aipId, representationId, descId, versionKey);
} else {
uri = RestUtils.createDescriptiveMetadataHTMLUri(aipId, descId, versionKey);
}
Expand Down Expand Up @@ -401,7 +401,8 @@ public void onSuccess(Boolean result) {
AsyncCallbackUtils.defaultFailureTreatment(error);
} else {
Toast.showInfo(messages.dialogDone(), messages.versionReverted());
HistoryUtils.newHistory(BrowseTop.RESOLVER, aipId, representationId);
HistoryUtils.newHistory(BrowseTop.RESOLVER, RodaConstants.RODA_OBJECT_REPRESENTATION, aipId,
representationId);
}
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ DescriptiveMetadata revertAIPDescriptiveMetadataVersion(
@Parameter(description = "The descriptive metadata identifier", required = true) @PathVariable(name = "descriptive-metadata-id") String descriptiveMetadataId,
@Parameter(description = "The version identifier", required = true) @PathVariable(name = "version-id") String versionId);

@RequestMapping(path = "/{id}/representation/{representation-id}metadata/descriptive/{descriptive-metadata-id}/versions/{version-id}/revert", method = RequestMethod.PUT, produces = MediaType.APPLICATION_JSON_VALUE)
@RequestMapping(path = "/{id}/representation/{representation-id}/metadata/descriptive/{descriptive-metadata-id}/versions/{version-id}/revert", method = RequestMethod.PUT, produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "Reverts representation descriptive metadata to the an older version", description = "Reverts representation descriptive metadata to the an older version", responses = {
@ApiResponse(responseCode = "200", description = "Reverted descriptive metadata"),
@ApiResponse(responseCode = "401", description = "Unauthorized access", content = @Content(schema = @Schema(implementation = ErrorResponseMessage.class))),
Expand Down
Loading

0 comments on commit eb6a640

Please sign in to comment.