diff --git a/domain/src/main/java/org/fao/geonet/domain/StatusValue.java b/domain/src/main/java/org/fao/geonet/domain/StatusValue.java index 26d5bf4ccc92..47f36e604064 100644 --- a/domain/src/main/java/org/fao/geonet/domain/StatusValue.java +++ b/domain/src/main/java/org/fao/geonet/domain/StatusValue.java @@ -24,9 +24,11 @@ package org.fao.geonet.domain; import org.fao.geonet.entitylistener.StatusValueEntityListenerManager; +import org.springframework.http.MediaType; import javax.persistence.*; +import java.util.Arrays; import java.util.Map; /** @@ -223,20 +225,141 @@ public static final class Status { * List of predefined status part of the events. Those values are the default * one for GeoNetwork and may be modified in the database. */ - public static final class Events { - public static final String RECORDCREATED = "50"; - public static final String RECORDUPDATED = "51"; - public static final String ATTACHMENTADDED = "52"; - public static final String ATTACHMENTDELETED = "53"; - public static final String RECORDOWNERCHANGE = "54"; - public static final String RECORDGROUPOWNERCHANGE = "55"; - public static final String RECORDPRIVILEGESCHANGE = "56"; - public static final String RECORDCATEGORYCHANGE = "57"; - public static final String RECORDVALIDATIONTRIGGERED = "58"; - public static final String RECORDSTATUSCHANGE = "59"; - public static final String RECORDPROCESSINGCHANGE = "60"; - public static final String RECORDDELETED = "61"; - public static final String RECORDIMPORTED = "62"; - public static final String RECORDRESTORED = "63"; + public enum Events { + RECORDCREATED(50, false, MediaType.APPLICATION_JSON, null), + RECORDUPDATED(51, true, MediaType.APPLICATION_XML, MediaType.APPLICATION_XML), + ATTACHMENTADDED(52, false, MediaType.TEXT_PLAIN, null), + ATTACHMENTDELETED(53, false, null, MediaType.TEXT_PLAIN), + RECORDOWNERCHANGE(54, false, MediaType.APPLICATION_JSON, MediaType.APPLICATION_JSON), + RECORDGROUPOWNERCHANGE(55, false, MediaType.APPLICATION_JSON, MediaType.APPLICATION_JSON), + RECORDPRIVILEGESCHANGE(56, false, MediaType.APPLICATION_JSON, MediaType.APPLICATION_JSON), + RECORDCATEGORYCHANGE(57, false, MediaType.APPLICATION_JSON, MediaType.APPLICATION_JSON), + RECORDVALIDATIONTRIGGERED(58, false, MediaType.TEXT_PLAIN, null), + RECORDSTATUSCHANGE(59, false, MediaType.APPLICATION_JSON, MediaType.APPLICATION_JSON), + RECORDPROCESSINGCHANGE(60, true, MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML), + RECORDDELETED(61, true, null, MediaType.APPLICATION_XML), + RECORDIMPORTED(62, false, MediaType.APPLICATION_JSON, null), + RECORDRESTORED(63, true, MediaType.APPLICATION_XML, MediaType.APPLICATION_XML); + + /** + * The id of the event. + */ + private final Integer id; + /** + * The restore function currently supports these states + */ + private final boolean isSupportedRestoreStatus; + + /** + * Indicates mime type of the current state will be stored in. + * This is generally json or xml and if it is null then the state is not supported. + */ + private final MediaType currentStateFormat; + + /** + * Indicates mime type of the previous state will be stored in. + * This is generally json or xml and if it is null then the state is not supported. + */ + private final MediaType previousStateFormat; + + /** + * Constructor. + * + * @param id the id of the event. + * @param isSupportedRestoreStatus the restore function currently supports these states. + * @param currentStateFormat indicates mime type of the current state will be stored in. + * @param previousStateFormat indicates mime type of the current state will be stored in. + */ + Events(Integer id, boolean isSupportedRestoreStatus, MediaType currentStateFormat, MediaType previousStateFormat) { + this.id = id; + this.isSupportedRestoreStatus = isSupportedRestoreStatus; + this.currentStateFormat = currentStateFormat; + this.previousStateFormat = previousStateFormat; + } + + /** + * Get the id of the event. + * + * @return the id of the event. + */ + public Integer getId() { + return id; + } + + /** + * Get the event from the id. + * + * @param id the id of the event. + * @return the event. + */ + public static Events fromId(Integer id) { + return Arrays.stream(values()) + .filter(event -> event.getId().equals(id)) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("No event found with id: " + id)); + } + + /** + * Get the code of the event. + * The code currently is the string representation of the id. + * + * @return the code of the event. + */ + public String getCode() { + return String.valueOf(id); + } + + /** + * Get the event from the code. + * + * @param code the code of the event. + * @return the event. + */ + public static Events fromCode(String code) { + return Arrays.stream(values()) + .filter(event -> event.getCode().equals(code)) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("No event found with code: " + code)); + } + + /** + * Get the mime type of the current state will be stored in. + * + * @return the mime type of the current state will be stored in. + */ + public MediaType getCurrentStateFormat() { + return currentStateFormat; + } + + /** + * Get the mime type of the previous state will be stored in. + * + * @return the mime type of the previous state will be stored in. + */ + public MediaType getPreviousStateFormat() { + return previousStateFormat; + } + + /** + * Identify if the current status supports restoring the values. + * This is mostly for restoring xml metadata records. + * + * @return true if supported. + */ + public boolean isSupportedRestoreStatus() { + return isSupportedRestoreStatus; + } + + /** + * Get an array of the event that support restoring statuses. + * This is mostly for restoring xml metadata records. + * + * @return list of events with isSupportedRestoreStatus set to true. + */ + public static Events[] getSupportedRestoreStatuses() { + return Arrays.stream(values()) + .filter(Events::isSupportedRestoreStatus) + .toArray(Events[]::new); + } } } diff --git a/listeners/src/main/java/org/fao/geonet/listener/history/AttachmentAddedListener.java b/listeners/src/main/java/org/fao/geonet/listener/history/AttachmentAddedListener.java index e8df7be7bb42..91faa0fc5018 100644 --- a/listeners/src/main/java/org/fao/geonet/listener/history/AttachmentAddedListener.java +++ b/listeners/src/main/java/org/fao/geonet/listener/history/AttachmentAddedListener.java @@ -31,7 +31,7 @@ public class AttachmentAddedListener extends GenericMetadataEventListener implements ApplicationListener { private String changeMessage = ""; - private String eventType = StatusValue.Events.ATTACHMENTADDED; + private final StatusValue.Events eventType = StatusValue.Events.ATTACHMENTADDED; @Override public String getChangeMessage() { @@ -40,7 +40,7 @@ public String getChangeMessage() { @Override public String getEventType() { - return eventType; + return eventType.getCode(); } @Override diff --git a/listeners/src/main/java/org/fao/geonet/listener/history/AttachmentDeletedListener.java b/listeners/src/main/java/org/fao/geonet/listener/history/AttachmentDeletedListener.java index e94a9680efc8..548e60dbc499 100644 --- a/listeners/src/main/java/org/fao/geonet/listener/history/AttachmentDeletedListener.java +++ b/listeners/src/main/java/org/fao/geonet/listener/history/AttachmentDeletedListener.java @@ -31,7 +31,7 @@ public class AttachmentDeletedListener extends GenericMetadataEventListener implements ApplicationListener { private String changeMessage = ""; - private String eventType = StatusValue.Events.ATTACHMENTDELETED; + private final StatusValue.Events eventType = StatusValue.Events.ATTACHMENTDELETED; @Override public String getChangeMessage() { @@ -40,7 +40,7 @@ public String getChangeMessage() { @Override public String getEventType() { - return eventType; + return eventType.getCode(); } @Override diff --git a/listeners/src/main/java/org/fao/geonet/listener/history/RecordCategoryChangeListener.java b/listeners/src/main/java/org/fao/geonet/listener/history/RecordCategoryChangeListener.java index 3412db6657a1..3c74a73c604a 100644 --- a/listeners/src/main/java/org/fao/geonet/listener/history/RecordCategoryChangeListener.java +++ b/listeners/src/main/java/org/fao/geonet/listener/history/RecordCategoryChangeListener.java @@ -31,7 +31,7 @@ public class RecordCategoryChangeListener extends GenericMetadataEventListener implements ApplicationListener { private String changeMessage = ""; - private String eventType = StatusValue.Events.RECORDCATEGORYCHANGE; + private final StatusValue.Events eventType = StatusValue.Events.RECORDCATEGORYCHANGE; @Override public String getChangeMessage() { @@ -40,7 +40,7 @@ public String getChangeMessage() { @Override public String getEventType() { - return eventType; + return eventType.getCode(); } @Override diff --git a/listeners/src/main/java/org/fao/geonet/listener/history/RecordCreatedListener.java b/listeners/src/main/java/org/fao/geonet/listener/history/RecordCreatedListener.java index 99909f079a6c..581f695f1cc5 100644 --- a/listeners/src/main/java/org/fao/geonet/listener/history/RecordCreatedListener.java +++ b/listeners/src/main/java/org/fao/geonet/listener/history/RecordCreatedListener.java @@ -31,7 +31,7 @@ public class RecordCreatedListener extends GenericMetadataEventListener implements ApplicationListener { private String changeMessage = ""; - private String eventType = StatusValue.Events.RECORDCREATED; + private final StatusValue.Events eventType = StatusValue.Events.RECORDCREATED; @Override public String getChangeMessage() { @@ -40,7 +40,7 @@ public String getChangeMessage() { @Override public String getEventType() { - return eventType; + return eventType.getCode(); } @Override diff --git a/listeners/src/main/java/org/fao/geonet/listener/history/RecordDeletedListener.java b/listeners/src/main/java/org/fao/geonet/listener/history/RecordDeletedListener.java index d3b02d855959..5f3b4d249b34 100644 --- a/listeners/src/main/java/org/fao/geonet/listener/history/RecordDeletedListener.java +++ b/listeners/src/main/java/org/fao/geonet/listener/history/RecordDeletedListener.java @@ -31,7 +31,7 @@ public class RecordDeletedListener extends GenericMetadataEventListener implements ApplicationListener { private String changeMessage = ""; - private String eventType = StatusValue.Events.RECORDDELETED; + private final StatusValue.Events eventType = StatusValue.Events.RECORDDELETED; @Override public String getChangeMessage() { @@ -40,7 +40,7 @@ public String getChangeMessage() { @Override public String getEventType() { - return eventType; + return eventType.getCode(); } @Override diff --git a/listeners/src/main/java/org/fao/geonet/listener/history/RecordGroupOwnerChangeListener.java b/listeners/src/main/java/org/fao/geonet/listener/history/RecordGroupOwnerChangeListener.java index bebd54bfa7c0..4f6d4a5a5414 100644 --- a/listeners/src/main/java/org/fao/geonet/listener/history/RecordGroupOwnerChangeListener.java +++ b/listeners/src/main/java/org/fao/geonet/listener/history/RecordGroupOwnerChangeListener.java @@ -32,7 +32,7 @@ public class RecordGroupOwnerChangeListener extends GenericMetadataEventListener implements ApplicationListener { private String changeMessage = ""; - private String eventType = StatusValue.Events.RECORDGROUPOWNERCHANGE; + private final StatusValue.Events eventType = StatusValue.Events.RECORDGROUPOWNERCHANGE; @Override public String getChangeMessage() { @@ -41,7 +41,7 @@ public String getChangeMessage() { @Override public String getEventType() { - return eventType; + return eventType.getCode(); } @Override diff --git a/listeners/src/main/java/org/fao/geonet/listener/history/RecordImportedListener.java b/listeners/src/main/java/org/fao/geonet/listener/history/RecordImportedListener.java index b3569c018c13..dae5ed3068aa 100644 --- a/listeners/src/main/java/org/fao/geonet/listener/history/RecordImportedListener.java +++ b/listeners/src/main/java/org/fao/geonet/listener/history/RecordImportedListener.java @@ -31,7 +31,7 @@ public class RecordImportedListener extends GenericMetadataEventListener implements ApplicationListener { private String changeMessage = ""; - private String eventType = StatusValue.Events.RECORDIMPORTED; + private final StatusValue.Events eventType = StatusValue.Events.RECORDIMPORTED; @Override public String getChangeMessage() { @@ -40,7 +40,7 @@ public String getChangeMessage() { @Override public String getEventType() { - return eventType; + return eventType.getCode(); } @Override diff --git a/listeners/src/main/java/org/fao/geonet/listener/history/RecordOwnerChangeListener.java b/listeners/src/main/java/org/fao/geonet/listener/history/RecordOwnerChangeListener.java index 434f8b5d5197..9ab4620aec58 100644 --- a/listeners/src/main/java/org/fao/geonet/listener/history/RecordOwnerChangeListener.java +++ b/listeners/src/main/java/org/fao/geonet/listener/history/RecordOwnerChangeListener.java @@ -31,7 +31,7 @@ public class RecordOwnerChangeListener extends GenericMetadataEventListener implements ApplicationListener { private String changeMessage = ""; - private String eventType = StatusValue.Events.RECORDOWNERCHANGE; + private final StatusValue.Events eventType = StatusValue.Events.RECORDOWNERCHANGE; @Override public String getChangeMessage() { @@ -40,7 +40,7 @@ public String getChangeMessage() { @Override public String getEventType() { - return eventType; + return eventType.getCode(); } @Override diff --git a/listeners/src/main/java/org/fao/geonet/listener/history/RecordPrivilegesChangeListener.java b/listeners/src/main/java/org/fao/geonet/listener/history/RecordPrivilegesChangeListener.java index 1662c04f5d6a..9ba5204054c2 100644 --- a/listeners/src/main/java/org/fao/geonet/listener/history/RecordPrivilegesChangeListener.java +++ b/listeners/src/main/java/org/fao/geonet/listener/history/RecordPrivilegesChangeListener.java @@ -32,7 +32,7 @@ public class RecordPrivilegesChangeListener extends GenericMetadataEventListener implements ApplicationListener { private String changeMessage = ""; - private String eventType = StatusValue.Events.RECORDPRIVILEGESCHANGE; + private final StatusValue.Events eventType = StatusValue.Events.RECORDPRIVILEGESCHANGE; @Override public String getChangeMessage() { @@ -41,7 +41,7 @@ public String getChangeMessage() { @Override public String getEventType() { - return eventType; + return eventType.getCode(); } @Override diff --git a/listeners/src/main/java/org/fao/geonet/listener/history/RecordProcessingChangeListener.java b/listeners/src/main/java/org/fao/geonet/listener/history/RecordProcessingChangeListener.java index 811eb0dc8336..2134a0239d9e 100644 --- a/listeners/src/main/java/org/fao/geonet/listener/history/RecordProcessingChangeListener.java +++ b/listeners/src/main/java/org/fao/geonet/listener/history/RecordProcessingChangeListener.java @@ -32,7 +32,7 @@ public class RecordProcessingChangeListener extends GenericMetadataEventListener implements ApplicationListener { private String changeMessage = ""; - private String eventType = StatusValue.Events.RECORDPROCESSINGCHANGE; + private final StatusValue.Events eventType = StatusValue.Events.RECORDPROCESSINGCHANGE; @Override public String getChangeMessage() { @@ -41,7 +41,7 @@ public String getChangeMessage() { @Override public String getEventType() { - return eventType; + return eventType.getCode(); } @Override diff --git a/listeners/src/main/java/org/fao/geonet/listener/history/RecordRestoredListener.java b/listeners/src/main/java/org/fao/geonet/listener/history/RecordRestoredListener.java index ad9a94b3c7c5..578ba20bdcba 100644 --- a/listeners/src/main/java/org/fao/geonet/listener/history/RecordRestoredListener.java +++ b/listeners/src/main/java/org/fao/geonet/listener/history/RecordRestoredListener.java @@ -31,7 +31,7 @@ public class RecordRestoredListener extends GenericMetadataEventListener implements ApplicationListener { private String changeMessage = ""; - private String eventType = StatusValue.Events.RECORDRESTORED; + private final StatusValue.Events eventType = StatusValue.Events.RECORDRESTORED; @Override public String getChangeMessage() { @@ -40,7 +40,7 @@ public String getChangeMessage() { @Override public String getEventType() { - return eventType; + return eventType.getCode(); } @Override diff --git a/listeners/src/main/java/org/fao/geonet/listener/history/RecordUpdatedListener.java b/listeners/src/main/java/org/fao/geonet/listener/history/RecordUpdatedListener.java index bcda0cf43d8d..958dbf8657cb 100644 --- a/listeners/src/main/java/org/fao/geonet/listener/history/RecordUpdatedListener.java +++ b/listeners/src/main/java/org/fao/geonet/listener/history/RecordUpdatedListener.java @@ -31,7 +31,7 @@ public class RecordUpdatedListener extends GenericMetadataEventListener implements ApplicationListener { private String changeMessage = ""; - private String eventType = StatusValue.Events.RECORDUPDATED; + private final StatusValue.Events eventType = StatusValue.Events.RECORDUPDATED; @Override public String getChangeMessage() { @@ -40,7 +40,7 @@ public String getChangeMessage() { @Override public String getEventType() { - return eventType; + return eventType.getCode(); } @Override diff --git a/listeners/src/main/java/org/fao/geonet/listener/history/RecordValidationTriggeredListener.java b/listeners/src/main/java/org/fao/geonet/listener/history/RecordValidationTriggeredListener.java index a34d961f1603..e0e433d4aacb 100644 --- a/listeners/src/main/java/org/fao/geonet/listener/history/RecordValidationTriggeredListener.java +++ b/listeners/src/main/java/org/fao/geonet/listener/history/RecordValidationTriggeredListener.java @@ -32,7 +32,7 @@ public class RecordValidationTriggeredListener extends GenericMetadataEventListe implements ApplicationListener { private String changeMessage = ""; - private String eventType = StatusValue.Events.RECORDVALIDATIONTRIGGERED; + private final StatusValue.Events eventType = StatusValue.Events.RECORDVALIDATIONTRIGGERED; @Override public String getChangeMessage() { @@ -41,7 +41,7 @@ public String getChangeMessage() { @Override public String getEventType() { - return eventType; + return eventType.getCode(); } @Override diff --git a/services/src/main/java/org/fao/geonet/api/records/MetadataWorkflowApi.java b/services/src/main/java/org/fao/geonet/api/records/MetadataWorkflowApi.java index a134e727c7c2..365cf3e80acc 100644 --- a/services/src/main/java/org/fao/geonet/api/records/MetadataWorkflowApi.java +++ b/services/src/main/java/org/fao/geonet/api/records/MetadataWorkflowApi.java @@ -68,8 +68,6 @@ import org.jdom.Element; import org.jdom.input.JDOMParseException; import org.jdom.output.XMLOutputter; -import org.json.JSONException; -import org.json.JSONObject; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.data.domain.PageRequest; @@ -85,6 +83,7 @@ import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.util.*; +import java.util.stream.Collectors; import static org.fao.geonet.api.ApiParams.*; import static org.fao.geonet.kernel.setting.Settings.SYSTEM_METADATAPRIVS_PUBLICATION_NOTIFICATIONLEVEL; @@ -162,11 +161,7 @@ public class MetadataWorkflowApi { RoleHierarchy roleHierarchy; // The restore function currently supports these states - static final Integer[] supportedRestoreStatuses = { - Integer.parseInt(StatusValue.Events.RECORDUPDATED), - Integer.parseInt(StatusValue.Events.RECORDPROCESSINGCHANGE), - Integer.parseInt(StatusValue.Events.RECORDDELETED), - Integer.parseInt(StatusValue.Events.RECORDRESTORED)}; + static final StatusValue.Events[] supportedRestoreStatuses = StatusValue.Events.getSupportedRestoreStatuses(); private enum State { BEFORE, AFTER @@ -1051,15 +1046,15 @@ private List buildMetadataStatusResponses(List categories = ObjectJSONUtils.extractListOfFieldFromJSONString(s.getCurrentState(), "category", "name"); StringBuilder categoriesAsString = new StringBuilder("[ "); @@ -1068,7 +1063,7 @@ private String extractCurrentStatus(MetadataStatus s) { } categoriesAsString.append("]"); return categoriesAsString.toString(); - case StatusValue.Events.RECORDVALIDATIONTRIGGERED: + case RECORDVALIDATIONTRIGGERED: if (s.getCurrentState() == null) { return "UNKNOWN"; } else if (s.getCurrentState().equals("1")) { @@ -1082,11 +1077,11 @@ private String extractCurrentStatus(MetadataStatus s) { } private String extractPreviousStatus(MetadataStatus s) { - switch (Integer.toString(s.getStatusValue().getId())) { - case StatusValue.Events.ATTACHMENTDELETED: + switch (StatusValue.Events.fromId(s.getStatusValue().getId())) { + case ATTACHMENTDELETED: return s.getPreviousState(); - case StatusValue.Events.RECORDOWNERCHANGE: - case StatusValue.Events.RECORDGROUPOWNERCHANGE: + case RECORDOWNERCHANGE: + case RECORDGROUPOWNERCHANGE: return ObjectJSONUtils.extractFieldFromJSONString(s.getPreviousState(), "owner", "name"); default: return ""; @@ -1232,20 +1227,31 @@ private MetadataStatus getMetadataStatus(String uuidOrInternalId, int statusId, private String getValidatedStateText(MetadataStatus metadataStatus, State state, HttpServletRequest request, HttpSession httpSession) throws Exception { if (!StatusValueType.event.equals(metadataStatus.getStatusValue().getType()) - || !ArrayUtils.contains(supportedRestoreStatuses, metadataStatus.getStatusValue().getId())) { + || !ArrayUtils.contains(supportedRestoreStatuses, StatusValue.Events.fromId(metadataStatus.getStatusValue().getId()))) { throw new NotAllowedException("Unsupported action on status type '" + metadataStatus.getStatusValue().getType() + "' for metadata '" + metadataStatus.getUuid() + "'. Supports status type '" - + StatusValueType.event + "' with the status id '" + Arrays.toString(supportedRestoreStatuses) + "'."); + + StatusValueType.event + "' with the status id '" + Arrays.stream(supportedRestoreStatuses).map(StatusValue.Events::getId).collect(Collectors.toList()) + "'."); } String stateText; + MediaType stateFormat; if (state.equals(State.AFTER)) { stateText = metadataStatus.getCurrentState(); + stateFormat = StatusValue.Events.fromId(metadataStatus.getStatusValue().getId()).getCurrentStateFormat(); } else { stateText = metadataStatus.getPreviousState(); + stateFormat = StatusValue.Events.fromId(metadataStatus.getStatusValue().getId()).getPreviousStateFormat(); } - if (stateText == null) { + String xmlStateText; + if (stateFormat.equals(MediaType.APPLICATION_JSON)) { + // Any status with JSON format will have the XML stored in the field 'xmlRecord' + xmlStateText = ObjectJSONUtils.extractFieldFromJSONString(stateText, "xmlRecord"); + } else { + xmlStateText = stateText; + } + + if (xmlStateText == null) { throw new ResourceNotFoundException( String.format("No data exists for previous state on metadata record '%s', user '%d' at date '%s'", metadataStatus.getUuid(), metadataStatus.getUserId(), metadataStatus.getChangeDate())); @@ -1260,30 +1266,10 @@ private String getValidatedStateText(MetadataStatus metadataStatus, State state, } catch (ResourceNotFoundException e) { // If metadata record does not exists then it was deleted so // we will only allow the administrator, owner to view the contents - checkCanViewStatus(stateText, httpSession); + checkCanViewStatus(xmlStateText, httpSession); } - if (isValidJSON(stateText)) { - JSONObject json = new JSONObject(stateText); - String xmlRecord = json.getString("xmlRecord"); - return xmlRecord; - } - - return stateText; - } - - /** - * Check if the input string is valid JSON format string - * @param json input string - * @return boolean if string is JSON format - */ - private boolean isValidJSON(String json) { - try { - new JSONObject(json); - } catch (JSONException e) { - return false; - } - return true; + return xmlStateText; } /**