From 9aec262388a3032f16cfb4af5456c293a94933eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Reitmann?= Date: Mon, 2 Sep 2019 13:54:20 +0200 Subject: [PATCH 01/16] #2360 prepare sprint 91 --- pom.xml | 2 +- src/main/webapp/scripts/app.constants.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 8c36b5f0da..afb21af8b8 100644 --- a/pom.xml +++ b/pom.xml @@ -11,7 +11,7 @@ eu.dzhw.fdz.metadatamanagement metadatamanagement - 1.0.90 + 1.0.91-SNAPSHOT war metadatamanagement diff --git a/src/main/webapp/scripts/app.constants.js b/src/main/webapp/scripts/app.constants.js index daa4c4813b..b51651351b 100644 --- a/src/main/webapp/scripts/app.constants.js +++ b/src/main/webapp/scripts/app.constants.js @@ -6,7 +6,7 @@ angular.module('metadatamanagementApp') .constant('ENV', 'local') -.constant('VERSION', '1.0.90') +.constant('VERSION', '1.0.91-SNAPSHOT') .constant('ElasticSearchProperties', {apiVersion:'6.3',logLevel:'error',pageSize:10}) From 8e8f3982dad6706b0ed62a41e2818733df1ce5fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Reitmann?= Date: Mon, 9 Sep 2019 13:57:02 +0200 Subject: [PATCH 02/16] #2278 add hiding and unhiding of shadows to backend --- .../AbstractShadowableRdcDomainObject.rst | 14 ++- .../common/domain/Task-TaskType.rst | 6 - .../domain/ShadowCopyQueueItem-Action.rst | 49 ++++++++ .../domain/ShadowCopyQueueItem.rst | 10 +- .../ShadowHidingNotAllowedException.rst | 20 +++ .../ShadowUnhidingNotAllowedException.rst | 20 +++ .../domain/package-index.rst | 3 + .../AbstractShadowableRdcDomainObject.java | 14 ++- .../common/domain/Task.java | 3 +- .../domain/validation/ValidHiddenShadow.java | 38 ++++++ .../ValidHiddenShadowValidator.java | 31 +++++ ...GenericDomainObjectResourceController.java | 6 +- ...bstractAttachmentShadowCopyDataSource.java | 27 +++- ...nericShadowableDomainObjectCrudHelper.java | 73 +++++++---- .../common/service/ShadowCopyDataSource.java | 14 +++ .../common/service/ShadowCopyHelper.java | 53 +++++++- .../rest/ConceptResourceController.java | 2 +- .../DataSetAttachmentShadowCopyService.java | 15 --- .../service/DataSetShadowCopyService.java | 28 ----- .../helper/DataSetShadowCopyDataSource.java | 21 ++++ ...InstrumentAttachmentShadowCopyService.java | 15 --- .../service/InstrumentShadowCopyService.java | 28 ----- .../InstrumentShadowCopyDataSource.java | 21 ++++ .../ordermanagement/rest/OrderResource.java | 2 +- .../domain/ShadowCopyQueueItem.java | 15 ++- .../ShadowHidingNotAllowedException.java | 14 +++ .../ShadowUnhidingNotAllowedException.java | 14 +++ .../rest/DaraReleaseResource.java | 2 +- ...DataAcquisitionProjectShadowsResource.java | 119 ++++++++++++++++++ .../service/DaraService.java | 32 +++-- ...taAcquisitionProjectManagementService.java | 112 ++++++++++++++--- ...taAcquisitionProjectShadowCopyService.java | 13 -- .../service/ShadowCopyQueueItemService.java | 71 ++++++++--- .../service/ShadowCopyingEndedEvent.java | 6 +- .../service/ShadowCopyingStartedEvent.java | 13 +- ...cquisitionProjectShadowCopyDataSource.java | 27 +++- .../QuestionImageShadowCopyService.java | 15 --- .../service/QuestionShadowCopyService.java | 28 ----- .../helper/QuestionShadowCopyDataSource.java | 21 ++++ .../StudyAttachmentShadowCopyService.java | 15 --- .../service/StudyShadowCopyService.java | 28 ----- .../helper/StudyShadowCopyDataSource.java | 21 ++++ .../SurveyAttachmentShadowCopyService.java | 15 --- ...veyResponseRateImageShadowCopyService.java | 15 --- .../service/SurveyShadowCopyService.java | 28 ----- .../helper/SurveyShadowCopyDataSource.java | 21 ++++ .../service/VariableShadowCopyService.java | 28 ----- .../helper/VariableShadowCopyDataSource.java | 21 ++++ .../templates/dara/register.xml.tmpl | 8 +- .../rest/StudyResourceControllerTest.java | 17 +++ 50 files changed, 856 insertions(+), 376 deletions(-) create mode 100644 docs/source/javadoc/eu/dzhw/fdz/metadatamanagement/projectmanagement/domain/ShadowCopyQueueItem-Action.rst create mode 100644 docs/source/javadoc/eu/dzhw/fdz/metadatamanagement/projectmanagement/domain/ShadowHidingNotAllowedException.rst create mode 100644 docs/source/javadoc/eu/dzhw/fdz/metadatamanagement/projectmanagement/domain/ShadowUnhidingNotAllowedException.rst create mode 100644 src/main/java/eu/dzhw/fdz/metadatamanagement/common/domain/validation/ValidHiddenShadow.java create mode 100644 src/main/java/eu/dzhw/fdz/metadatamanagement/common/domain/validation/ValidHiddenShadowValidator.java create mode 100644 src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/domain/ShadowHidingNotAllowedException.java create mode 100644 src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/domain/ShadowUnhidingNotAllowedException.java create mode 100644 src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/rest/DataAcquisitionProjectShadowsResource.java diff --git a/docs/source/javadoc/eu/dzhw/fdz/metadatamanagement/common/domain/AbstractShadowableRdcDomainObject.rst b/docs/source/javadoc/eu/dzhw/fdz/metadatamanagement/common/domain/AbstractShadowableRdcDomainObject.rst index 892962ea47..dbd180c40a 100644 --- a/docs/source/javadoc/eu/dzhw/fdz/metadatamanagement/common/domain/AbstractShadowableRdcDomainObject.rst +++ b/docs/source/javadoc/eu/dzhw/fdz/metadatamanagement/common/domain/AbstractShadowableRdcDomainObject.rst @@ -2,6 +2,8 @@ .. java:import:: org.springframework.data.mongodb.core.index Indexed +.. java:import:: eu.dzhw.fdz.metadatamanagement.common.domain.validation ValidHiddenShadow + .. java:import:: lombok AccessLevel .. java:import:: lombok Data @@ -16,12 +18,20 @@ AbstractShadowableRdcDomainObject .. java:package:: eu.dzhw.fdz.metadatamanagement.common.domain :noindex: -.. java:type:: @Data @EqualsAndHashCode public abstract class AbstractShadowableRdcDomainObject extends AbstractRdcDomainObject +.. java:type:: @Data @EqualsAndHashCode @ValidHiddenShadow public abstract class AbstractShadowableRdcDomainObject extends AbstractRdcDomainObject - Base class for all rdc domain objects which can exist as multiple versions. + Base class for all rdc domain objects which can exist as multiple versions (shadows). Fields ------ +hidden +^^^^^^ + +.. java:field:: private boolean hidden + :outertype: AbstractShadowableRdcDomainObject + + True if and only if the shadow copy must not be available for the public user. Only shadow copies which have a successor may be hidden. + serialVersionUID ^^^^^^^^^^^^^^^^ diff --git a/docs/source/javadoc/eu/dzhw/fdz/metadatamanagement/common/domain/Task-TaskType.rst b/docs/source/javadoc/eu/dzhw/fdz/metadatamanagement/common/domain/Task-TaskType.rst index 7b17940988..c347b4df9f 100644 --- a/docs/source/javadoc/eu/dzhw/fdz/metadatamanagement/common/domain/Task-TaskType.rst +++ b/docs/source/javadoc/eu/dzhw/fdz/metadatamanagement/common/domain/Task-TaskType.rst @@ -37,9 +37,3 @@ DATA_SET_REPORT .. java:field:: public static final Task.TaskType DATA_SET_REPORT :outertype: Task.TaskType -PROJECT_RELEASE -^^^^^^^^^^^^^^^ - -.. java:field:: public static final Task.TaskType PROJECT_RELEASE - :outertype: Task.TaskType - diff --git a/docs/source/javadoc/eu/dzhw/fdz/metadatamanagement/projectmanagement/domain/ShadowCopyQueueItem-Action.rst b/docs/source/javadoc/eu/dzhw/fdz/metadatamanagement/projectmanagement/domain/ShadowCopyQueueItem-Action.rst new file mode 100644 index 0000000000..569ce8e18d --- /dev/null +++ b/docs/source/javadoc/eu/dzhw/fdz/metadatamanagement/projectmanagement/domain/ShadowCopyQueueItem-Action.rst @@ -0,0 +1,49 @@ +.. java:import:: java.time LocalDateTime + +.. java:import:: javax.validation.constraints NotNull + +.. java:import:: org.springframework.data.annotation Id + +.. java:import:: org.springframework.data.mongodb.core.mapping Document + +.. java:import:: eu.dzhw.fdz.metadatamanagement.common.domain AbstractRdcDomainObject + +.. java:import:: lombok AllArgsConstructor + +.. java:import:: lombok Data + +.. java:import:: lombok EqualsAndHashCode + +.. java:import:: lombok NoArgsConstructor + +ShadowCopyQueueItem.Action +========================== + +.. java:package:: eu.dzhw.fdz.metadatamanagement.projectmanagement.domain + :noindex: + +.. java:type:: public enum Action + :outertype: ShadowCopyQueueItem + + The action which will be performed for the shadows. + +Enum Constants +-------------- +CREATE +^^^^^^ + +.. java:field:: public static final ShadowCopyQueueItem.Action CREATE + :outertype: ShadowCopyQueueItem.Action + +HIDE +^^^^ + +.. java:field:: public static final ShadowCopyQueueItem.Action HIDE + :outertype: ShadowCopyQueueItem.Action + +UNHIDE +^^^^^^ + +.. java:field:: public static final ShadowCopyQueueItem.Action UNHIDE + :outertype: ShadowCopyQueueItem.Action + diff --git a/docs/source/javadoc/eu/dzhw/fdz/metadatamanagement/projectmanagement/domain/ShadowCopyQueueItem.rst b/docs/source/javadoc/eu/dzhw/fdz/metadatamanagement/projectmanagement/domain/ShadowCopyQueueItem.rst index 34e5c97156..54f420a3d0 100644 --- a/docs/source/javadoc/eu/dzhw/fdz/metadatamanagement/projectmanagement/domain/ShadowCopyQueueItem.rst +++ b/docs/source/javadoc/eu/dzhw/fdz/metadatamanagement/projectmanagement/domain/ShadowCopyQueueItem.rst @@ -28,13 +28,21 @@ ShadowCopyQueueItem Fields ------ +action +^^^^^^ + +.. java:field:: @NotNull private Action action + :outertype: ShadowCopyQueueItem + + The action which will be performed for the shadow copies. + dataAcquisitionProjectId ^^^^^^^^^^^^^^^^^^^^^^^^ .. java:field:: @NotNull private String dataAcquisitionProjectId :outertype: ShadowCopyQueueItem - Project id for which a shadow copy should be created. + Project id for which a shadow copy should be created or hidden or unhidden. id ^^ diff --git a/docs/source/javadoc/eu/dzhw/fdz/metadatamanagement/projectmanagement/domain/ShadowHidingNotAllowedException.rst b/docs/source/javadoc/eu/dzhw/fdz/metadatamanagement/projectmanagement/domain/ShadowHidingNotAllowedException.rst new file mode 100644 index 0000000000..2dca651278 --- /dev/null +++ b/docs/source/javadoc/eu/dzhw/fdz/metadatamanagement/projectmanagement/domain/ShadowHidingNotAllowedException.rst @@ -0,0 +1,20 @@ +ShadowHidingNotAllowedException +=============================== + +.. java:package:: eu.dzhw.fdz.metadatamanagement.projectmanagement.domain + :noindex: + +.. java:type:: public class ShadowHidingNotAllowedException extends Exception + + Exception which is thrown when the user tries to hide a master or the most recent shadow copy. + + :author: René Reitmann + +Fields +------ +serialVersionUID +^^^^^^^^^^^^^^^^ + +.. java:field:: private static final long serialVersionUID + :outertype: ShadowHidingNotAllowedException + diff --git a/docs/source/javadoc/eu/dzhw/fdz/metadatamanagement/projectmanagement/domain/ShadowUnhidingNotAllowedException.rst b/docs/source/javadoc/eu/dzhw/fdz/metadatamanagement/projectmanagement/domain/ShadowUnhidingNotAllowedException.rst new file mode 100644 index 0000000000..cb72296592 --- /dev/null +++ b/docs/source/javadoc/eu/dzhw/fdz/metadatamanagement/projectmanagement/domain/ShadowUnhidingNotAllowedException.rst @@ -0,0 +1,20 @@ +ShadowUnhidingNotAllowedException +================================= + +.. java:package:: eu.dzhw.fdz.metadatamanagement.projectmanagement.domain + :noindex: + +.. java:type:: public class ShadowUnhidingNotAllowedException extends Exception + + Exception which is thrown when the user tries to unhide shadows which are already unhidden. + + :author: René Reitmann + +Fields +------ +serialVersionUID +^^^^^^^^^^^^^^^^ + +.. java:field:: private static final long serialVersionUID + :outertype: ShadowUnhidingNotAllowedException + diff --git a/docs/source/javadoc/eu/dzhw/fdz/metadatamanagement/projectmanagement/domain/package-index.rst b/docs/source/javadoc/eu/dzhw/fdz/metadatamanagement/projectmanagement/domain/package-index.rst index 0bf84db6f9..91d4907f7f 100644 --- a/docs/source/javadoc/eu/dzhw/fdz/metadatamanagement/projectmanagement/domain/package-index.rst +++ b/docs/source/javadoc/eu/dzhw/fdz/metadatamanagement/projectmanagement/domain/package-index.rst @@ -17,5 +17,8 @@ Domain objects describing \ :java:ref:`eu.dzhw.fdz.metadatamanagement.projectman Release Requirements ShadowCopyQueueItem + ShadowCopyQueueItem-Action ShadowCopyReleaseToDaraNotAllowed + ShadowHidingNotAllowedException + ShadowUnhidingNotAllowedException diff --git a/src/main/java/eu/dzhw/fdz/metadatamanagement/common/domain/AbstractShadowableRdcDomainObject.java b/src/main/java/eu/dzhw/fdz/metadatamanagement/common/domain/AbstractShadowableRdcDomainObject.java index 7f5ab864bf..fba265ac4b 100644 --- a/src/main/java/eu/dzhw/fdz/metadatamanagement/common/domain/AbstractShadowableRdcDomainObject.java +++ b/src/main/java/eu/dzhw/fdz/metadatamanagement/common/domain/AbstractShadowableRdcDomainObject.java @@ -4,16 +4,18 @@ import org.springframework.data.mongodb.core.index.Indexed; +import eu.dzhw.fdz.metadatamanagement.common.domain.validation.ValidHiddenShadow; import lombok.AccessLevel; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.Setter; /** - * Base class for all rdc domain objects which can exist as multiple versions. + * Base class for all rdc domain objects which can exist as multiple versions (shadows). */ @Data @EqualsAndHashCode(callSuper = false) +@ValidHiddenShadow public abstract class AbstractShadowableRdcDomainObject extends AbstractRdcDomainObject { private static final long serialVersionUID = 8006229461938445620L; @@ -30,9 +32,16 @@ public abstract class AbstractShadowableRdcDomainObject extends AbstractRdcDomai @Indexed private boolean shadow; + /** + * True if and only if the shadow copy must not be available for the public user. + * Only shadow copies which have a successor may be hidden. + */ + private boolean hidden = false; + /** * Set the master id for the document. This will modify it's * {@link AbstractShadowableRdcDomainObject#shadow} field as well. + * * @param masterId Master id */ public final void setMasterId(String masterId) { @@ -43,6 +52,7 @@ public final void setMasterId(String masterId) { /** * Set the id for the document. This will modify it's * {@link AbstractShadowableRdcDomainObject#shadow} field as well. + * * @param id Document id */ public final void setId(String id) { @@ -52,12 +62,14 @@ public final void setId(String id) { /** * Set masterId on implementations of {@link AbstractShadowableRdcDomainObject}. + * * @param masterId Master Id */ protected abstract void setMasterIdInternal(String masterId); /** * Set id on implementation of {@link AbstractShadowableRdcDomainObject}. + * * @param id Id */ protected abstract void setIdInternal(String id); diff --git a/src/main/java/eu/dzhw/fdz/metadatamanagement/common/domain/Task.java b/src/main/java/eu/dzhw/fdz/metadatamanagement/common/domain/Task.java index 446473d6fc..81d4687330 100644 --- a/src/main/java/eu/dzhw/fdz/metadatamanagement/common/domain/Task.java +++ b/src/main/java/eu/dzhw/fdz/metadatamanagement/common/domain/Task.java @@ -70,7 +70,6 @@ public enum TaskState { * */ public enum TaskType { - DATA_SET_REPORT, - PROJECT_RELEASE + DATA_SET_REPORT } } diff --git a/src/main/java/eu/dzhw/fdz/metadatamanagement/common/domain/validation/ValidHiddenShadow.java b/src/main/java/eu/dzhw/fdz/metadatamanagement/common/domain/validation/ValidHiddenShadow.java new file mode 100644 index 0000000000..dab9141b35 --- /dev/null +++ b/src/main/java/eu/dzhw/fdz/metadatamanagement/common/domain/validation/ValidHiddenShadow.java @@ -0,0 +1,38 @@ +package eu.dzhw.fdz.metadatamanagement.common.domain.validation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import javax.validation.Constraint; +import javax.validation.Payload; + +import eu.dzhw.fdz.metadatamanagement.common.domain.AbstractShadowableRdcDomainObject; + +/** + * Validates that {@link AbstractShadowableRdcDomainObject} {@code hidden} is true if and only if + * the domain object is a shadow and has a successor. + */ +@Documented +@Constraint(validatedBy = ValidHiddenShadowValidator.class) +@Target({ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +public @interface ValidHiddenShadow { + + /** + * Defines the default error message. + */ + String message() default "{common.domain.validation.error.invalid-hidden-shadow}"; + + /** + * Groups parameter. + */ + Class[] groups() default {}; + + /** + * Payload parameter. + */ + Class[] payload() default {}; +} diff --git a/src/main/java/eu/dzhw/fdz/metadatamanagement/common/domain/validation/ValidHiddenShadowValidator.java b/src/main/java/eu/dzhw/fdz/metadatamanagement/common/domain/validation/ValidHiddenShadowValidator.java new file mode 100644 index 0000000000..293177a357 --- /dev/null +++ b/src/main/java/eu/dzhw/fdz/metadatamanagement/common/domain/validation/ValidHiddenShadowValidator.java @@ -0,0 +1,31 @@ +package eu.dzhw.fdz.metadatamanagement.common.domain.validation; + +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; + +import org.springframework.util.StringUtils; + +import eu.dzhw.fdz.metadatamanagement.common.domain.AbstractShadowableRdcDomainObject; + +/** + * Default validator implementation for {@link ValidHiddenShadow} validation. + */ +public class ValidHiddenShadowValidator + implements ConstraintValidator { + + @Override + public boolean isValid(AbstractShadowableRdcDomainObject abstractShadowableRdcDomainObject, + ConstraintValidatorContext constraintValidatorContext) { + + if (!abstractShadowableRdcDomainObject.isHidden()) { + return true; + } + + if (abstractShadowableRdcDomainObject.isShadow() + && StringUtils.hasText(abstractShadowableRdcDomainObject.getSuccessorId())) { + return true; + } + + return false; + } +} diff --git a/src/main/java/eu/dzhw/fdz/metadatamanagement/common/rest/GenericDomainObjectResourceController.java b/src/main/java/eu/dzhw/fdz/metadatamanagement/common/rest/GenericDomainObjectResourceController.java index 6a63b24d7c..f30bc4b91f 100644 --- a/src/main/java/eu/dzhw/fdz/metadatamanagement/common/rest/GenericDomainObjectResourceController.java +++ b/src/main/java/eu/dzhw/fdz/metadatamanagement/common/rest/GenericDomainObjectResourceController.java @@ -30,7 +30,7 @@ public abstract class GenericDomainObjectResourceController > { private final CrudService crudService; - + private final UserInformationProvider userInformationProvider; /** @@ -53,6 +53,10 @@ public ResponseEntity getDomainObject(String id) { return ResponseEntity.notFound().build(); } else { T domainObject = optional.get(); + if (AbstractShadowableRdcDomainObject.class.isAssignableFrom(domainObject.getClass()) + && ((AbstractShadowableRdcDomainObject) domainObject).isHidden()) { + return ResponseEntity.notFound().build(); + } return ResponseEntity.ok() .cacheControl(CacheControl.maxAge(0, TimeUnit.DAYS).mustRevalidate().cachePublic()) .eTag(domainObject.getVersion().toString()).lastModified(domainObject diff --git a/src/main/java/eu/dzhw/fdz/metadatamanagement/common/service/AbstractAttachmentShadowCopyDataSource.java b/src/main/java/eu/dzhw/fdz/metadatamanagement/common/service/AbstractAttachmentShadowCopyDataSource.java index 4d28636cbb..5584d79c40 100644 --- a/src/main/java/eu/dzhw/fdz/metadatamanagement/common/service/AbstractAttachmentShadowCopyDataSource.java +++ b/src/main/java/eu/dzhw/fdz/metadatamanagement/common/service/AbstractAttachmentShadowCopyDataSource.java @@ -166,6 +166,31 @@ public void deleteExistingShadowCopies(String projectId, String version) { @Override public void updateElasticsearch(String dataAcquisitionProjectId, String releaseVersion, String previousVersion) { - throw new IllegalAccessError("Attachment indexing has not yet been implemented!"); + // there is currently no elasticsearch index for attachments + } + + @Override + public void hideExistingShadowCopies(String projectId, String version) { + setHiddenState(projectId, version, true); + } + + @Override + public void unhideExistingShadowCopies(String projectId, String version) { + setHiddenState(projectId, version, false); + } + + private void setHiddenState(String projectId, String version, boolean hidden) { + String shadowId = projectId + "-" + version; + Query query = + new Query(GridFsCriteria.whereMetaData("dataAcquisitionProjectId").is(shadowId) + .andOperator(GridFsCriteria.whereFilename().regex(getMasterFileNamePattern()), + GridFsCriteria.whereMetaData("shadow").is(true))); + + try (Stream attachments = convertIterableToStream(gridFsOperations.find(query))) { + attachments.forEach(attachment -> { + attachment.setHidden(hidden); + updatePredecessor(attachment); + }); + } } } diff --git a/src/main/java/eu/dzhw/fdz/metadatamanagement/common/service/GenericShadowableDomainObjectCrudHelper.java b/src/main/java/eu/dzhw/fdz/metadatamanagement/common/service/GenericShadowableDomainObjectCrudHelper.java index 47296ad626..ddb934831b 100644 --- a/src/main/java/eu/dzhw/fdz/metadatamanagement/common/service/GenericShadowableDomainObjectCrudHelper.java +++ b/src/main/java/eu/dzhw/fdz/metadatamanagement/common/service/GenericShadowableDomainObjectCrudHelper.java @@ -5,9 +5,14 @@ import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.search.builder.SearchSourceBuilder; import org.springframework.context.ApplicationEventPublisher; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; + +import com.querydsl.core.types.Predicate; import eu.dzhw.fdz.metadatamanagement.common.domain.AbstractRdcDomainObject; import eu.dzhw.fdz.metadatamanagement.common.domain.AbstractShadowableRdcDomainObject; +import eu.dzhw.fdz.metadatamanagement.common.domain.QAbstractShadowableRdcDomainObject; import eu.dzhw.fdz.metadatamanagement.common.domain.ShadowCopyCreateNotAllowedException; import eu.dzhw.fdz.metadatamanagement.common.domain.ShadowCopyDeleteNotAllowedException; import eu.dzhw.fdz.metadatamanagement.common.domain.ShadowCopySaveNotAllowedException; @@ -22,16 +27,19 @@ /** * CRUD Service Helper for {@link AbstractShadowableRdcDomainObject}. - * + * * @param The {@link BaseRepository} managing the data access. * @param The {@link AbstractShadowableRdcDomainObject}. - * + * * @author René Reitmann */ public class GenericShadowableDomainObjectCrudHelper > extends GenericDomainObjectCrudHelper { + private static final QAbstractShadowableRdcDomainObject shadowQuery = + QAbstractShadowableRdcDomainObject.abstractShadowableRdcDomainObject; + private UserInformationProvider userInformationProvider; /** @@ -50,7 +58,7 @@ public GenericShadowableDomainObjectCrudHelper(S repository, /** * Create the given master {@link AbstractShadowableRdcDomainObject}. Updates elasticsearch as * well. - * + * * @param domainObject The master {@link AbstractShadowableRdcDomainObject} to be created. * @return The created master {@link AbstractShadowableRdcDomainObject}. */ @@ -64,7 +72,7 @@ public T createMaster(T domainObject) { /** * Save (update or create) the given master {@link AbstractShadowableRdcDomainObject}. Updates * elasticsearch as well. - * + * * @param domainObject The master {@link AbstractShadowableRdcDomainObject} to be saved. * @return The saved master {@link AbstractShadowableRdcDomainObject}. */ @@ -78,7 +86,7 @@ public T saveMaster(T domainObject) { /** * Delete the given master {@link AbstractShadowableRdcDomainObject}. Updates elasticsearch as * well. - * + * * @param domainObject The master {@link AbstractShadowableRdcDomainObject} to be deleted. */ public void deleteMaster(T domainObject) { @@ -91,7 +99,7 @@ public void deleteMaster(T domainObject) { /** * Create the given shadow {@link AbstractShadowableRdcDomainObject}. Does not do any * elasticsearch updates at all. Cause the entire shadow project needs to be reindexed anyway. - * + * * @param domainObject The shadow {@link AbstractShadowableRdcDomainObject} to be created. * @return The created shadow {@link AbstractShadowableRdcDomainObject}. */ @@ -104,8 +112,8 @@ public T createShadow(T domainObject) { /** * Save (update or create) the given shadow {@link AbstractShadowableRdcDomainObject}. Does not do - * any elasticsearch updates at all. Cause the entire shadow project needs to be reindex anyway. - * + * any elasticsearch updates at all. Cause the entire shadow project needs to be reindexed anyway. + * * @param domainObject The shadow {@link AbstractShadowableRdcDomainObject} to be saved. * @return The saved shadow {@link AbstractShadowableRdcDomainObject}. */ @@ -120,7 +128,7 @@ public T saveShadow(T domainObject) { * Delete the given shadow {@link AbstractShadowableRdcDomainObject}. Updates elasticsearch as * well. But does not throw any events cause the request scoped * {@link DomainObjectChangesProvider} do not work during shadow copying. - * + * * @param domainObject The master {@link AbstractShadowableRdcDomainObject} to be deleted. */ public void deleteShadow(T domainObject) { @@ -157,7 +165,7 @@ public void delete(T domainObject) { /** * Find the {@link SearchDocumentInterface} which corresponds to the * {@link AbstractRdcDomainObject}. Public users (anonymous users) only get the latest shadow. - * + * * @param id The id of the domain object. * @return An optional domain object. */ @@ -166,21 +174,40 @@ public Optional readSearchDocument(String id) { if (elasticsearchType == null) { return Optional.empty(); } - if (id.matches("^.*-\\d+.\\d+.\\d+$")) { - // explicit get by id containing version - return super.readSearchDocument(id); - } if (!userInformationProvider.isUserAnonymous()) { return super.readSearchDocument(id); + } else { + Optional searchDocument = null; + if (id.matches("^.*-\\d+.\\d+.\\d+$")) { + // explicit get by id containing version + searchDocument = super.readSearchDocument(id); + } else { + SearchSourceBuilder builder = new SearchSourceBuilder(); + builder.fetchSource(null, + ExcludeFieldsHelper.getFieldsToExcludeOnDeserialization(searchDocumentClass)); + builder.query(QueryBuilders.constantScoreQuery(QueryBuilders.boolQuery() + .must(QueryBuilders.termQuery("shadow", true)) + .must(QueryBuilders.termQuery("masterId", id)) + .mustNot(QueryBuilders.existsQuery("successorId")))).size(1); + Search search = + new Search.Builder(builder.toString()).addIndex(elasticsearchType.name()).build(); + searchDocument = super.executeSearch(search); + } + return searchDocument; } - SearchSourceBuilder builder = new SearchSourceBuilder(); - builder.fetchSource(null, - ExcludeFieldsHelper.getFieldsToExcludeOnDeserialization(searchDocumentClass)); - builder.query(QueryBuilders.constantScoreQuery(QueryBuilders.boolQuery() - .must(QueryBuilders.termQuery("shadow", true)).must(QueryBuilders.termQuery("masterId", id)) - .mustNot(QueryBuilders.existsQuery("successorId")))).size(1); - Search search = - new Search.Builder(builder.toString()).addIndex(elasticsearchType.name()).build(); - return super.executeSearch(search); + } + + /** + * Find all shadows for the given masterId. + * @param masterId The id of the master. + * @param pageable used for paging and sorting the results + * @return A page containing all shadows. Can be empty. + */ + public Page findAllShadows(String masterId, Pageable pageable) { + return repository.findAll(isShadowOf(masterId), pageable); + } + + private Predicate isShadowOf(String masterId) { + return shadowQuery.shadow.isTrue().and(shadowQuery.masterId.eq(masterId)); } } diff --git a/src/main/java/eu/dzhw/fdz/metadatamanagement/common/service/ShadowCopyDataSource.java b/src/main/java/eu/dzhw/fdz/metadatamanagement/common/service/ShadowCopyDataSource.java index 9311a4cdbc..43957d267c 100644 --- a/src/main/java/eu/dzhw/fdz/metadatamanagement/common/service/ShadowCopyDataSource.java +++ b/src/main/java/eu/dzhw/fdz/metadatamanagement/common/service/ShadowCopyDataSource.java @@ -76,4 +76,18 @@ public interface ShadowCopyDataSource { public DataSetShadowCopyService(DataSetShadowCopyDataSource dataSetShadowCopyDataSource) { super(dataSetShadowCopyDataSource); } - - /** - * Create shadow copies of current master dataSets on project release. - * - * @param shadowCopyingStartedEvent Emitted by {@link ShadowCopyQueueItemService} - */ - @EventListener - public void onShadowCopyingStarted(ShadowCopyingStartedEvent shadowCopyingStartedEvent) { - super.createShadowCopies(shadowCopyingStartedEvent.getDataAcquisitionProjectId(), - shadowCopyingStartedEvent.getRelease(), - shadowCopyingStartedEvent.getPreviousReleaseVersion()); - } - - /** - * Update elasticsearch (both predecessors and current shadows). - * - * @param shadowCopyingEndedEvent Emitted by {@link ShadowCopyQueueItemService} - */ - @EventListener - public void onShadowCopyingEnded(ShadowCopyingEndedEvent shadowCopyingEndedEvent) { - super.updateElasticsearch(shadowCopyingEndedEvent.getDataAcquisitionProjectId(), - shadowCopyingEndedEvent.getRelease().getVersion(), - shadowCopyingEndedEvent.getPreviousReleaseVersion()); - } } diff --git a/src/main/java/eu/dzhw/fdz/metadatamanagement/datasetmanagement/service/helper/DataSetShadowCopyDataSource.java b/src/main/java/eu/dzhw/fdz/metadatamanagement/datasetmanagement/service/helper/DataSetShadowCopyDataSource.java index eb956f09a0..40467c0438 100644 --- a/src/main/java/eu/dzhw/fdz/metadatamanagement/datasetmanagement/service/helper/DataSetShadowCopyDataSource.java +++ b/src/main/java/eu/dzhw/fdz/metadatamanagement/datasetmanagement/service/helper/DataSetShadowCopyDataSource.java @@ -104,4 +104,25 @@ public void updateElasticsearch(String dataAcquisitionProjectId, String releaseV }, ElasticsearchType.data_sets); } } + + @Override + public void hideExistingShadowCopies(String projectId, String version) { + setHiddenState(projectId, version, true); + } + + private void setHiddenState(String projectId, String version, boolean hidden) { + String shadowId = projectId + "-" + version; + try (Stream dataSets = + dataSetRepository.streamByDataAcquisitionProjectIdAndShadowIsTrue(shadowId)) { + dataSets.forEach(shadow -> { + shadow.setHidden(hidden); + crudHelper.saveShadow(shadow); + }); + } + } + + @Override + public void unhideExistingShadowCopies(String projectId, String version) { + setHiddenState(projectId, version, false); + } } diff --git a/src/main/java/eu/dzhw/fdz/metadatamanagement/instrumentmanagement/service/InstrumentAttachmentShadowCopyService.java b/src/main/java/eu/dzhw/fdz/metadatamanagement/instrumentmanagement/service/InstrumentAttachmentShadowCopyService.java index 655b880187..de62c16564 100644 --- a/src/main/java/eu/dzhw/fdz/metadatamanagement/instrumentmanagement/service/InstrumentAttachmentShadowCopyService.java +++ b/src/main/java/eu/dzhw/fdz/metadatamanagement/instrumentmanagement/service/InstrumentAttachmentShadowCopyService.java @@ -1,13 +1,10 @@ package eu.dzhw.fdz.metadatamanagement.instrumentmanagement.service; -import org.springframework.context.event.EventListener; import org.springframework.stereotype.Service; import eu.dzhw.fdz.metadatamanagement.common.service.ShadowCopyHelper; import eu.dzhw.fdz.metadatamanagement.instrumentmanagement.domain.InstrumentAttachmentMetadata; import eu.dzhw.fdz.metadatamanagement.instrumentmanagement.service.helper.InstrumentAttachmentShadowCopyDataSource; -import eu.dzhw.fdz.metadatamanagement.projectmanagement.service.ShadowCopyQueueItemService; -import eu.dzhw.fdz.metadatamanagement.projectmanagement.service.ShadowCopyingStartedEvent; /** * Service which generates shadow copies of all instrument attachments of a project, when the @@ -22,16 +19,4 @@ public InstrumentAttachmentShadowCopyService( InstrumentAttachmentShadowCopyDataSource shadowCopyDataSource) { super(shadowCopyDataSource); } - - /** - * Create shadow copies of current master instrument attachments on project release. - * - * @param shadowCopyingStartedEvent Emitted by {@link ShadowCopyQueueItemService} - */ - @EventListener - public void onShadowCopyingStarted(ShadowCopyingStartedEvent shadowCopyingStartedEvent) { - super.createShadowCopies(shadowCopyingStartedEvent.getDataAcquisitionProjectId(), - shadowCopyingStartedEvent.getRelease(), - shadowCopyingStartedEvent.getPreviousReleaseVersion()); - } } diff --git a/src/main/java/eu/dzhw/fdz/metadatamanagement/instrumentmanagement/service/InstrumentShadowCopyService.java b/src/main/java/eu/dzhw/fdz/metadatamanagement/instrumentmanagement/service/InstrumentShadowCopyService.java index d12869aa42..d78e5c4bd6 100644 --- a/src/main/java/eu/dzhw/fdz/metadatamanagement/instrumentmanagement/service/InstrumentShadowCopyService.java +++ b/src/main/java/eu/dzhw/fdz/metadatamanagement/instrumentmanagement/service/InstrumentShadowCopyService.java @@ -1,14 +1,10 @@ package eu.dzhw.fdz.metadatamanagement.instrumentmanagement.service; -import org.springframework.context.event.EventListener; import org.springframework.stereotype.Service; import eu.dzhw.fdz.metadatamanagement.common.service.ShadowCopyHelper; import eu.dzhw.fdz.metadatamanagement.instrumentmanagement.domain.Instrument; import eu.dzhw.fdz.metadatamanagement.instrumentmanagement.service.helper.InstrumentShadowCopyDataSource; -import eu.dzhw.fdz.metadatamanagement.projectmanagement.service.ShadowCopyQueueItemService; -import eu.dzhw.fdz.metadatamanagement.projectmanagement.service.ShadowCopyingEndedEvent; -import eu.dzhw.fdz.metadatamanagement.projectmanagement.service.ShadowCopyingStartedEvent; /** * Service which generates shadow copies of all instruments of a project, when the project has been @@ -22,28 +18,4 @@ public InstrumentShadowCopyService( InstrumentShadowCopyDataSource instrumentShadowCopyDataSource) { super(instrumentShadowCopyDataSource); } - - /** - * Create shadow copies of current master instruments on project release. - * - * @param shadowCopyingStartedEvent Emitted by {@link ShadowCopyQueueItemService} - */ - @EventListener - public void onShadowCopyingStarted(ShadowCopyingStartedEvent shadowCopyingStartedEvent) { - super.createShadowCopies(shadowCopyingStartedEvent.getDataAcquisitionProjectId(), - shadowCopyingStartedEvent.getRelease(), - shadowCopyingStartedEvent.getPreviousReleaseVersion()); - } - - /** - * Update elasticsearch (both predecessors and current shadows). - * - * @param shadowCopyingEndedEvent Emitted by {@link ShadowCopyQueueItemService} - */ - @EventListener - public void onShadowCopyingEnded(ShadowCopyingEndedEvent shadowCopyingEndedEvent) { - super.updateElasticsearch(shadowCopyingEndedEvent.getDataAcquisitionProjectId(), - shadowCopyingEndedEvent.getRelease().getVersion(), - shadowCopyingEndedEvent.getPreviousReleaseVersion()); - } } diff --git a/src/main/java/eu/dzhw/fdz/metadatamanagement/instrumentmanagement/service/helper/InstrumentShadowCopyDataSource.java b/src/main/java/eu/dzhw/fdz/metadatamanagement/instrumentmanagement/service/helper/InstrumentShadowCopyDataSource.java index a2469598a5..54651eae7d 100644 --- a/src/main/java/eu/dzhw/fdz/metadatamanagement/instrumentmanagement/service/helper/InstrumentShadowCopyDataSource.java +++ b/src/main/java/eu/dzhw/fdz/metadatamanagement/instrumentmanagement/service/helper/InstrumentShadowCopyDataSource.java @@ -106,4 +106,25 @@ public void updateElasticsearch(String dataAcquisitionProjectId, String releaseV }, ElasticsearchType.instruments); } } + + @Override + public void hideExistingShadowCopies(String projectId, String version) { + setHiddenState(projectId, version, true); + } + + private void setHiddenState(String projectId, String version, boolean hidden) { + String shadowId = projectId + "-" + version; + try (Stream instruments = + instrumentRepository.streamByDataAcquisitionProjectIdAndShadowIsTrue(shadowId)) { + instruments.forEach(shadow -> { + shadow.setHidden(hidden); + crudHelper.saveShadow(shadow); + }); + } + } + + @Override + public void unhideExistingShadowCopies(String projectId, String version) { + setHiddenState(projectId, version, false); + } } diff --git a/src/main/java/eu/dzhw/fdz/metadatamanagement/ordermanagement/rest/OrderResource.java b/src/main/java/eu/dzhw/fdz/metadatamanagement/ordermanagement/rest/OrderResource.java index ac8f71aadc..35d8320b03 100644 --- a/src/main/java/eu/dzhw/fdz/metadatamanagement/ordermanagement/rest/OrderResource.java +++ b/src/main/java/eu/dzhw/fdz/metadatamanagement/ordermanagement/rest/OrderResource.java @@ -144,7 +144,7 @@ private String getDlpUrl(String orderId) { @ExceptionHandler(OrderAlreadyCompletedException.class) @ResponseBody @ResponseStatus(HttpStatus.BAD_REQUEST) - ErrorListDto handleOrderAlreadyCompletedException() { + protected ErrorListDto handleOrderAlreadyCompletedException() { ErrorDto errorDto = new ErrorDto(null, "order-management.error." + "order-already-completed", null, null); ErrorListDto errorListDto = new ErrorListDto(); diff --git a/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/domain/ShadowCopyQueueItem.java b/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/domain/ShadowCopyQueueItem.java index 0f246e0a84..0af1f94434 100644 --- a/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/domain/ShadowCopyQueueItem.java +++ b/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/domain/ShadowCopyQueueItem.java @@ -32,7 +32,7 @@ public class ShadowCopyQueueItem extends AbstractRdcDomainObject { private String id; /** - * Project id for which a shadow copy should be created. + * Project id for which a shadow copy should be created or hidden or unhidden. */ @NotNull private String dataAcquisitionProjectId; @@ -47,4 +47,17 @@ public class ShadowCopyQueueItem extends AbstractRdcDomainObject { * Start time of the copy process. */ private LocalDateTime updateStartedAt; + + /** + * The action which will be performed for the shadow copies. + */ + @NotNull + private Action action; + + /** + * The action which will be performed for the shadows. + */ + public enum Action { + CREATE, HIDE, UNHIDE + } } diff --git a/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/domain/ShadowHidingNotAllowedException.java b/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/domain/ShadowHidingNotAllowedException.java new file mode 100644 index 0000000000..e0a8ffc0d8 --- /dev/null +++ b/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/domain/ShadowHidingNotAllowedException.java @@ -0,0 +1,14 @@ +package eu.dzhw.fdz.metadatamanagement.projectmanagement.domain; + +/** + * Exception which is thrown when the user tries to hide a master or the most recent shadow copy. + * + * @author René Reitmann + */ +public class ShadowHidingNotAllowedException extends Exception { + private static final long serialVersionUID = -7949019887169025105L; + + public ShadowHidingNotAllowedException(String message) { + super(message); + } +} diff --git a/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/domain/ShadowUnhidingNotAllowedException.java b/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/domain/ShadowUnhidingNotAllowedException.java new file mode 100644 index 0000000000..62f6f28292 --- /dev/null +++ b/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/domain/ShadowUnhidingNotAllowedException.java @@ -0,0 +1,14 @@ +package eu.dzhw.fdz.metadatamanagement.projectmanagement.domain; + +/** + * Exception which is thrown when the user tries to unhide shadows which are already unhidden. + * + * @author René Reitmann + */ +public class ShadowUnhidingNotAllowedException extends Exception { + private static final long serialVersionUID = 6282804107553767675L; + + public ShadowUnhidingNotAllowedException(String message) { + super(message); + } +} diff --git a/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/rest/DaraReleaseResource.java b/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/rest/DaraReleaseResource.java index 862a5b818a..69b2acd2c0 100644 --- a/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/rest/DaraReleaseResource.java +++ b/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/rest/DaraReleaseResource.java @@ -60,7 +60,7 @@ public ResponseEntity release(@PathVariable String id, @ExceptionHandler(ShadowCopyReleaseToDaraNotAllowed.class) @ResponseBody @ResponseStatus(HttpStatus.BAD_REQUEST) - ErrorListDto handleShadowCopyReleaseToDaraNotAllowed() { + protected ErrorListDto handleShadowCopyReleaseToDaraNotAllowed() { ErrorDto errorDto = new ErrorDto(null, "project-management.error." + "shadow-copy-release-to-dara-not-allowed", null, null); ErrorListDto errorListDto = new ErrorListDto(); diff --git a/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/rest/DataAcquisitionProjectShadowsResource.java b/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/rest/DataAcquisitionProjectShadowsResource.java new file mode 100644 index 0000000000..7914af14f3 --- /dev/null +++ b/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/rest/DataAcquisitionProjectShadowsResource.java @@ -0,0 +1,119 @@ +package eu.dzhw.fdz.metadatamanagement.projectmanagement.rest; + +import java.util.Optional; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.http.CacheControl; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; + +import eu.dzhw.fdz.metadatamanagement.common.rest.errors.ErrorDto; +import eu.dzhw.fdz.metadatamanagement.common.rest.errors.ErrorListDto; +import eu.dzhw.fdz.metadatamanagement.projectmanagement.domain.DataAcquisitionProject; +import eu.dzhw.fdz.metadatamanagement.projectmanagement.domain.ShadowHidingNotAllowedException; +import eu.dzhw.fdz.metadatamanagement.projectmanagement.domain.ShadowUnhidingNotAllowedException; +import eu.dzhw.fdz.metadatamanagement.projectmanagement.service.DataAcquisitionProjectManagementService; +import lombok.RequiredArgsConstructor; + +/** + * REST resource for getting all shadow copies of a {@link DataAcquisitionProject}. + * + * @author René Reitmann + */ +@RestController +@RequestMapping("/api") +@RequiredArgsConstructor +public class DataAcquisitionProjectShadowsResource { + + private final DataAcquisitionProjectManagementService dataAcquisitionProjectManagementService; + + /** + * Get the previous 5 versions of the data acquisition project. + * + * @param id The id of the project + * @param pageable contains size and limit + * + * @return A list of previous data acquisition project versions + */ + @GetMapping("/data-acquisition-projects/{id}/shadows") + public ResponseEntity findShadows(@PathVariable String id, Pageable pageable) { + Page page = + dataAcquisitionProjectManagementService.findAllShadows(id, pageable); + + return ResponseEntity.ok().cacheControl(CacheControl.noStore()).body(page); + } + + /** + * Hide the shadow copies of the given project with the given version. + * + * @param id The id of the project + * @param version the version of the shadows to hide + * + * @return ACCEPTED if the hiding task has been started + * @throws ShadowHidingNotAllowedException Thrown if hiding the project version is not allowed. + */ + @PostMapping("/data-acquisition-projects/{id}/shadows/{version}/hidden") + public ResponseEntity hideShadows(@PathVariable String id, @PathVariable String version) + throws ShadowHidingNotAllowedException { + String shadowId = id + "-" + version; + Optional optional = + dataAcquisitionProjectManagementService.read(shadowId); + if (optional.isPresent()) { + dataAcquisitionProjectManagementService.hideShadows(optional.get()); + } else { + return ResponseEntity.notFound().build(); + } + + return ResponseEntity.accepted().build(); + } + + /** + * Unhide the shadow copies of the given project with the given version. + * + * @param id The id of the project + * @param version the version of the shadows to hide + * + * @return ACCEPTED if the hiding task has been started + * @throws ShadowUnhidingNotAllowedException Thrown if the given project version is already + * unhidden + */ + @DeleteMapping("/data-acquisition-projects/{id}/shadows/{version}/hidden") + public ResponseEntity unhideShadows(@PathVariable String id, @PathVariable String version) + throws ShadowUnhidingNotAllowedException { + String shadowId = id + "-" + version; + Optional optional = + dataAcquisitionProjectManagementService.read(shadowId); + if (optional.isPresent()) { + dataAcquisitionProjectManagementService.unhideShadows(optional.get()); + } else { + return ResponseEntity.notFound().build(); + } + + return ResponseEntity.accepted().build(); + } + + /** + * Handle {@link ShadowHidingNotAllowedException} {@link ShadowUnhidingNotAllowedException} or + * thrown by attempts to hide or unhide a project. + */ + @ExceptionHandler({ShadowHidingNotAllowedException.class, + ShadowUnhidingNotAllowedException.class}) + @ResponseBody + @ResponseStatus(HttpStatus.BAD_REQUEST) + protected ErrorListDto handleShadowHidingExceptions(Exception ex) { + ErrorDto errorDto = new ErrorDto(null, ex.getMessage(), null, null); + ErrorListDto errorListDto = new ErrorListDto(); + errorListDto.add(errorDto); + return errorListDto; + } +} diff --git a/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/service/DaraService.java b/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/service/DaraService.java index c453c12eec..e9d0cc5294 100644 --- a/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/service/DaraService.java +++ b/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/service/DaraService.java @@ -257,35 +257,34 @@ private HttpStatus postToDaraImportXml(String filledTemplate) { private Map getDataForTemplate(DataAcquisitionProject project) { Map dataForTemplate = new HashMap<>(); - String projectId = project.getId(); // Get Project Information dataForTemplate.put("dataAcquisitionProject", project); // Get Study Information - Study study = this.studyRepository.findOneByDataAcquisitionProjectId(projectId); + Study study = this.studyRepository.findOneByDataAcquisitionProjectId(project.getId()); dataForTemplate.put("study", study); String availabilityControlled = AVAILABILITY_CONTROLLED_NOT_AVAILABLE; - if (study.getDataAvailability().equals(DataAvailabilities.AVAILABLE)) { + if (!study.isHidden() && study.getDataAvailability().equals(DataAvailabilities.AVAILABLE)) { availabilityControlled = AVAILABILITY_CONTROLLED_DELIVERY; } - + Release release = project.getRelease(); if (release == null) { - release = dataAcquisitionProjectVersionsService.findLastRelease(project.getId()); + release = dataAcquisitionProjectVersionsService.findLastRelease(project.getMasterId()); } String doi = doiBuilder.buildStudyDoi(study, release); dataForTemplate.put("doi", doi); - String previousDoi = doiBuilder.buildStudyDoi(study, dataAcquisitionProjectVersionsService - .findPreviousRelease(project.getId(), release)); + String previousDoi = doiBuilder.buildStudyDoi(study, + dataAcquisitionProjectVersionsService.findPreviousRelease(project.getMasterId(), release)); dataForTemplate.put("previousDoi", previousDoi); // Get Surveys Information List surveys = - this.surveyRepository.findByDataAcquisitionProjectIdOrderByNumber(projectId); + this.surveyRepository.findByDataAcquisitionProjectIdOrderByNumber(project.getId()); dataForTemplate.put("surveys", surveys); dataForTemplate.put("surveyUnits", concatenateUnits(surveys)); @@ -295,7 +294,7 @@ private Map getDataForTemplate(DataAcquisitionProject project) { dataForTemplate.put("surveySamplesMap", concatenateSurveySamplesByLanguage(surveys)); // Get Datasets Information - List dataSets = this.dataSetRepository.findByDataAcquisitionProjectId(projectId); + List dataSets = this.dataSetRepository.findByDataAcquisitionProjectId(project.getId()); dataForTemplate.put("dataSets", dataSets); HashMap dataSetNumberOfVariablesMap = new HashMap<>(); @@ -307,7 +306,7 @@ private Map getDataForTemplate(DataAcquisitionProject project) { // Get Related Publications List relatedPublications = - this.relatedPublicationRepository.findByStudyIdsContaining(study.getId()); + this.relatedPublicationRepository.findByStudyIdsContaining(study.getMasterId()); dataForTemplate.put("relatedPublications", relatedPublications); // Add Date @@ -332,8 +331,7 @@ private Map getDataForTemplate(DataAcquisitionProject project) { private String concatenateUnits(List surveys) { return String.join("; ", surveys.stream() - .map(survey -> survey.getPopulation().getUnit().getDe()) - .collect(Collectors.toSet())); + .map(survey -> survey.getPopulation().getUnit().getDe()).collect(Collectors.toSet())); } private Map> computeSurveyToCollectionModesMap(List surveys) { @@ -372,17 +370,15 @@ private Map> computeSurveyToCollectionModesMap(List private Set deduplicateGeographicCoverages(List surveys) { return surveys.stream() - .flatMap(survey -> survey.getPopulation().getGeographicCoverages() - .stream()).collect(Collectors.toSet()); + .flatMap(survey -> survey.getPopulation().getGeographicCoverages().stream()) + .collect(Collectors.toSet()); } private Map concatenateSurveySamplesByLanguage(List surveys) { - Set samples = surveys.stream() - .map(Survey::getSample) - .collect(Collectors.toSet()); + Set samples = surveys.stream().map(Survey::getSample).collect(Collectors.toSet()); - Map samplesGroupedByLanguage = new HashMap<>(); + Map samplesGroupedByLanguage = new HashMap<>(); String german = samples.stream().map(I18nString::getDe).collect(Collectors.joining("; ")); samplesGroupedByLanguage.put("de", german); String english = samples.stream().map(I18nString::getEn).collect(Collectors.joining("; ")); diff --git a/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/service/DataAcquisitionProjectManagementService.java b/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/service/DataAcquisitionProjectManagementService.java index 14996312be..5aa5a047ef 100644 --- a/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/service/DataAcquisitionProjectManagementService.java +++ b/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/service/DataAcquisitionProjectManagementService.java @@ -1,5 +1,6 @@ package eu.dzhw.fdz.metadatamanagement.projectmanagement.service; +import java.io.IOException; import java.time.LocalDateTime; import java.util.Collections; import java.util.HashSet; @@ -9,9 +10,12 @@ import java.util.stream.Collectors; import org.springframework.context.event.EventListener; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.data.rest.core.annotation.RepositoryEventHandler; import org.springframework.security.access.annotation.Secured; import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; import com.github.zafarkhaja.semver.Version; @@ -21,6 +25,8 @@ import eu.dzhw.fdz.metadatamanagement.projectmanagement.domain.AssigneeGroup; import eu.dzhw.fdz.metadatamanagement.projectmanagement.domain.DataAcquisitionProject; import eu.dzhw.fdz.metadatamanagement.projectmanagement.domain.Release; +import eu.dzhw.fdz.metadatamanagement.projectmanagement.domain.ShadowHidingNotAllowedException; +import eu.dzhw.fdz.metadatamanagement.projectmanagement.domain.ShadowUnhidingNotAllowedException; import eu.dzhw.fdz.metadatamanagement.projectmanagement.repository.DataAcquisitionProjectRepository; import eu.dzhw.fdz.metadatamanagement.projectmanagement.service.helper.DataAcquisitionProjectCrudHelper; import eu.dzhw.fdz.metadatamanagement.usermanagement.domain.Authority; @@ -29,6 +35,7 @@ import eu.dzhw.fdz.metadatamanagement.usermanagement.security.AuthoritiesConstants; import eu.dzhw.fdz.metadatamanagement.usermanagement.security.SecurityUtils; import eu.dzhw.fdz.metadatamanagement.usermanagement.security.UserInformationProvider; +import freemarker.template.TemplateException; import lombok.RequiredArgsConstructor; /** @@ -60,6 +67,8 @@ public class DataAcquisitionProjectManagementService private final DataAcquisitionProjectVersionsService projectVersionsService; + private final DaraService daraService; + /** * Searches for {@link DataAcquisitionProject} items for the given id. The result may be limited * if the current user is not an admin or publisher. @@ -252,7 +261,7 @@ public DataAcquisitionProject save(DataAcquisitionProject project) { final String projectId = project.getId(); if (isProjectBeingReleased(oldProject, project)) { - shadowCopyQueueItemService.createShadowCopyTask(projectId, project.getRelease()); + shadowCopyQueueItemService.scheduleShadowCopyCreation(projectId, project.getRelease()); } else { sendPublishersDataProvidersChangedMails(projectId); sendAssigneeGroupChangedMails(project); @@ -276,26 +285,93 @@ public Optional readSearchDocument(String id) { * Notify all {@link AuthoritiesConstants.RELEASE_MANAGER}'s about the new major release. * * @param shadowCopyingEndedEvent Emitted by {@link ShadowCopyQueueItemService}. + * @throws TemplateException thrown if template processing for dara's xml fails + * @throws IOException thrown if IO errors occur during template processing */ @EventListener - public void onShadowCopyingEnded(ShadowCopyingEndedEvent shadowCopyingEndedEvent) { - if (shadowCopyingEndedEvent.isRerelease()) { - // do not send mails for rereleases - return; + public void onShadowCopyingEnded(ShadowCopyingEndedEvent shadowCopyingEndedEvent) + throws IOException, TemplateException { + switch (shadowCopyingEndedEvent.getAction()) { + case CREATE: + if (shadowCopyingEndedEvent.isRerelease()) { + // do not send mails for rereleases + return; + } + Version currentVersion = Version.valueOf(shadowCopyingEndedEvent.getRelease().getVersion()); + Release previousRelease = projectVersionsService.findPreviousRelease( + shadowCopyingEndedEvent.getDataAcquisitionProjectId(), + shadowCopyingEndedEvent.getRelease()); + if (previousRelease == null && currentVersion.getMajorVersion() > 0 + || previousRelease != null && currentVersion.getMajorVersion() > Version + .valueOf(previousRelease.getVersion()).getMajorVersion()) { + // a new major release has been shadow copied + List releaseManagers = userRepository + .findAllByAuthoritiesContaining(new Authority(AuthoritiesConstants.RELEASE_MANAGER)); + mailService.sendMailOnNewMajorProjectRelease(releaseManagers, + shadowCopyingEndedEvent.getDataAcquisitionProjectId(), + shadowCopyingEndedEvent.getRelease()); + } + break; + case HIDE: + case UNHIDE: + daraService + .registerOrUpdateProjectToDara(shadowCopyingEndedEvent.getDataAcquisitionProjectId() + + "-" + shadowCopyingEndedEvent.getRelease().getVersion()); + break; + default: + throw new IllegalArgumentException( + shadowCopyingEndedEvent.getAction() + " has not been implemented yet!"); } - Version currentVersion = Version.valueOf(shadowCopyingEndedEvent.getRelease().getVersion()); - Release previousRelease = projectVersionsService.findPreviousRelease( - shadowCopyingEndedEvent.getDataAcquisitionProjectId(), - shadowCopyingEndedEvent.getRelease()); - if (previousRelease == null && currentVersion.getMajorVersion() > 0 - || previousRelease != null && currentVersion.getMajorVersion() > Version - .valueOf(previousRelease.getVersion()).getMajorVersion()) { - // a new major release has been shadow copied - List releaseManagers = userRepository - .findAllByAuthoritiesContaining(new Authority(AuthoritiesConstants.RELEASE_MANAGER)); - mailService.sendMailOnNewMajorProjectRelease(releaseManagers, - shadowCopyingEndedEvent.getDataAcquisitionProjectId(), - shadowCopyingEndedEvent.getRelease()); + } + + /** + * Load a page containing all shadow copies of the given master. + * + * @param masterId project id of the master + * @param pageable pageable for paging and sorting + * @return all shadows of the given master, may be empty + */ + public Page findAllShadows(String masterId, Pageable pageable) { + return crudHelper.findAllShadows(masterId, pageable); + } + + /** + * Hide the given shadow copy of a project. + * + * @param shadowProject The shadow to be hidden. + * @throws ShadowHidingNotAllowedException thrown if the given project cannot be hidden + */ + @Secured(value = {AuthoritiesConstants.PUBLISHER, AuthoritiesConstants.DATA_PROVIDER, + AuthoritiesConstants.ADMIN}) + public void hideShadows(DataAcquisitionProject shadowProject) + throws ShadowHidingNotAllowedException { + if (!shadowProject.isShadow()) { + throw new ShadowHidingNotAllowedException("Master projects cannot be hidden!"); + } + if (StringUtils.isEmpty(shadowProject.getSuccessorId())) { + throw new ShadowHidingNotAllowedException("Shadows without successor cannot be hidden!"); + } + if (shadowProject.isHidden()) { + throw new ShadowHidingNotAllowedException("Project is already hidden!"); + } + shadowCopyQueueItemService.scheduleShadowCopyHiding(shadowProject.getMasterId(), + shadowProject.getRelease()); + } + + /** + * Unhide the given shadow, thus make it visible for public users. + * + * @param shadowProject The shadow copy of a project. + * @throws ShadowUnhidingNotAllowedException Thrown if the project is already unhidden. + */ + @Secured(value = {AuthoritiesConstants.PUBLISHER, AuthoritiesConstants.DATA_PROVIDER, + AuthoritiesConstants.ADMIN}) + public void unhideShadows(DataAcquisitionProject shadowProject) + throws ShadowUnhidingNotAllowedException { + if (!shadowProject.isHidden()) { + throw new ShadowUnhidingNotAllowedException("Project shadow is already unhidden!"); } + shadowCopyQueueItemService.scheduleShadowCopyUnhiding(shadowProject.getMasterId(), + shadowProject.getRelease()); } } diff --git a/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/service/DataAcquisitionProjectShadowCopyService.java b/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/service/DataAcquisitionProjectShadowCopyService.java index b83af976c6..a321aef521 100644 --- a/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/service/DataAcquisitionProjectShadowCopyService.java +++ b/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/service/DataAcquisitionProjectShadowCopyService.java @@ -1,6 +1,5 @@ package eu.dzhw.fdz.metadatamanagement.projectmanagement.service; -import org.springframework.context.event.EventListener; import org.springframework.stereotype.Service; import eu.dzhw.fdz.metadatamanagement.common.service.ShadowCopyHelper; @@ -20,16 +19,4 @@ public DataAcquisitionProjectShadowCopyService( DataAcquisitionProjectShadowCopyDataSource projectShadowCopyDataSource) { super(projectShadowCopyDataSource); } - - /** - * Create shadow copies of current master project on project release. - * - * @param shadowCopyingStartedEvent Emitted by {@link ShadowCopyQueueItemService} - */ - @EventListener - public void onShadowCopyingStarted(ShadowCopyingStartedEvent shadowCopyingStartedEvent) { - super.createShadowCopies(shadowCopyingStartedEvent.getDataAcquisitionProjectId(), - shadowCopyingStartedEvent.getRelease(), - shadowCopyingStartedEvent.getPreviousReleaseVersion()); - } } diff --git a/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/service/ShadowCopyQueueItemService.java b/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/service/ShadowCopyQueueItemService.java index 3b555c530b..9ac32b4138 100644 --- a/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/service/ShadowCopyQueueItemService.java +++ b/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/service/ShadowCopyQueueItemService.java @@ -17,6 +17,7 @@ import eu.dzhw.fdz.metadatamanagement.projectmanagement.domain.DataAcquisitionProject; import eu.dzhw.fdz.metadatamanagement.projectmanagement.domain.Release; import eu.dzhw.fdz.metadatamanagement.projectmanagement.domain.ShadowCopyQueueItem; +import eu.dzhw.fdz.metadatamanagement.projectmanagement.domain.ShadowCopyQueueItem.Action; import eu.dzhw.fdz.metadatamanagement.projectmanagement.repository.DataAcquisitionProjectRepository; import eu.dzhw.fdz.metadatamanagement.projectmanagement.repository.ShadowCopyQueueItemRepository; import eu.dzhw.fdz.metadatamanagement.usermanagement.security.SecurityUtils; @@ -64,7 +65,12 @@ public ShadowCopyQueueItemService(ApplicationEventPublisher applicationEventPubl * @param dataAcquisitionProjectId Id of project for which a shadow copy should be created * @param release The release object of the project which has been released. */ - public void createShadowCopyTask(String dataAcquisitionProjectId, Release release) { + public void scheduleShadowCopyCreation(String dataAcquisitionProjectId, Release release) { + createShadowCopyQueueItem(dataAcquisitionProjectId, release, Action.CREATE); + } + + private void createShadowCopyQueueItem(String dataAcquisitionProjectId, Release release, + Action action) { ShadowCopyQueueItem queueItem = new ShadowCopyQueueItem(); Optional taskItem = @@ -77,19 +83,40 @@ public void createShadowCopyTask(String dataAcquisitionProjectId, Release releas queueItem.setDataAcquisitionProjectId(dataAcquisitionProjectId); queueItem.setRelease(release); queueItem.setCreatedBy(SecurityUtils.getCurrentUserLogin()); + queueItem.setAction(action); shadowCopyQueueItemRepository.save(queueItem); } + /** + * Create a new shadow copy queue item for hiding the shadow copies of the given version. + * + * @param dataAcquisitionProjectId Id of project for which the shadow copies shall be hidden. + * @param release The release object of the project which has been released. + */ + public void scheduleShadowCopyHiding(String dataAcquisitionProjectId, Release release) { + createShadowCopyQueueItem(dataAcquisitionProjectId, release, Action.HIDE); + } + + /** + * Create a new shadow copy queue item for unhiding the shadow copies of the given version. + * + * @param dataAcquisitionProjectId Id of project for which the shadow copies shall be unhidden. + * @param release The release object of the project which has been released. + */ + public void scheduleShadowCopyUnhiding(String dataAcquisitionProjectId, Release release) { + createShadowCopyQueueItem(dataAcquisitionProjectId, release, Action.UNHIDE); + } + /** * Emits {@link ShadowCopyingStartedEvent} for each entry of the collection at a fixed rate. */ @Scheduled(fixedRate = 1000 * 60, initialDelay = 1000 * 60) - public void createShadowCopies() { + public void executeShadowCopyActions() { LocalDateTime updateStartTime = LocalDateTime.now(); shadowCopyQueueItemRepository.lockAllUnlockedOrExpiredItems(updateStartTime, jvmId); List tasks = shadowCopyQueueItemRepository.findOldestLockedItems(updateStartTime, jvmId); - log.debug("Creating shadow copies for {} queued items.", tasks.size()); + log.debug("Executing shadow copy actions for {} queued items.", tasks.size()); tasks.forEach(task -> { try { setupSecurityContext(task); @@ -99,13 +126,29 @@ public void createShadowCopies() { dataAcquisitionProjectRepository.findById(dataAcquisitionProjectId); if (dataAcquisitionProjectOpt.isPresent()) { DataAcquisitionProject dataAcquisitionProject = dataAcquisitionProjectOpt.get(); - Optional existingShadow = dataAcquisitionProjectRepository - .findById(dataAcquisitionProjectId + "-" + release.getVersion()); - String previousReleaseVersion = - getPreviousReleaseVersion(dataAcquisitionProject, release); - emitShadowCopyingStartedEvent(dataAcquisitionProject, release, previousReleaseVersion); - emitShadowCopyingEndedEvent(dataAcquisitionProject, release, previousReleaseVersion, - existingShadow.isPresent()); + switch (task.getAction()) { + case CREATE: + Optional existingShadow = dataAcquisitionProjectRepository + .findById(dataAcquisitionProjectId + "-" + release.getVersion()); + String previousReleaseVersion = + getPreviousReleaseVersion(dataAcquisitionProject, release); + emitShadowCopyingStartedEvent(dataAcquisitionProject, release, previousReleaseVersion, + task.getAction()); + emitShadowCopyingEndedEvent(dataAcquisitionProject, release, previousReleaseVersion, + existingShadow.isPresent(), task.getAction()); + break; + case HIDE: + case UNHIDE: + emitShadowCopyingStartedEvent(dataAcquisitionProject, release, null, + task.getAction()); + emitShadowCopyingEndedEvent(dataAcquisitionProject, release, null, true, + task.getAction()); + break; + default: + throw new IllegalArgumentException( + task.getAction() + " has not been implemented yet!"); + } + } else { log.warn("A shadow copy task was scheduled for project {}, but it could not be found!", dataAcquisitionProjectId); @@ -119,9 +162,9 @@ public void createShadowCopies() { } private void emitShadowCopyingEndedEvent(DataAcquisitionProject dataAcquisitionProject, - Release release, String previousReleaseVersion, boolean isRerelease) { + Release release, String previousReleaseVersion, boolean isRerelease, Action action) { this.applicationEventPublisher.publishEvent(new ShadowCopyingEndedEvent(this, - dataAcquisitionProject.getId(), release, previousReleaseVersion, isRerelease)); + dataAcquisitionProject.getId(), release, previousReleaseVersion, isRerelease, action)); } private void setupSecurityContext(ShadowCopyQueueItem shadowCopyQueueItem) { @@ -158,8 +201,8 @@ private String getPreviousReleaseVersion(DataAcquisitionProject dataAcquisitionP } private void emitShadowCopyingStartedEvent(DataAcquisitionProject dataAcquisitionProject, - Release release, String previousReleaseVersion) { + Release release, String previousReleaseVersion, Action action) { this.applicationEventPublisher.publishEvent(new ShadowCopyingStartedEvent(this, - dataAcquisitionProject.getId(), release, previousReleaseVersion)); + dataAcquisitionProject.getId(), release, previousReleaseVersion, action)); } } diff --git a/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/service/ShadowCopyingEndedEvent.java b/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/service/ShadowCopyingEndedEvent.java index 1ffc703e8a..c44bd5adaf 100644 --- a/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/service/ShadowCopyingEndedEvent.java +++ b/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/service/ShadowCopyingEndedEvent.java @@ -4,6 +4,7 @@ import eu.dzhw.fdz.metadatamanagement.projectmanagement.domain.DataAcquisitionProject; import eu.dzhw.fdz.metadatamanagement.projectmanagement.domain.Release; +import eu.dzhw.fdz.metadatamanagement.projectmanagement.domain.ShadowCopyQueueItem.Action; import lombok.Getter; /** @@ -22,6 +23,8 @@ public class ShadowCopyingEndedEvent extends ApplicationEvent { private Release release; private boolean isRerelease; + + private Action action; /** * Create a new event instance. @@ -33,11 +36,12 @@ public class ShadowCopyingEndedEvent extends ApplicationEvent { * @param isRerelease true if the project has been released with this version before */ public ShadowCopyingEndedEvent(Object source, String dataAcquisitionProjectId, - Release release, String previousReleaseVersion, boolean isRerelease) { + Release release, String previousReleaseVersion, boolean isRerelease, Action action) { super(source); this.dataAcquisitionProjectId = dataAcquisitionProjectId; this.previousReleaseVersion = previousReleaseVersion; this.release = release; this.isRerelease = isRerelease; + this.action = action; } } diff --git a/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/service/ShadowCopyingStartedEvent.java b/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/service/ShadowCopyingStartedEvent.java index 6fc5cf1599..9213c5047a 100644 --- a/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/service/ShadowCopyingStartedEvent.java +++ b/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/service/ShadowCopyingStartedEvent.java @@ -4,11 +4,12 @@ import eu.dzhw.fdz.metadatamanagement.projectmanagement.domain.DataAcquisitionProject; import eu.dzhw.fdz.metadatamanagement.projectmanagement.domain.Release; +import eu.dzhw.fdz.metadatamanagement.projectmanagement.domain.ShadowCopyQueueItem.Action; import lombok.Getter; /** - * Event emitted if a project release is detected. Contains the release version and projectId of - * {@link DataAcquisitionProject} as a reference. + * Event emitted if a project release is detected or a shadow need to be hidden/unhidden. Contains + * the release version and projectId of {@link DataAcquisitionProject} as a reference. */ @Getter public class ShadowCopyingStartedEvent extends ApplicationEvent { @@ -21,6 +22,8 @@ public class ShadowCopyingStartedEvent extends ApplicationEvent { private Release release; + private Action action; + /** * Create a new event instance. * @@ -28,12 +31,14 @@ public class ShadowCopyingStartedEvent extends ApplicationEvent { * @param dataAcquisitionProjectId id of the released project * @param release the version which has been released * @param previousReleaseVersion the previous version or null + * @param action The action to be executed. */ - public ShadowCopyingStartedEvent(Object source, String dataAcquisitionProjectId, - Release release, String previousReleaseVersion) { + public ShadowCopyingStartedEvent(Object source, String dataAcquisitionProjectId, Release release, + String previousReleaseVersion, Action action) { super(source); this.dataAcquisitionProjectId = dataAcquisitionProjectId; this.previousReleaseVersion = previousReleaseVersion; this.release = release; + this.action = action; } } diff --git a/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/service/helper/DataAcquisitionProjectShadowCopyDataSource.java b/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/service/helper/DataAcquisitionProjectShadowCopyDataSource.java index 1c5a4cdb8d..fb3fc24698 100644 --- a/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/service/helper/DataAcquisitionProjectShadowCopyDataSource.java +++ b/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/service/helper/DataAcquisitionProjectShadowCopyDataSource.java @@ -32,8 +32,7 @@ public Stream getMasters(String dataAcquisitionProjectId @Override public DataAcquisitionProject createShadowCopy(DataAcquisitionProject source, Release release) { String derivedId = source.getId() + "-" + release.getVersion(); - DataAcquisitionProject copy = crudHelper.read(derivedId) - .orElseGet(DataAcquisitionProject::new); + DataAcquisitionProject copy = crudHelper.read(derivedId).orElseGet(DataAcquisitionProject::new); BeanUtils.copyProperties(source, copy, "version"); copy.setId(derivedId); copy.setRelease(release); @@ -82,7 +81,27 @@ public void deleteExistingShadowCopies(String projectId, String version) { @Override public void updateElasticsearch(String dataAcquisitionProjectId, String releaseVersion, String previousVersion) { - throw new IllegalAccessError( - "DataAcquisitionProjects are currently not indexed in elasticsearch"); + // there is currently no elasticsearch index for projects + } + + @Override + public void hideExistingShadowCopies(String projectId, String version) { + setHiddenState(projectId, version, true); + } + + private void setHiddenState(String projectId, String version, boolean hidden) { + String shadowId = projectId + "-" + version; + try (Stream projects = + dataAcquisitionProjectRepository.streamByIdAndShadowIsTrue(shadowId)) { + projects.forEach(shadow -> { + shadow.setHidden(hidden); + crudHelper.saveShadow(shadow); + }); + } + } + + @Override + public void unhideExistingShadowCopies(String projectId, String version) { + setHiddenState(projectId, version, false); } } diff --git a/src/main/java/eu/dzhw/fdz/metadatamanagement/questionmanagement/service/QuestionImageShadowCopyService.java b/src/main/java/eu/dzhw/fdz/metadatamanagement/questionmanagement/service/QuestionImageShadowCopyService.java index 77d4e34b89..b8ca594c52 100644 --- a/src/main/java/eu/dzhw/fdz/metadatamanagement/questionmanagement/service/QuestionImageShadowCopyService.java +++ b/src/main/java/eu/dzhw/fdz/metadatamanagement/questionmanagement/service/QuestionImageShadowCopyService.java @@ -1,11 +1,8 @@ package eu.dzhw.fdz.metadatamanagement.questionmanagement.service; -import org.springframework.context.event.EventListener; import org.springframework.stereotype.Service; import eu.dzhw.fdz.metadatamanagement.common.service.ShadowCopyHelper; -import eu.dzhw.fdz.metadatamanagement.projectmanagement.service.ShadowCopyQueueItemService; -import eu.dzhw.fdz.metadatamanagement.projectmanagement.service.ShadowCopyingStartedEvent; import eu.dzhw.fdz.metadatamanagement.questionmanagement.domain.QuestionImageMetadata; import eu.dzhw.fdz.metadatamanagement.questionmanagement.service.helper.QuestionImageShadowCopyDataSource; @@ -21,16 +18,4 @@ public QuestionImageShadowCopyService( QuestionImageShadowCopyDataSource shadowCopyDataSource) { super(shadowCopyDataSource); } - - /** - * Create shadow copies of current master question images on project release. - * - * @param shadowCopyingStartedEvent Emitted by {@link ShadowCopyQueueItemService} - */ - @EventListener - public void onShadowCopyingStarted(ShadowCopyingStartedEvent shadowCopyingStartedEvent) { - super.createShadowCopies(shadowCopyingStartedEvent.getDataAcquisitionProjectId(), - shadowCopyingStartedEvent.getRelease(), - shadowCopyingStartedEvent.getPreviousReleaseVersion()); - } } diff --git a/src/main/java/eu/dzhw/fdz/metadatamanagement/questionmanagement/service/QuestionShadowCopyService.java b/src/main/java/eu/dzhw/fdz/metadatamanagement/questionmanagement/service/QuestionShadowCopyService.java index 79b2e4ee34..e1e922c9a6 100644 --- a/src/main/java/eu/dzhw/fdz/metadatamanagement/questionmanagement/service/QuestionShadowCopyService.java +++ b/src/main/java/eu/dzhw/fdz/metadatamanagement/questionmanagement/service/QuestionShadowCopyService.java @@ -1,12 +1,8 @@ package eu.dzhw.fdz.metadatamanagement.questionmanagement.service; -import org.springframework.context.event.EventListener; import org.springframework.stereotype.Service; import eu.dzhw.fdz.metadatamanagement.common.service.ShadowCopyHelper; -import eu.dzhw.fdz.metadatamanagement.projectmanagement.service.ShadowCopyQueueItemService; -import eu.dzhw.fdz.metadatamanagement.projectmanagement.service.ShadowCopyingEndedEvent; -import eu.dzhw.fdz.metadatamanagement.projectmanagement.service.ShadowCopyingStartedEvent; import eu.dzhw.fdz.metadatamanagement.questionmanagement.domain.Question; import eu.dzhw.fdz.metadatamanagement.questionmanagement.service.helper.QuestionShadowCopyDataSource; @@ -21,28 +17,4 @@ public class QuestionShadowCopyService extends ShadowCopyHelper { public QuestionShadowCopyService(QuestionShadowCopyDataSource questionShadowCopyDataSource) { super(questionShadowCopyDataSource); } - - /** - * Create shadow copies of current master questions on project release. - * - * @param shadowCopyingStartedEvent Emitted by {@link ShadowCopyQueueItemService} - */ - @EventListener - public void onShadowCopyingStarted(ShadowCopyingStartedEvent shadowCopyingStartedEvent) { - super.createShadowCopies(shadowCopyingStartedEvent.getDataAcquisitionProjectId(), - shadowCopyingStartedEvent.getRelease(), - shadowCopyingStartedEvent.getPreviousReleaseVersion()); - } - - /** - * Update elasticsearch (both predecessors and current shadows). - * - * @param shadowCopyingEndedEvent Emitted by {@link ShadowCopyQueueItemService} - */ - @EventListener - public void onShadowCopyingEnded(ShadowCopyingEndedEvent shadowCopyingEndedEvent) { - super.updateElasticsearch(shadowCopyingEndedEvent.getDataAcquisitionProjectId(), - shadowCopyingEndedEvent.getRelease().getVersion(), - shadowCopyingEndedEvent.getPreviousReleaseVersion()); - } } diff --git a/src/main/java/eu/dzhw/fdz/metadatamanagement/questionmanagement/service/helper/QuestionShadowCopyDataSource.java b/src/main/java/eu/dzhw/fdz/metadatamanagement/questionmanagement/service/helper/QuestionShadowCopyDataSource.java index 19e1dd490b..ebd5e13185 100644 --- a/src/main/java/eu/dzhw/fdz/metadatamanagement/questionmanagement/service/helper/QuestionShadowCopyDataSource.java +++ b/src/main/java/eu/dzhw/fdz/metadatamanagement/questionmanagement/service/helper/QuestionShadowCopyDataSource.java @@ -107,4 +107,25 @@ public void updateElasticsearch(String dataAcquisitionProjectId, String releaseV }, ElasticsearchType.questions); } } + + @Override + public void hideExistingShadowCopies(String projectId, String version) { + setHiddenState(projectId, version, true); + } + + private void setHiddenState(String projectId, String version, boolean hidden) { + String shadowId = projectId + "-" + version; + try (Stream questions = + questionRepository.streamByDataAcquisitionProjectIdAndShadowIsTrue(shadowId)) { + questions.forEach(shadow -> { + shadow.setHidden(hidden); + crudHelper.saveShadow(shadow); + }); + } + } + + @Override + public void unhideExistingShadowCopies(String projectId, String version) { + setHiddenState(projectId, version, false); + } } diff --git a/src/main/java/eu/dzhw/fdz/metadatamanagement/studymanagement/service/StudyAttachmentShadowCopyService.java b/src/main/java/eu/dzhw/fdz/metadatamanagement/studymanagement/service/StudyAttachmentShadowCopyService.java index 10d2aa927a..df61c9ee65 100644 --- a/src/main/java/eu/dzhw/fdz/metadatamanagement/studymanagement/service/StudyAttachmentShadowCopyService.java +++ b/src/main/java/eu/dzhw/fdz/metadatamanagement/studymanagement/service/StudyAttachmentShadowCopyService.java @@ -1,11 +1,8 @@ package eu.dzhw.fdz.metadatamanagement.studymanagement.service; -import org.springframework.context.event.EventListener; import org.springframework.stereotype.Service; import eu.dzhw.fdz.metadatamanagement.common.service.ShadowCopyHelper; -import eu.dzhw.fdz.metadatamanagement.projectmanagement.service.ShadowCopyQueueItemService; -import eu.dzhw.fdz.metadatamanagement.projectmanagement.service.ShadowCopyingStartedEvent; import eu.dzhw.fdz.metadatamanagement.studymanagement.domain.StudyAttachmentMetadata; import eu.dzhw.fdz.metadatamanagement.studymanagement.service.helper.StudyAttachmentShadowCopyDataSource; @@ -21,16 +18,4 @@ public StudyAttachmentShadowCopyService( StudyAttachmentShadowCopyDataSource shadowCopyDataSource) { super(shadowCopyDataSource); } - - /** - * Create shadow copies of current master study attachments on project release. - * - * @param shadowCopyingStartedEvent Emitted by {@link ShadowCopyQueueItemService} - */ - @EventListener - public void onShadowCopyingStarted(ShadowCopyingStartedEvent shadowCopyingStartedEvent) { - super.createShadowCopies(shadowCopyingStartedEvent.getDataAcquisitionProjectId(), - shadowCopyingStartedEvent.getRelease(), - shadowCopyingStartedEvent.getPreviousReleaseVersion()); - } } diff --git a/src/main/java/eu/dzhw/fdz/metadatamanagement/studymanagement/service/StudyShadowCopyService.java b/src/main/java/eu/dzhw/fdz/metadatamanagement/studymanagement/service/StudyShadowCopyService.java index 2c1ce40569..f7fd9a5176 100644 --- a/src/main/java/eu/dzhw/fdz/metadatamanagement/studymanagement/service/StudyShadowCopyService.java +++ b/src/main/java/eu/dzhw/fdz/metadatamanagement/studymanagement/service/StudyShadowCopyService.java @@ -1,12 +1,8 @@ package eu.dzhw.fdz.metadatamanagement.studymanagement.service; -import org.springframework.context.event.EventListener; import org.springframework.stereotype.Service; import eu.dzhw.fdz.metadatamanagement.common.service.ShadowCopyHelper; -import eu.dzhw.fdz.metadatamanagement.projectmanagement.service.ShadowCopyQueueItemService; -import eu.dzhw.fdz.metadatamanagement.projectmanagement.service.ShadowCopyingEndedEvent; -import eu.dzhw.fdz.metadatamanagement.projectmanagement.service.ShadowCopyingStartedEvent; import eu.dzhw.fdz.metadatamanagement.studymanagement.domain.Study; import eu.dzhw.fdz.metadatamanagement.studymanagement.service.helper.StudyShadowCopyDataSource; @@ -21,29 +17,5 @@ public class StudyShadowCopyService extends ShadowCopyHelper { public StudyShadowCopyService(StudyShadowCopyDataSource studyShadowCopyDataSource) { super(studyShadowCopyDataSource); } - - /** - * Create shadow copies of current master studies on project release. - * - * @param shadowCopyingStartedEvent Emitted by {@link ShadowCopyQueueItemService} - */ - @EventListener - public void onShadowCopyingStarted(ShadowCopyingStartedEvent shadowCopyingStartedEvent) { - super.createShadowCopies(shadowCopyingStartedEvent.getDataAcquisitionProjectId(), - shadowCopyingStartedEvent.getRelease(), - shadowCopyingStartedEvent.getPreviousReleaseVersion()); - } - - /** - * Update elasticsearch (both predecessors and current shadows). - * - * @param shadowCopyingEndedEvent Emitted by {@link ShadowCopyQueueItemService} - */ - @EventListener - public void onShadowCopyingEnded(ShadowCopyingEndedEvent shadowCopyingEndedEvent) { - super.updateElasticsearch(shadowCopyingEndedEvent.getDataAcquisitionProjectId(), - shadowCopyingEndedEvent.getRelease().getVersion(), - shadowCopyingEndedEvent.getPreviousReleaseVersion()); - } } diff --git a/src/main/java/eu/dzhw/fdz/metadatamanagement/studymanagement/service/helper/StudyShadowCopyDataSource.java b/src/main/java/eu/dzhw/fdz/metadatamanagement/studymanagement/service/helper/StudyShadowCopyDataSource.java index c27b6fdb50..bc70a64f7b 100644 --- a/src/main/java/eu/dzhw/fdz/metadatamanagement/studymanagement/service/helper/StudyShadowCopyDataSource.java +++ b/src/main/java/eu/dzhw/fdz/metadatamanagement/studymanagement/service/helper/StudyShadowCopyDataSource.java @@ -96,4 +96,25 @@ public void updateElasticsearch(String dataAcquisitionProjectId, String releaseV }, ElasticsearchType.studies); } } + + @Override + public void hideExistingShadowCopies(String projectId, String version) { + setHiddenState(projectId, version, true); + } + + private void setHiddenState(String projectId, String version, boolean hidden) { + String shadowId = projectId + "-" + version; + try (Stream studies = + studyRepository.streamByDataAcquisitionProjectIdAndShadowIsTrue(shadowId)) { + studies.forEach(shadow -> { + shadow.setHidden(hidden); + crudHelper.saveShadow(shadow); + }); + } + } + + @Override + public void unhideExistingShadowCopies(String projectId, String version) { + setHiddenState(projectId, version, false); + } } diff --git a/src/main/java/eu/dzhw/fdz/metadatamanagement/surveymanagement/service/SurveyAttachmentShadowCopyService.java b/src/main/java/eu/dzhw/fdz/metadatamanagement/surveymanagement/service/SurveyAttachmentShadowCopyService.java index f26526965a..a63e0fd902 100644 --- a/src/main/java/eu/dzhw/fdz/metadatamanagement/surveymanagement/service/SurveyAttachmentShadowCopyService.java +++ b/src/main/java/eu/dzhw/fdz/metadatamanagement/surveymanagement/service/SurveyAttachmentShadowCopyService.java @@ -1,11 +1,8 @@ package eu.dzhw.fdz.metadatamanagement.surveymanagement.service; -import org.springframework.context.event.EventListener; import org.springframework.stereotype.Service; import eu.dzhw.fdz.metadatamanagement.common.service.ShadowCopyHelper; -import eu.dzhw.fdz.metadatamanagement.projectmanagement.service.ShadowCopyQueueItemService; -import eu.dzhw.fdz.metadatamanagement.projectmanagement.service.ShadowCopyingStartedEvent; import eu.dzhw.fdz.metadatamanagement.surveymanagement.domain.SurveyAttachmentMetadata; import eu.dzhw.fdz.metadatamanagement.surveymanagement.service.helper.SurveyAttachmentShadowCopyDataSource; @@ -21,16 +18,4 @@ public SurveyAttachmentShadowCopyService( SurveyAttachmentShadowCopyDataSource shadowCopyDataSource) { super(shadowCopyDataSource); } - - /** - * Create shadow copies of current master survey attachments on project release. - * - * @param shadowCopyingStartedEvent Emitted by {@link ShadowCopyQueueItemService} - */ - @EventListener - public void onShadowCopyingStarted(ShadowCopyingStartedEvent shadowCopyingStartedEvent) { - super.createShadowCopies(shadowCopyingStartedEvent.getDataAcquisitionProjectId(), - shadowCopyingStartedEvent.getRelease(), - shadowCopyingStartedEvent.getPreviousReleaseVersion()); - } } diff --git a/src/main/java/eu/dzhw/fdz/metadatamanagement/surveymanagement/service/SurveyResponseRateImageShadowCopyService.java b/src/main/java/eu/dzhw/fdz/metadatamanagement/surveymanagement/service/SurveyResponseRateImageShadowCopyService.java index b2bf1bce43..b18163afa4 100644 --- a/src/main/java/eu/dzhw/fdz/metadatamanagement/surveymanagement/service/SurveyResponseRateImageShadowCopyService.java +++ b/src/main/java/eu/dzhw/fdz/metadatamanagement/surveymanagement/service/SurveyResponseRateImageShadowCopyService.java @@ -1,11 +1,8 @@ package eu.dzhw.fdz.metadatamanagement.surveymanagement.service; -import org.springframework.context.event.EventListener; import org.springframework.stereotype.Service; import eu.dzhw.fdz.metadatamanagement.common.service.ShadowCopyHelper; -import eu.dzhw.fdz.metadatamanagement.projectmanagement.service.ShadowCopyQueueItemService; -import eu.dzhw.fdz.metadatamanagement.projectmanagement.service.ShadowCopyingStartedEvent; import eu.dzhw.fdz.metadatamanagement.surveymanagement.domain.SurveyResponseRateImageMetadata; import eu.dzhw.fdz.metadatamanagement.surveymanagement.service.helper.SurveyResponseRateImageShadowCopyDataSource; @@ -23,16 +20,4 @@ public SurveyResponseRateImageShadowCopyService( SurveyResponseRateImageShadowCopyDataSource shadowCopyDataSource) { super(shadowCopyDataSource); } - - /** - * Create shadow copies of current master response rate images on project release. - * - * @param shadowCopyingStartedEvent Emitted by {@link ShadowCopyQueueItemService} - */ - @EventListener - public void onShadowCopyingStarted(ShadowCopyingStartedEvent shadowCopyingStartedEvent) { - super.createShadowCopies(shadowCopyingStartedEvent.getDataAcquisitionProjectId(), - shadowCopyingStartedEvent.getRelease(), - shadowCopyingStartedEvent.getPreviousReleaseVersion()); - } } diff --git a/src/main/java/eu/dzhw/fdz/metadatamanagement/surveymanagement/service/SurveyShadowCopyService.java b/src/main/java/eu/dzhw/fdz/metadatamanagement/surveymanagement/service/SurveyShadowCopyService.java index a80ba8f859..84c8f507f8 100644 --- a/src/main/java/eu/dzhw/fdz/metadatamanagement/surveymanagement/service/SurveyShadowCopyService.java +++ b/src/main/java/eu/dzhw/fdz/metadatamanagement/surveymanagement/service/SurveyShadowCopyService.java @@ -1,12 +1,8 @@ package eu.dzhw.fdz.metadatamanagement.surveymanagement.service; -import org.springframework.context.event.EventListener; import org.springframework.stereotype.Service; import eu.dzhw.fdz.metadatamanagement.common.service.ShadowCopyHelper; -import eu.dzhw.fdz.metadatamanagement.projectmanagement.service.ShadowCopyQueueItemService; -import eu.dzhw.fdz.metadatamanagement.projectmanagement.service.ShadowCopyingEndedEvent; -import eu.dzhw.fdz.metadatamanagement.projectmanagement.service.ShadowCopyingStartedEvent; import eu.dzhw.fdz.metadatamanagement.surveymanagement.domain.Survey; import eu.dzhw.fdz.metadatamanagement.surveymanagement.service.helper.SurveyShadowCopyDataSource; @@ -21,28 +17,4 @@ public class SurveyShadowCopyService extends ShadowCopyHelper { public SurveyShadowCopyService(SurveyShadowCopyDataSource surveyShadowCopyDataSource) { super(surveyShadowCopyDataSource); } - - /** - * Create shadow copies of current master surveys on project release. - * - * @param shadowCopyingStartedEvent Emitted by {@link ShadowCopyQueueItemService} - */ - @EventListener - public void onShadowCopyingStarted(ShadowCopyingStartedEvent shadowCopyingStartedEvent) { - super.createShadowCopies(shadowCopyingStartedEvent.getDataAcquisitionProjectId(), - shadowCopyingStartedEvent.getRelease(), - shadowCopyingStartedEvent.getPreviousReleaseVersion()); - } - - /** - * Update elasticsearch (both predecessors and current shadows). - * - * @param shadowCopyingEndedEvent Emitted by {@link ShadowCopyQueueItemService} - */ - @EventListener - public void onShadowCopyingEnded(ShadowCopyingEndedEvent shadowCopyingEndedEvent) { - super.updateElasticsearch(shadowCopyingEndedEvent.getDataAcquisitionProjectId(), - shadowCopyingEndedEvent.getRelease().getVersion(), - shadowCopyingEndedEvent.getPreviousReleaseVersion()); - } } diff --git a/src/main/java/eu/dzhw/fdz/metadatamanagement/surveymanagement/service/helper/SurveyShadowCopyDataSource.java b/src/main/java/eu/dzhw/fdz/metadatamanagement/surveymanagement/service/helper/SurveyShadowCopyDataSource.java index 84b1104b02..4403590f32 100644 --- a/src/main/java/eu/dzhw/fdz/metadatamanagement/surveymanagement/service/helper/SurveyShadowCopyDataSource.java +++ b/src/main/java/eu/dzhw/fdz/metadatamanagement/surveymanagement/service/helper/SurveyShadowCopyDataSource.java @@ -97,4 +97,25 @@ public void updateElasticsearch(String dataAcquisitionProjectId, String releaseV }, ElasticsearchType.surveys); } } + + @Override + public void hideExistingShadowCopies(String projectId, String version) { + setHiddenState(projectId, version, true); + } + + private void setHiddenState(String projectId, String version, boolean hidden) { + String shadowId = projectId + "-" + version; + try (Stream surveys = + surveyRepository.streamByDataAcquisitionProjectIdAndShadowIsTrue(shadowId)) { + surveys.forEach(shadow -> { + shadow.setHidden(hidden); + crudHelper.saveShadow(shadow); + }); + } + } + + @Override + public void unhideExistingShadowCopies(String projectId, String version) { + setHiddenState(projectId, version, false); + } } diff --git a/src/main/java/eu/dzhw/fdz/metadatamanagement/variablemanagement/service/VariableShadowCopyService.java b/src/main/java/eu/dzhw/fdz/metadatamanagement/variablemanagement/service/VariableShadowCopyService.java index 0676e2ead7..8846b8e72b 100644 --- a/src/main/java/eu/dzhw/fdz/metadatamanagement/variablemanagement/service/VariableShadowCopyService.java +++ b/src/main/java/eu/dzhw/fdz/metadatamanagement/variablemanagement/service/VariableShadowCopyService.java @@ -1,12 +1,8 @@ package eu.dzhw.fdz.metadatamanagement.variablemanagement.service; -import org.springframework.context.event.EventListener; import org.springframework.stereotype.Service; import eu.dzhw.fdz.metadatamanagement.common.service.ShadowCopyHelper; -import eu.dzhw.fdz.metadatamanagement.projectmanagement.service.ShadowCopyQueueItemService; -import eu.dzhw.fdz.metadatamanagement.projectmanagement.service.ShadowCopyingEndedEvent; -import eu.dzhw.fdz.metadatamanagement.projectmanagement.service.ShadowCopyingStartedEvent; import eu.dzhw.fdz.metadatamanagement.variablemanagement.domain.Variable; import eu.dzhw.fdz.metadatamanagement.variablemanagement.service.helper.VariableShadowCopyDataSource; @@ -21,28 +17,4 @@ public class VariableShadowCopyService extends ShadowCopyHelper { public VariableShadowCopyService(VariableShadowCopyDataSource variableShadowCopyDataSource) { super(variableShadowCopyDataSource); } - - /** - * Create shadow copies of current master variables on project release. - * - * @param shadowCopyingStartedEvent Emitted by {@link ShadowCopyQueueItemService} - */ - @EventListener - public void onShadowCopyingStarted(ShadowCopyingStartedEvent shadowCopyingStartedEvent) { - super.createShadowCopies(shadowCopyingStartedEvent.getDataAcquisitionProjectId(), - shadowCopyingStartedEvent.getRelease(), - shadowCopyingStartedEvent.getPreviousReleaseVersion()); - } - - /** - * Update elasticsearch (both predecessors and current shadows). - * - * @param shadowCopyingEndedEvent Emitted by {@link ShadowCopyQueueItemService} - */ - @EventListener - public void onShadowCopyingEnded(ShadowCopyingEndedEvent shadowCopyingEndedEvent) { - super.updateElasticsearch(shadowCopyingEndedEvent.getDataAcquisitionProjectId(), - shadowCopyingEndedEvent.getRelease().getVersion(), - shadowCopyingEndedEvent.getPreviousReleaseVersion()); - } } diff --git a/src/main/java/eu/dzhw/fdz/metadatamanagement/variablemanagement/service/helper/VariableShadowCopyDataSource.java b/src/main/java/eu/dzhw/fdz/metadatamanagement/variablemanagement/service/helper/VariableShadowCopyDataSource.java index e8a7dcdc62..d80b459040 100644 --- a/src/main/java/eu/dzhw/fdz/metadatamanagement/variablemanagement/service/helper/VariableShadowCopyDataSource.java +++ b/src/main/java/eu/dzhw/fdz/metadatamanagement/variablemanagement/service/helper/VariableShadowCopyDataSource.java @@ -137,4 +137,25 @@ public void updateElasticsearch(String dataAcquisitionProjectId, String releaseV }, ElasticsearchType.variables); } } + + @Override + public void hideExistingShadowCopies(String projectId, String version) { + setHiddenState(projectId, version, true); + } + + private void setHiddenState(String projectId, String version, boolean hidden) { + String shadowId = projectId + "-" + version; + try (Stream variables = + variableRepository.findByDataAcquisitionProjectIdAndShadowIsTrue(shadowId)) { + variables.forEach(shadow -> { + shadow.setHidden(hidden); + crudHelper.saveShadow(shadow); + }); + } + } + + @Override + public void unhideExistingShadowCopies(String projectId, String version) { + setHiddenState(projectId, version, false); + } } diff --git a/src/main/resources/templates/dara/register.xml.tmpl b/src/main/resources/templates/dara/register.xml.tmpl index c38f0bc9fe..1571e93e63 100644 --- a/src/main/resources/templates/dara/register.xml.tmpl +++ b/src/main/resources/templates/dara/register.xml.tmpl @@ -12,7 +12,7 @@ - dzhw:${study.dataAcquisitionProjectId}:1.0.0 + dzhw:${dataAcquisitionProject.masterId}:1.0.0 ${dataAcquisitionProject.release.version} @@ -49,7 +49,7 @@ - https://metadata.fdz.dzhw.eu/#!/de/studies/${study.id}?version=${dataAcquisitionProject.release.version} + https://metadata.fdz.dzhw.eu/#!/de/studies/${study.masterId}?version=${dataAcquisitionProject.release.version} ${doi} @@ -60,11 +60,11 @@ ${availabilityControlled} de - Beantragung notwendig unter https://metadata.fdz.dzhw.eu/#!/de/studies/${study.id}?version=${dataAcquisitionProject.release.version} + Beantragung notwendig unter https://metadata.fdz.dzhw.eu/#!/de/studies/${study.masterId}?version=${dataAcquisitionProject.release.version} en - Application necessary under https://metadata.fdz.dzhw.eu/#!/en/studies/${study.id}?version=${dataAcquisitionProject.release.version} + Application necessary under https://metadata.fdz.dzhw.eu/#!/en/studies/${study.masterId}?version=${dataAcquisitionProject.release.version} diff --git a/src/test/java/eu/dzhw/fdz/metadatamanagement/studymanagement/rest/StudyResourceControllerTest.java b/src/test/java/eu/dzhw/fdz/metadatamanagement/studymanagement/rest/StudyResourceControllerTest.java index cc8187a476..76f495a5a6 100644 --- a/src/test/java/eu/dzhw/fdz/metadatamanagement/studymanagement/rest/StudyResourceControllerTest.java +++ b/src/test/java/eu/dzhw/fdz/metadatamanagement/studymanagement/rest/StudyResourceControllerTest.java @@ -98,6 +98,23 @@ public void testCreateStudy() throws IOException, Exception { // read the study under the new url mockMvc.perform(get(API_STUDY_URI + "/" + study.getId())).andExpect(status().isOk()); } + + @Test + @WithMockUser(authorities = AuthoritiesConstants.PUBLISHER) + public void testCreateHiddenStudy() throws IOException, Exception { + DataAcquisitionProject project = UnitTestCreateDomainObjectUtils.buildDataAcquisitionProject(); + dataAcquisitionProjectRepository.save(project); + + Study study = UnitTestCreateDomainObjectUtils.buildStudy(project.getId()); + study.setHidden(true); + + // create the hidden study with the given id + mockMvc.perform(put(API_STUDY_URI + "/" + study.getId()) + .content(TestUtil.convertObjectToJsonBytes(study)).contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isBadRequest()) + .andExpect(jsonPath("$.errors[0].message", + containsString("invalid-hidden-shadow"))); + } @Test @WithMockUser(authorities = AuthoritiesConstants.PUBLISHER) From 18cf2e7f6cfb8d3d6d7d180b201259b171c773d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Reitmann?= Date: Tue, 10 Sep 2019 14:33:03 +0200 Subject: [PATCH 03/16] #2278 add front end implementation --- ...GenericDomainObjectResourceController.java | 3 +- .../GenericDomainObjectVersionsService.java | 2 +- ...DataAcquisitionProjectShadowsResource.java | 23 +++ .../service/DaraService.java | 1 + ...taAcquisitionProjectManagementService.java | 9 +- ...DataAcquisitionProjectVersionsService.java | 40 ++++- .../service/ShadowCopyQueueItemService.java | 17 ++ .../elasticsearch/data_sets/mapping.json | 4 + .../elasticsearch/indices_version.json | 2 +- .../elasticsearch/instruments/mapping.json | 4 + .../elasticsearch/questions/mapping.json | 4 + .../elasticsearch/studies/mapping.json | 4 + .../elasticsearch/surveys/mapping.json | 4 + .../elasticsearch/variables/mapping.json | 4 + src/main/scss/main.scss | 4 + src/main/webapp/index.html | 4 + src/main/webapp/scripts/app.js | 1 + .../attachment-edit-or-create.html.tmpl | 2 +- .../dialogs/services/commonDialogs.service.js | 13 ++ .../views/concept-edit-or-create.html.tmpl | 2 +- .../configuration/translations-de.js | 20 ++- .../configuration/translations-en.js | 20 ++- .../project-cockpit-versions.directive.js | 151 ++++++++++++++++++ .../project-cockpit-versions.html.tmpl | 36 +++++ .../directives/user-list.directive.js | 3 +- .../dataAcquisitionProjectShadows.resource.js | 13 ++ ...cquisitionProjectShadowsAction.resource.js | 14 ++ ...aAcquisitionProjectShadowsHide.resource.js | 17 ++ .../views/project-cockpit.controller.js | 7 +- .../views/project-cockpit.html.tmpl | 9 ++ .../views/data-set-edit-or-create.html.tmpl | 2 +- .../views/instrument-edit-or-create.html.tmpl | 2 +- .../services/searchHelper.service.js | 11 ++ .../views/study-edit-or-create.html.tmpl | 2 +- .../views/survey-edit-or-create.html.tmpl | 2 +- 35 files changed, 431 insertions(+), 25 deletions(-) create mode 100644 src/main/webapp/scripts/dataacquisitionprojectmanagement/directives/project-cockpit-versions.directive.js create mode 100644 src/main/webapp/scripts/dataacquisitionprojectmanagement/directives/project-cockpit-versions.html.tmpl create mode 100644 src/main/webapp/scripts/dataacquisitionprojectmanagement/resources/dataAcquisitionProjectShadows.resource.js create mode 100644 src/main/webapp/scripts/dataacquisitionprojectmanagement/resources/dataAcquisitionProjectShadowsAction.resource.js create mode 100644 src/main/webapp/scripts/dataacquisitionprojectmanagement/resources/dataAcquisitionProjectShadowsHide.resource.js diff --git a/src/main/java/eu/dzhw/fdz/metadatamanagement/common/rest/GenericDomainObjectResourceController.java b/src/main/java/eu/dzhw/fdz/metadatamanagement/common/rest/GenericDomainObjectResourceController.java index f30bc4b91f..a4785b3193 100644 --- a/src/main/java/eu/dzhw/fdz/metadatamanagement/common/rest/GenericDomainObjectResourceController.java +++ b/src/main/java/eu/dzhw/fdz/metadatamanagement/common/rest/GenericDomainObjectResourceController.java @@ -53,7 +53,8 @@ public ResponseEntity getDomainObject(String id) { return ResponseEntity.notFound().build(); } else { T domainObject = optional.get(); - if (AbstractShadowableRdcDomainObject.class.isAssignableFrom(domainObject.getClass()) + if (userInformationProvider.isUserAnonymous() + && AbstractShadowableRdcDomainObject.class.isAssignableFrom(domainObject.getClass()) && ((AbstractShadowableRdcDomainObject) domainObject).isHidden()) { return ResponseEntity.notFound().build(); } diff --git a/src/main/java/eu/dzhw/fdz/metadatamanagement/common/service/GenericDomainObjectVersionsService.java b/src/main/java/eu/dzhw/fdz/metadatamanagement/common/service/GenericDomainObjectVersionsService.java index 6ac00f0609..63fd354b05 100644 --- a/src/main/java/eu/dzhw/fdz/metadatamanagement/common/service/GenericDomainObjectVersionsService.java +++ b/src/main/java/eu/dzhw/fdz/metadatamanagement/common/service/GenericDomainObjectVersionsService.java @@ -26,7 +26,7 @@ public abstract class GenericDomainObjectVersionsService> { protected Javers javers; - private S repository; + protected S repository; private MetadataManagementProperties metadataManagementProperties; private Class domainObjectClass; diff --git a/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/rest/DataAcquisitionProjectShadowsResource.java b/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/rest/DataAcquisitionProjectShadowsResource.java index 7914af14f3..799606682b 100644 --- a/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/rest/DataAcquisitionProjectShadowsResource.java +++ b/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/rest/DataAcquisitionProjectShadowsResource.java @@ -1,5 +1,7 @@ package eu.dzhw.fdz.metadatamanagement.projectmanagement.rest; +import java.util.HashMap; +import java.util.Map; import java.util.Optional; import org.springframework.data.domain.Page; @@ -20,9 +22,11 @@ import eu.dzhw.fdz.metadatamanagement.common.rest.errors.ErrorDto; import eu.dzhw.fdz.metadatamanagement.common.rest.errors.ErrorListDto; import eu.dzhw.fdz.metadatamanagement.projectmanagement.domain.DataAcquisitionProject; +import eu.dzhw.fdz.metadatamanagement.projectmanagement.domain.ShadowCopyQueueItem.Action; import eu.dzhw.fdz.metadatamanagement.projectmanagement.domain.ShadowHidingNotAllowedException; import eu.dzhw.fdz.metadatamanagement.projectmanagement.domain.ShadowUnhidingNotAllowedException; import eu.dzhw.fdz.metadatamanagement.projectmanagement.service.DataAcquisitionProjectManagementService; +import eu.dzhw.fdz.metadatamanagement.projectmanagement.service.ShadowCopyQueueItemService; import lombok.RequiredArgsConstructor; /** @@ -37,6 +41,8 @@ public class DataAcquisitionProjectShadowsResource { private final DataAcquisitionProjectManagementService dataAcquisitionProjectManagementService; + private final ShadowCopyQueueItemService shadowCopyQueueItemService; + /** * Get the previous 5 versions of the data acquisition project. * @@ -102,6 +108,23 @@ public ResponseEntity unhideShadows(@PathVariable String id, @PathVariable St return ResponseEntity.accepted().build(); } + /** + * Get the current action which is currently performed for the given shadow. + * + * @param id The master id of the project + * @param version the version of the project + * + * @return The current action, or empty response. + */ + @GetMapping("/data-acquisition-projects/{id}/shadows/{version}/action") + public ResponseEntity> getCurrentAction(@PathVariable String id, + @PathVariable String version) { + Action action = shadowCopyQueueItemService.findCurrentAction(id, version); + Map result = new HashMap<>(); + result.put("action", action); + return ResponseEntity.ok().cacheControl(CacheControl.noStore()).body(result); + } + /** * Handle {@link ShadowHidingNotAllowedException} {@link ShadowUnhidingNotAllowedException} or * thrown by attempts to hide or unhide a project. diff --git a/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/service/DaraService.java b/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/service/DaraService.java index e9d0cc5294..555c0af154 100644 --- a/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/service/DaraService.java +++ b/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/service/DaraService.java @@ -1,3 +1,4 @@ + package eu.dzhw.fdz.metadatamanagement.projectmanagement.service; import java.io.IOException; diff --git a/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/service/DataAcquisitionProjectManagementService.java b/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/service/DataAcquisitionProjectManagementService.java index 5aa5a047ef..7aa75b2662 100644 --- a/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/service/DataAcquisitionProjectManagementService.java +++ b/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/service/DataAcquisitionProjectManagementService.java @@ -314,9 +314,12 @@ public void onShadowCopyingEnded(ShadowCopyingEndedEvent shadowCopyingEndedEvent break; case HIDE: case UNHIDE: - daraService - .registerOrUpdateProjectToDara(shadowCopyingEndedEvent.getDataAcquisitionProjectId() - + "-" + shadowCopyingEndedEvent.getRelease().getVersion()); + if (Version.valueOf(shadowCopyingEndedEvent.getRelease().getVersion()) + .greaterThanOrEqualTo(Version.valueOf("1.0.0"))) { + daraService + .registerOrUpdateProjectToDara(shadowCopyingEndedEvent.getDataAcquisitionProjectId() + + "-" + shadowCopyingEndedEvent.getRelease().getVersion()); + } break; default: throw new IllegalArgumentException( diff --git a/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/service/DataAcquisitionProjectVersionsService.java b/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/service/DataAcquisitionProjectVersionsService.java index 39dc3520de..cb844e5531 100644 --- a/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/service/DataAcquisitionProjectVersionsService.java +++ b/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/service/DataAcquisitionProjectVersionsService.java @@ -16,12 +16,15 @@ import org.springframework.stereotype.Service; import com.github.zafarkhaja.semver.Version; +import com.querydsl.core.types.Predicate; import eu.dzhw.fdz.metadatamanagement.common.config.MetadataManagementProperties; import eu.dzhw.fdz.metadatamanagement.common.service.GenericDomainObjectVersionsService; import eu.dzhw.fdz.metadatamanagement.projectmanagement.domain.DataAcquisitionProject; +import eu.dzhw.fdz.metadatamanagement.projectmanagement.domain.QDataAcquisitionProject; import eu.dzhw.fdz.metadatamanagement.projectmanagement.domain.Release; import eu.dzhw.fdz.metadatamanagement.projectmanagement.repository.DataAcquisitionProjectRepository; +import eu.dzhw.fdz.metadatamanagement.usermanagement.security.UserInformationProvider; /** * Service responsible for retrieving an initializing the data acquisition project history. @@ -32,14 +35,23 @@ @Service public class DataAcquisitionProjectVersionsService extends GenericDomainObjectVersionsService { + + private final UserInformationProvider userInformationProvider; + + private static final Predicate projectNotHidden = + QDataAcquisitionProject.dataAcquisitionProject.hidden.isNull() + .or(QDataAcquisitionProject.dataAcquisitionProject.hidden.isFalse()); + /** * Construct the service. */ public DataAcquisitionProjectVersionsService(Javers javers, DataAcquisitionProjectRepository dataAcquisitionProjectRepository, - MetadataManagementProperties metadataManagementProperties) { + MetadataManagementProperties metadataManagementProperties, + UserInformationProvider userInformationProvider) { super(DataAcquisitionProject.class, javers, dataAcquisitionProjectRepository, metadataManagementProperties); + this.userInformationProvider = userInformationProvider; } /** @@ -100,23 +112,37 @@ public Release findPreviousRelease(String id, Release currentRelease) { * Find all release stamps (limited to 100 results) for the given project id. * * @param id the project id - * @param noBeta boolean indicating if beta release shall be skipped or not + * @param noBeta boolean indicating if beta release shall be skipped or not * @return List of all releases (max 100 entries). */ public List findAllReleases(String id, boolean noBeta) { // Find all version changes List> shadows = - javers.findShadows(QueryBuilder.byValueObjectId( - id, DataAcquisitionProject.class, "release") + javers.findShadows(QueryBuilder.byValueObjectId(id, DataAcquisitionProject.class, "release") .withChangedProperty("version").limit(100).build()); if (shadows.isEmpty()) { return new ArrayList<>(); } else { - return shadows - .stream().map(shadow -> shadow.get()).filter(release -> !noBeta || Version - .valueOf(release.getVersion()).greaterThanOrEqualTo(Version.valueOf("1.0.0"))) + return shadows.stream().map(shadow -> shadow.get()) + .filter(release -> isAvailable(id, release) && (!noBeta || Version + .valueOf(release.getVersion()).greaterThanOrEqualTo(Version.valueOf("1.0.0")))) .collect(Collectors.toList()); } } + + /** + * Check if the released shadow has not been hidden for public users. + * + * @param id masterId of the project + * @param release the release containing the version of the shadow + * @return false if the shadow is hidden and the current user is a public user + */ + private boolean isAvailable(String id, Release release) { + if (userInformationProvider.isUserAnonymous()) { + return super.repository.exists(QDataAcquisitionProject.dataAcquisitionProject.id + .eq(id + "-" + release.getVersion()).and(projectNotHidden)); + } + return true; + } } diff --git a/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/service/ShadowCopyQueueItemService.java b/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/service/ShadowCopyQueueItemService.java index 9ac32b4138..c71253a3d7 100644 --- a/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/service/ShadowCopyQueueItemService.java +++ b/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/service/ShadowCopyQueueItemService.java @@ -205,4 +205,21 @@ private void emitShadowCopyingStartedEvent(DataAcquisitionProject dataAcquisitio this.applicationEventPublisher.publishEvent(new ShadowCopyingStartedEvent(this, dataAcquisitionProject.getId(), release, previousReleaseVersion, action)); } + + /** + * Get the action which is currently performed for the given shadow identified by the given + * params. + * + * @param dataAcquisitionProjectId masterId of the project + * @param version the version of the project + * @return The current action if the shadow is still in the queue. + */ + public Action findCurrentAction(String dataAcquisitionProjectId, String version) { + Optional queueItem = shadowCopyQueueItemRepository + .findByDataAcquisitionProjectIdAndReleaseVersion(dataAcquisitionProjectId, version); + if (queueItem.isPresent()) { + return queueItem.get().getAction(); + } + return null; + } } diff --git a/src/main/resources/elasticsearch/data_sets/mapping.json b/src/main/resources/elasticsearch/data_sets/mapping.json index a8745c3bda..f495fcdcdb 100644 --- a/src/main/resources/elasticsearch/data_sets/mapping.json +++ b/src/main/resources/elasticsearch/data_sets/mapping.json @@ -55,6 +55,10 @@ "type": "boolean", "copy_to": "all" }, + "hidden": { + "type": "boolean", + "copy_to": "all" + }, "completeTitle": { "type": "object", "properties": { diff --git a/src/main/resources/elasticsearch/indices_version.json b/src/main/resources/elasticsearch/indices_version.json index 796da69ed5..a94fe6923c 100644 --- a/src/main/resources/elasticsearch/indices_version.json +++ b/src/main/resources/elasticsearch/indices_version.json @@ -1,3 +1,3 @@ { - "indicesVersion": "201906171150" + "indicesVersion": "201909101325" } diff --git a/src/main/resources/elasticsearch/instruments/mapping.json b/src/main/resources/elasticsearch/instruments/mapping.json index a08347fafe..2c61980cc1 100644 --- a/src/main/resources/elasticsearch/instruments/mapping.json +++ b/src/main/resources/elasticsearch/instruments/mapping.json @@ -55,6 +55,10 @@ "type": "boolean", "copy_to": "all" }, + "hidden": { + "type": "boolean", + "copy_to": "all" + }, "completeTitle": { "type": "object", "properties": { diff --git a/src/main/resources/elasticsearch/questions/mapping.json b/src/main/resources/elasticsearch/questions/mapping.json index 8fb34132d5..1132e9ead4 100644 --- a/src/main/resources/elasticsearch/questions/mapping.json +++ b/src/main/resources/elasticsearch/questions/mapping.json @@ -55,6 +55,10 @@ "type": "boolean", "copy_to": "all" }, + "hidden": { + "type": "boolean", + "copy_to": "all" + }, "completeTitle": { "type": "object", "properties": { diff --git a/src/main/resources/elasticsearch/studies/mapping.json b/src/main/resources/elasticsearch/studies/mapping.json index a0b48f1ff0..5590cd2651 100644 --- a/src/main/resources/elasticsearch/studies/mapping.json +++ b/src/main/resources/elasticsearch/studies/mapping.json @@ -55,6 +55,10 @@ "type": "boolean", "copy_to": "all" }, + "hidden": { + "type": "boolean", + "copy_to": "all" + }, "completeTitle": { "type": "object", "properties": { diff --git a/src/main/resources/elasticsearch/surveys/mapping.json b/src/main/resources/elasticsearch/surveys/mapping.json index 47c323f096..b9767ceeb1 100644 --- a/src/main/resources/elasticsearch/surveys/mapping.json +++ b/src/main/resources/elasticsearch/surveys/mapping.json @@ -55,6 +55,10 @@ "type": "boolean", "copy_to": "all" }, + "hidden": { + "type": "boolean", + "copy_to": "all" + }, "completeTitle": { "type": "object", "properties": { diff --git a/src/main/resources/elasticsearch/variables/mapping.json b/src/main/resources/elasticsearch/variables/mapping.json index 28683a712e..f96ad8944f 100644 --- a/src/main/resources/elasticsearch/variables/mapping.json +++ b/src/main/resources/elasticsearch/variables/mapping.json @@ -55,6 +55,10 @@ "type": "boolean", "copy_to": "all" }, + "hidden": { + "type": "boolean", + "copy_to": "all" + }, "completeTitle": { "type": "object", "properties": { diff --git a/src/main/scss/main.scss b/src/main/scss/main.scss index bd696b1b6b..893d36e17b 100644 --- a/src/main/scss/main.scss +++ b/src/main/scss/main.scss @@ -1251,6 +1251,10 @@ geographic-coverage { } } +.fdz-odd-row { + background-color: #f9f9f9; +} + .egg-confused { position: absolute; z-index: 999999; diff --git a/src/main/webapp/index.html b/src/main/webapp/index.html index 8ae214b1f7..cadd80a032 100644 --- a/src/main/webapp/index.html +++ b/src/main/webapp/index.html @@ -421,6 +421,9 @@

Metadatamanagement (MDM)

+ + + @@ -437,6 +440,7 @@

Metadatamanagement (MDM)

+ diff --git a/src/main/webapp/scripts/app.js b/src/main/webapp/scripts/app.js index 58dd830079..fd72aa1dc3 100644 --- a/src/main/webapp/scripts/app.js +++ b/src/main/webapp/scripts/app.js @@ -184,6 +184,7 @@ try { if (config.url.indexOf('_search') !== -1 || (config.url.indexOf('/api/data-acquisition-projects/') !== -1 && config.method === 'GET' && + config.url.indexOf('/shadows') === -1 && config.url.indexOf('/releases') === -1) || config.url.indexOf('/api/users/findUserWithRole') !== -1 || (config.url.indexOf('/api/concepts/') !== -1 && diff --git a/src/main/webapp/scripts/common/dialogs/attachment/attachment-edit-or-create.html.tmpl b/src/main/webapp/scripts/common/dialogs/attachment/attachment-edit-or-create.html.tmpl index 595cc632a5..c27add92f5 100644 --- a/src/main/webapp/scripts/common/dialogs/attachment/attachment-edit-or-create.html.tmpl +++ b/src/main/webapp/scripts/common/dialogs/attachment/attachment-edit-or-create.html.tmpl @@ -124,7 +124,7 @@ {{'attachment.tooltip.previous-version' | translate}} - undo + history diff --git a/src/main/webapp/scripts/common/dialogs/services/commonDialogs.service.js b/src/main/webapp/scripts/common/dialogs/services/commonDialogs.service.js index cc5d0f14a9..2aaf85cfaf 100644 --- a/src/main/webapp/scripts/common/dialogs/services/commonDialogs.service.js +++ b/src/main/webapp/scripts/common/dialogs/services/commonDialogs.service.js @@ -21,6 +21,18 @@ angular.module('metadatamanagementApp').factory('CommonDialogsService', $cancelButton.focus(); }; + var showConfirmDialog = function(titleKey, titleParams, contentKey, + contentParams, targetEvent) { + var confirmDialog = $mdDialog.confirm({ + onComplete: focusCancelButton + }).title($translate.instant(titleKey, titleParams)).textContent( + $translate.instant(contentKey, contentParams)) + .ok($translate.instant('global.common-dialogs.yes')) + .cancel($translate.instant('global.common-dialogs.no')) + .targetEvent(targetEvent); + return $mdDialog.show(confirmDialog); + }; + var showConfirmOnDirtyDialog = function() { var confirmOnDirtyDialog = $mdDialog.confirm({ onComplete: focusCancelButton, @@ -79,6 +91,7 @@ angular.module('metadatamanagementApp').factory('CommonDialogsService', }; return { + showConfirmDialog: showConfirmDialog, showConfirmOnDirtyDialog: showConfirmOnDirtyDialog, showConfirmFileDeletionDialog: showConfirmFileDeletionDialog, showConfirmFilenameChangedDialog: showConfirmFilenameChangedDialog, diff --git a/src/main/webapp/scripts/conceptmanagement/views/concept-edit-or-create.html.tmpl b/src/main/webapp/scripts/conceptmanagement/views/concept-edit-or-create.html.tmpl index 2749434a60..c0a732cc70 100644 --- a/src/main/webapp/scripts/conceptmanagement/views/concept-edit-or-create.html.tmpl +++ b/src/main/webapp/scripts/conceptmanagement/views/concept-edit-or-create.html.tmpl @@ -322,7 +322,7 @@ {{'concept-management.edit.open-choose-previous-version-tooltip' | translate}} - undo + history diff --git a/src/main/webapp/scripts/dataacquisitionprojectmanagement/configuration/translations-de.js b/src/main/webapp/scripts/dataacquisitionprojectmanagement/configuration/translations-de.js index 9551e010cb..53f9b53ad1 100644 --- a/src/main/webapp/scripts/dataacquisitionprojectmanagement/configuration/translations-de.js +++ b/src/main/webapp/scripts/dataacquisitionprojectmanagement/configuration/translations-de.js @@ -147,7 +147,8 @@ angular.module('metadatamanagementApp').config( }, 'tabs': { 'status': 'Status', - 'config': 'Einstellungen' + 'config': 'Einstellungen', + 'versions': 'Versionen' }, 'requirements': { 'header': 'Erwartete Metadaten', @@ -183,6 +184,23 @@ angular.module('metadatamanagementApp').config( 'takeback-dialog': { 'title': 'Projekt zurückziehen', 'text': 'Möchten Sie das Projekt wirklich von der Gruppe Datengeber zurückziehen?' + }, + 'versions': { + 'header': 'Liste aller Projektversionen (Schattenkopien):', + 'confirm-hide' : { + 'title': 'Freigabe von Version {{version}} des Projektes {{id}} zurücknehmen?', + 'content': 'Sind Sie sicher, dass Sie die Freigabe der Version {{version}} des Projektes {{id}} zurücknehmen möchten? Datennutzer können diese Version dann nicht mehr sehen.' + }, + 'confirm-unhide' : { + 'title': 'Version {{version}} des Projektes {{id}} wieder freigeben?', + 'content': 'Sind Sie sicher, dass Sie die Version {{version}} des Projektes {{id}} wieder freigeben möchten? Datennutzer können diese Version dann wieder sehen.' + }, + 'hiding-toast': 'Die Version {{version}} des Projektes {{id}} wird in ca. 10 Minuten nur noch für angemeldete Benutzer sichtbar sein!', + 'unhiding-toast': 'Die Version {{version}} des Projektes {{id}} wird in ca. 10 Minuten wieder für alle Benutzer sichtbar sein!', + 'button': { + 'hide-shadow': 'Diese Version ist aktuell freigeben. Klicken Sie hier, um die Freigabe zurückzunehmen!', + 'unhide-shadow': 'Diese Version ist aktuell nicht für alle Benutzer freigegeben. Klicken Sie hier, um die Version wieder freizugeben!' + } } }, 'project-overview': { diff --git a/src/main/webapp/scripts/dataacquisitionprojectmanagement/configuration/translations-en.js b/src/main/webapp/scripts/dataacquisitionprojectmanagement/configuration/translations-en.js index 9ed91fe0bc..1af0e24847 100644 --- a/src/main/webapp/scripts/dataacquisitionprojectmanagement/configuration/translations-en.js +++ b/src/main/webapp/scripts/dataacquisitionprojectmanagement/configuration/translations-en.js @@ -148,7 +148,8 @@ angular.module('metadatamanagementApp').config( }, 'tabs': { 'status': 'Status', - 'config': 'Settings' + 'config': 'Settings', + 'versions': 'Versions' }, 'requirements': { 'header': 'Expected Metadata', @@ -184,6 +185,23 @@ angular.module('metadatamanagementApp').config( 'takeback-dialog': { 'title': 'Take back project', 'text': 'Do you really want to withdraw this project from the data provider group?' + }, + 'versions': { + 'header': 'List of all Project Versions (Shadow Copies):', + 'confirm-hide' : { + 'title': 'Revoke release of version {{version}} of the project {{id}}?', + 'content': 'Are you sure you want to revoke the release of version {{version}} of the project {{id}}? Data users will no longer be able to see this version.' + }, + 'confirm-unhide' : { + 'title': 'Release version {{version}} of the project {{id}} again?', + 'content': 'Are you sure you want to release the version {{version}} of the project {{id}} again? Data users will then be able to see this version again.' + }, + 'hiding-toast': 'The version {{version}} of the project {{id}} will be visible only for registered users in about 10 minutes!', + 'unhiding-toast': 'The version {{version}} of the project {{id}} will be visible again for all users in about 10 minutes!', + 'button': { + 'hide-shadow': 'This version is currently released. Click here to revoke the release!', + 'unhide-shadow': 'This version is currently not released for all users. Click here to release the version again!' + } } }, 'project-overview': { diff --git a/src/main/webapp/scripts/dataacquisitionprojectmanagement/directives/project-cockpit-versions.directive.js b/src/main/webapp/scripts/dataacquisitionprojectmanagement/directives/project-cockpit-versions.directive.js new file mode 100644 index 0000000000..2ee6c986e5 --- /dev/null +++ b/src/main/webapp/scripts/dataacquisitionprojectmanagement/directives/project-cockpit-versions.directive.js @@ -0,0 +1,151 @@ +/* global _, bowser */ + +'use strict'; + +angular.module('metadatamanagementApp') + .directive('projectCockpitVersions', function(Principal, CommonDialogsService, + DataAcquisitionProjectShadowsResource, SimpleMessageToastService, + DataAcquisitionProjectShadowsHideResource, $timeout, + DataAcquisitionProjectShadowsActionResource, + DataAcquisitionProjectResource) { + return { + restrict: 'E', + templateUrl: 'scripts/dataacquisitionprojectmanagement/directives/' + + 'project-cockpit-versions.html.tmpl', + scope: { + project: '=' + }, + replace: true, + controllerAs: 'ctrl', + controller: function($scope) { + this.project = $scope.project; + $scope.bowser = bowser; + }, + /* jshint -W098 */ + link: function($scope, elem, attrs, ctrl) { + $scope.$on('$destroy', function() { + delete ctrl.shadows; + }); + + var watchAction = function(shadow) { + if (ctrl.shadows && _.findIndex(ctrl.shadows, function(s) { + return s.id === shadow.id;}) > -1) { + $timeout(function() { + DataAcquisitionProjectShadowsActionResource.get({ + id: shadow.masterId, + version: shadow.release.version + }).$promise.then(function(result) { + if (result.action) { + shadow.inProgress = true; + watchAction(shadow); + } else { + DataAcquisitionProjectResource.get({id: shadow.id}) + .$promise.then(function(result) { + angular.copy(result, shadow); + }); + } + }); + }, 10000); + } + }; + + var loadShadows = function(pageNumber) { + DataAcquisitionProjectShadowsResource.get({ + id: ctrl.project.id, + sort: 'release.version,DESC', + page: pageNumber || 0 + }) + .$promise.then(function(page) { + ctrl.shadows = page.content; + ctrl.page = page; + ctrl.page.number++; + ctrl.shadows.forEach(function(shadow) { + DataAcquisitionProjectShadowsActionResource.get({ + id: shadow.masterId, + version: shadow.release.version + }).$promise.then(function(result) { + if (result.action) { + shadow.inProgress = true; + watchAction(shadow); + } + }); + }); + }); + }; + + loadShadows(); + + ctrl.onPageChanged = function() { + loadShadows(ctrl.page.number - 1); + }; + + var isNotAssignedPublisher = function() { + var loginName = Principal.loginName(); + var publishers = _.get(ctrl.project, 'configuration.publishers', []); + return publishers.indexOf(loginName) === -1; + }; + + var showConfirmDialog = function(action, shadow, event) { + var translationPrefix = 'data-acquisition-project-management.' + + 'project-cockpit.versions.confirm-'; + return CommonDialogsService.showConfirmDialog( + translationPrefix + action + '.title', { + version: shadow.release.version, + id: shadow.masterId + }, + translationPrefix + action + '.content', { + version: shadow.release.version, + id: shadow.masterId + }, + event + ); + }; + + ctrl.isShadowStateChangeDisabled = function() { + return !ctrl.isUserPublisher() || isNotAssignedPublisher(); + }; + + ctrl.isUserPublisher = function() { + return Principal.hasAuthority('ROLE_PUBLISHER'); + }; + + ctrl.hide = function(shadow, event) { + showConfirmDialog('hide', shadow, event).then(function() { + DataAcquisitionProjectShadowsHideResource.hide({ + id: shadow.masterId, + version: shadow.release.version + }).$promise.then(function() { + SimpleMessageToastService + .openSimpleMessageToast( + 'data-acquisition-project-management.project-cockpit.' + + 'versions.hiding-toast', { + id: shadow.masterId, + version: shadow.release.version + }); + shadow.inProgress = true; + watchAction(shadow); + }); + }); + }; + + ctrl.unhide = function(shadow, event) { + showConfirmDialog('unhide', shadow, event).then(function() { + DataAcquisitionProjectShadowsHideResource.unhide({ + id: shadow.masterId, + version: shadow.release.version + }).$promise.then(function() { + SimpleMessageToastService + .openSimpleMessageToast( + 'data-acquisition-project-management.project-cockpit.' + + 'versions.unhiding-toast', { + id: shadow.masterId, + version: shadow.release.version + }); + shadow.inProgress = true; + watchAction(shadow); + }); + }); + }; + } + }; + }); diff --git a/src/main/webapp/scripts/dataacquisitionprojectmanagement/directives/project-cockpit-versions.html.tmpl b/src/main/webapp/scripts/dataacquisitionprojectmanagement/directives/project-cockpit-versions.html.tmpl new file mode 100644 index 0000000000..a04d172385 --- /dev/null +++ b/src/main/webapp/scripts/dataacquisitionprojectmanagement/directives/project-cockpit-versions.html.tmpl @@ -0,0 +1,36 @@ +
+
{{'data-acquisition-project-management.project-cockpit.versions.header' | translate}}
+ + +
+ + + {{('study-management.detail.label.version' | translate) + ' ' + shadow.release.version}} + {{'(' + ('study-management.detail.label.published-at' | translate) + ' ' + (shadow.release.firstDate + 'Z' | date:'mediumDate') + ')'}} + + + + + + visibility_on + + {{'data-acquisition-project-management.project-cockpit.versions.button.hide-shadow' | translate}} + + + + visibility_off + + {{'data-acquisition-project-management.project-cockpit.versions.button.unhide-shadow' | translate}} + + + + +
+
+
+
    +
+
+
+
diff --git a/src/main/webapp/scripts/dataacquisitionprojectmanagement/directives/user-list.directive.js b/src/main/webapp/scripts/dataacquisitionprojectmanagement/directives/user-list.directive.js index 63c581b830..c419539c4d 100644 --- a/src/main/webapp/scripts/dataacquisitionprojectmanagement/directives/user-list.directive.js +++ b/src/main/webapp/scripts/dataacquisitionprojectmanagement/directives/user-list.directive.js @@ -1,4 +1,4 @@ -/* global _, $ */ +/* global _, $, bowser */ 'use strict'; @@ -21,6 +21,7 @@ angular.module('metadatamanagementApp') this.group = $scope.group; this.isPublisher = $scope.isPublisher; this.project = $scope.project; + $scope.bowser = bowser; }, link: function($scope, elem, attrs, ctrl) { // jshint ignore:line ctrl.disabled = !ctrl.isPublisher && diff --git a/src/main/webapp/scripts/dataacquisitionprojectmanagement/resources/dataAcquisitionProjectShadows.resource.js b/src/main/webapp/scripts/dataacquisitionprojectmanagement/resources/dataAcquisitionProjectShadows.resource.js new file mode 100644 index 0000000000..74a88e9493 --- /dev/null +++ b/src/main/webapp/scripts/dataacquisitionprojectmanagement/resources/dataAcquisitionProjectShadows.resource.js @@ -0,0 +1,13 @@ +'use strict'; +angular.module('metadatamanagementApp') + .factory('DataAcquisitionProjectShadowsResource', + function($resource) { + return $resource( + '/api/data-acquisition-projects/:id/shadows', { + id: '@id' + }, { + 'get': { + method: 'GET' + } + }); + }); diff --git a/src/main/webapp/scripts/dataacquisitionprojectmanagement/resources/dataAcquisitionProjectShadowsAction.resource.js b/src/main/webapp/scripts/dataacquisitionprojectmanagement/resources/dataAcquisitionProjectShadowsAction.resource.js new file mode 100644 index 0000000000..669dfcf160 --- /dev/null +++ b/src/main/webapp/scripts/dataacquisitionprojectmanagement/resources/dataAcquisitionProjectShadowsAction.resource.js @@ -0,0 +1,14 @@ +'use strict'; +angular.module('metadatamanagementApp') + .factory('DataAcquisitionProjectShadowsActionResource', + function($resource) { + return $resource( + '/api/data-acquisition-projects/:id/shadows/:version/action', { + id: '@id', + version: '@version' + }, { + 'get': { + method: 'GET' + } + }); + }); diff --git a/src/main/webapp/scripts/dataacquisitionprojectmanagement/resources/dataAcquisitionProjectShadowsHide.resource.js b/src/main/webapp/scripts/dataacquisitionprojectmanagement/resources/dataAcquisitionProjectShadowsHide.resource.js new file mode 100644 index 0000000000..14ab86c581 --- /dev/null +++ b/src/main/webapp/scripts/dataacquisitionprojectmanagement/resources/dataAcquisitionProjectShadowsHide.resource.js @@ -0,0 +1,17 @@ +'use strict'; +angular.module('metadatamanagementApp') + .factory('DataAcquisitionProjectShadowsHideResource', + function($resource) { + return $resource( + '/api/data-acquisition-projects/:id/shadows/:version/hidden', { + id: '@id', + version: '@version' + }, { + 'hide': { + method: 'POST' + }, + 'unhide': { + method: 'DELETE' + } + }); + }); diff --git a/src/main/webapp/scripts/dataacquisitionprojectmanagement/views/project-cockpit.controller.js b/src/main/webapp/scripts/dataacquisitionprojectmanagement/views/project-cockpit.controller.js index 46e5fb95fe..02ad3d7ef4 100644 --- a/src/main/webapp/scripts/dataacquisitionprojectmanagement/views/project-cockpit.controller.js +++ b/src/main/webapp/scripts/dataacquisitionprojectmanagement/views/project-cockpit.controller.js @@ -115,6 +115,7 @@ angular.module('metadatamanagementApp').controller('ProjectCockpitController', switch (newValue.tab) { case 'status': return 0; case 'config': return 1; + case 'versions': return 2; default: return 0; } })(); @@ -123,9 +124,8 @@ angular.module('metadatamanagementApp').controller('ProjectCockpitController', $scope.onTabSelect = function(tab) { $state.go('project-cockpit', {tab: tab}); - if (tab === 'config') { - $scope.shareButtonShown = false; - } else if (tab === 'status') { + $scope.shareButtonShown = false; + if (tab === 'status') { $scope.shareButtonShown = true; } }; @@ -134,6 +134,7 @@ angular.module('metadatamanagementApp').controller('ProjectCockpitController', switch ($state.params.tab) { case 'status': return 0; case 'config': return 1; + case 'versions': return 2; default: return 0; } })(); diff --git a/src/main/webapp/scripts/dataacquisitionprojectmanagement/views/project-cockpit.html.tmpl b/src/main/webapp/scripts/dataacquisitionprojectmanagement/views/project-cockpit.html.tmpl index 56c58f928f..cae1d73000 100644 --- a/src/main/webapp/scripts/dataacquisitionprojectmanagement/views/project-cockpit.html.tmpl +++ b/src/main/webapp/scripts/dataacquisitionprojectmanagement/views/project-cockpit.html.tmpl @@ -27,6 +27,15 @@ + + + history + {{'data-acquisition-project-management.project-cockpit.tabs.versions' | translate}} + + + + + diff --git a/src/main/webapp/scripts/datasetmanagement/views/data-set-edit-or-create.html.tmpl b/src/main/webapp/scripts/datasetmanagement/views/data-set-edit-or-create.html.tmpl index cc5f2acbf3..4d99142a30 100644 --- a/src/main/webapp/scripts/datasetmanagement/views/data-set-edit-or-create.html.tmpl +++ b/src/main/webapp/scripts/datasetmanagement/views/data-set-edit-or-create.html.tmpl @@ -332,7 +332,7 @@ {{'data-set-management.edit.open-choose-previous-version-tooltip' | translate}} - undo + history
diff --git a/src/main/webapp/scripts/instrumentmanagement/views/instrument-edit-or-create.html.tmpl b/src/main/webapp/scripts/instrumentmanagement/views/instrument-edit-or-create.html.tmpl index dd6fb0332b..3fc44ef98e 100644 --- a/src/main/webapp/scripts/instrumentmanagement/views/instrument-edit-or-create.html.tmpl +++ b/src/main/webapp/scripts/instrumentmanagement/views/instrument-edit-or-create.html.tmpl @@ -266,7 +266,7 @@ {{'instrument-management.edit.open-choose-previous-version-tooltip' | translate}} - undo + history diff --git a/src/main/webapp/scripts/searchmanagement/services/searchHelper.service.js b/src/main/webapp/scripts/searchmanagement/services/searchHelper.service.js index 3029c941b5..b7012dee09 100644 --- a/src/main/webapp/scripts/searchmanagement/services/searchHelper.service.js +++ b/src/main/webapp/scripts/searchmanagement/services/searchHelper.service.js @@ -342,6 +342,9 @@ angular.module('metadatamanagementApp').factory( 'bool': { 'must': [{ 'term': {'shadow': true} + }, + { + 'term': {'hidden': false} }] } }; @@ -416,6 +419,14 @@ angular.module('metadatamanagementApp').factory( } }; + if (!Principal.loginName()) { + query.body.query.constant_score.filter.bool.must.push({ + 'term': { + 'hidden': false + } + }); + } + if (version) { query.body.query.constant_score.filter.bool.must.push({ 'term': { diff --git a/src/main/webapp/scripts/studymanagement/views/study-edit-or-create.html.tmpl b/src/main/webapp/scripts/studymanagement/views/study-edit-or-create.html.tmpl index c462e913c2..5c2c66fbab 100644 --- a/src/main/webapp/scripts/studymanagement/views/study-edit-or-create.html.tmpl +++ b/src/main/webapp/scripts/studymanagement/views/study-edit-or-create.html.tmpl @@ -395,7 +395,7 @@ {{'study-management.edit.open-choose-previous-version-tooltip' | translate}} - undo + history diff --git a/src/main/webapp/scripts/surveymanagement/views/survey-edit-or-create.html.tmpl b/src/main/webapp/scripts/surveymanagement/views/survey-edit-or-create.html.tmpl index 7dfcfc6de1..240551cf7d 100644 --- a/src/main/webapp/scripts/surveymanagement/views/survey-edit-or-create.html.tmpl +++ b/src/main/webapp/scripts/surveymanagement/views/survey-edit-or-create.html.tmpl @@ -399,7 +399,7 @@ {{'survey-management.edit.open-choose-previous-version-tooltip' | translate}} - undo + history From 592be0c1332e469d264863619111d22ff38f0abb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Reitmann?= Date: Tue, 10 Sep 2019 17:35:17 +0200 Subject: [PATCH 04/16] #2278 add fallback to all shadow details --- .../configuration/translations-de.js | 18 ++++---- .../configuration/translations-en.js | 18 ++++---- .../project-cockpit-versions.html.tmpl | 3 +- .../outdatedVersionNotifierService.js | 26 ++++++++--- .../configuration/dataSet.js | 37 ++++++++++++++-- .../configuration/translations-de.js | 2 +- .../views/dataSet-detail.html.tmpl | 6 +-- .../configuration/instrument.js | 35 +++++++++++++-- .../configuration/translations-de.js | 1 + .../configuration/translations-en.js | 1 + .../views/instrument-detail.html.tmpl | 6 +-- .../configuration/question.js | 43 +++++++++++++++---- .../views/question-detail.html.tmpl | 8 ++-- .../studymanagement/configuration/study.js | 2 +- .../configuration/translations-de.js | 1 - .../configuration/translations-en.js | 1 - .../views/study-detail.controller.js | 16 +------ .../views/study-detail.html.tmpl | 10 ++--- .../surveymanagement/configuration/survey.js | 35 +++++++++++++-- .../views/survey-detail.html.tmpl | 8 ++-- .../configuration/variable.js | 34 +++++++++++++-- .../views/variable-detail.html.tmpl | 8 ++-- 22 files changed, 233 insertions(+), 86 deletions(-) diff --git a/src/main/webapp/scripts/dataacquisitionprojectmanagement/configuration/translations-de.js b/src/main/webapp/scripts/dataacquisitionprojectmanagement/configuration/translations-de.js index 53f9b53ad1..4e1031e41b 100644 --- a/src/main/webapp/scripts/dataacquisitionprojectmanagement/configuration/translations-de.js +++ b/src/main/webapp/scripts/dataacquisitionprojectmanagement/configuration/translations-de.js @@ -187,19 +187,20 @@ angular.module('metadatamanagementApp').config( }, 'versions': { 'header': 'Liste aller Projektversionen (Schattenkopien):', + 'no-shadows': 'Das Projekt wurde noch nicht freigegeben.', 'confirm-hide' : { - 'title': 'Freigabe von Version {{version}} des Projektes {{id}} zurücknehmen?', - 'content': 'Sind Sie sicher, dass Sie die Freigabe der Version {{version}} des Projektes {{id}} zurücknehmen möchten? Datennutzer können diese Version dann nicht mehr sehen.' + 'title': 'Freigegebene Version {{version}} des Projektes {{id}} verstecken?', + 'content': 'Sind Sie sicher, dass Sie die freigegebene Version {{version}} des Projektes {{id}} verstecken möchten? Datennutzer können diese Version dann nicht mehr sehen.' }, 'confirm-unhide' : { - 'title': 'Version {{version}} des Projektes {{id}} wieder freigeben?', - 'content': 'Sind Sie sicher, dass Sie die Version {{version}} des Projektes {{id}} wieder freigeben möchten? Datennutzer können diese Version dann wieder sehen.' + 'title': 'Version {{version}} des Projektes {{id}} wieder für alle sichtbar machen?', + 'content': 'Sind Sie sicher, dass Sie die Version {{version}} des Projektes {{id}} wieder für alle Nutzer sichtbar machen möchten?' }, 'hiding-toast': 'Die Version {{version}} des Projektes {{id}} wird in ca. 10 Minuten nur noch für angemeldete Benutzer sichtbar sein!', 'unhiding-toast': 'Die Version {{version}} des Projektes {{id}} wird in ca. 10 Minuten wieder für alle Benutzer sichtbar sein!', 'button': { - 'hide-shadow': 'Diese Version ist aktuell freigeben. Klicken Sie hier, um die Freigabe zurückzunehmen!', - 'unhide-shadow': 'Diese Version ist aktuell nicht für alle Benutzer freigegeben. Klicken Sie hier, um die Version wieder freizugeben!' + 'hide-shadow': 'Diese Version ist aktuell für alle Benutzer sichtbar. Klicken Sie hier, um die Version zu verstecken!', + 'unhide-shadow': 'Diese Version ist aktuell nicht für alle Benutzer sichtbar. Klicken Sie hier, um die Version wieder sichtbar zu machen!' } } }, @@ -227,8 +228,9 @@ angular.module('metadatamanagementApp').config( 'current': 'Klicken, um die Projekte auf Seite {{number}} anzuzeigen' } }, - 'outdated-version-alert': 'Sie betrachten eine veraltete Version ({{oldVersion}}). Hier geht es zur aktuellen Version ({{newVersion}})!', - 'not-master-alert': 'Sie betrachten eine Schattenkopie ({{version}}). Hier geht es zur aktuellen Version!' + 'outdated-version-alert': 'Sie betrachten eine veraltete Version ({{oldVersion}}) dieser Seite. Hier geht es zur aktuellen Version ({{newVersion}}).', + 'outdated-version-not-found-alert': 'Ihr Link verweist auf eine ältere Version ({{oldVersion}}) dieser Seite. Hier wird die aktuelle Version ({{newVersion}}) dargestellt.', + 'not-master-alert': 'Sie betrachten eine {{hidden?"versteckte":""}} Schattenkopie ({{version}}). Hier geht es zur aktuellen Version!' } //jscs:enable }; diff --git a/src/main/webapp/scripts/dataacquisitionprojectmanagement/configuration/translations-en.js b/src/main/webapp/scripts/dataacquisitionprojectmanagement/configuration/translations-en.js index 1af0e24847..3d07af2230 100644 --- a/src/main/webapp/scripts/dataacquisitionprojectmanagement/configuration/translations-en.js +++ b/src/main/webapp/scripts/dataacquisitionprojectmanagement/configuration/translations-en.js @@ -188,19 +188,20 @@ angular.module('metadatamanagementApp').config( }, 'versions': { 'header': 'List of all Project Versions (Shadow Copies):', + 'no-shadows': 'The project has not been released yet.', 'confirm-hide' : { - 'title': 'Revoke release of version {{version}} of the project {{id}}?', - 'content': 'Are you sure you want to revoke the release of version {{version}} of the project {{id}}? Data users will no longer be able to see this version.' + 'title': 'Hide {{version}} of the project {{id}}?', + 'content': 'Are you sure you want to hide version {{version}} of the project {{id}} from the public user? Data users will no longer be able to see this version.' }, 'confirm-unhide' : { - 'title': 'Release version {{version}} of the project {{id}} again?', - 'content': 'Are you sure you want to release the version {{version}} of the project {{id}} again? Data users will then be able to see this version again.' + 'title': 'Make version {{version}} of the project {{id}} available again?', + 'content': 'Are you sure you want to make version {{version}} of the project {{id}} availabl for all users again? Data users will then be able to see this version again.' }, 'hiding-toast': 'The version {{version}} of the project {{id}} will be visible only for registered users in about 10 minutes!', 'unhiding-toast': 'The version {{version}} of the project {{id}} will be visible again for all users in about 10 minutes!', 'button': { - 'hide-shadow': 'This version is currently released. Click here to revoke the release!', - 'unhide-shadow': 'This version is currently not released for all users. Click here to release the version again!' + 'hide-shadow': 'This version is currently visible for all users. Click here to hide this version!', + 'unhide-shadow': 'This version is currently not visible for all users. Click here to make it availabe for all users!' } } }, @@ -228,8 +229,9 @@ angular.module('metadatamanagementApp').config( 'current': 'Click to show projects on page {{number}}' } }, - 'outdated-version-alert': 'This is an outdated document version ({{oldVersion}}). Click here to open the current version ({{newVersion}})!', - 'not-master-alert': 'This is a shadow copy ({{version}}). Click here to open the current version!' + 'outdated-version-alert': 'This is an outdated page version ({{oldVersion}}). Click here to open the current version ({{newVersion}})!', + 'outdated-version-not-found-alert': 'Your link refers to a former version ({{oldVersion}}) of this page. This is the current version ({{newVersion}}).', + 'not-master-alert': 'This is a {{hidden?"hidden":""}} shadow copy ({{version}}). Click here to open the current version!' } //jscs:enable }; diff --git a/src/main/webapp/scripts/dataacquisitionprojectmanagement/directives/project-cockpit-versions.html.tmpl b/src/main/webapp/scripts/dataacquisitionprojectmanagement/directives/project-cockpit-versions.html.tmpl index a04d172385..60352442d0 100644 --- a/src/main/webapp/scripts/dataacquisitionprojectmanagement/directives/project-cockpit-versions.html.tmpl +++ b/src/main/webapp/scripts/dataacquisitionprojectmanagement/directives/project-cockpit-versions.html.tmpl @@ -27,10 +27,11 @@ -
+
+
{{'data-acquisition-project-management.project-cockpit.versions.no-shadows' | translate}}
diff --git a/src/main/webapp/scripts/dataacquisitionprojectmanagement/services/outdatedVersionNotifierService.js b/src/main/webapp/scripts/dataacquisitionprojectmanagement/services/outdatedVersionNotifierService.js index 4e6e9e7db5..212e40ad96 100644 --- a/src/main/webapp/scripts/dataacquisitionprojectmanagement/services/outdatedVersionNotifierService.js +++ b/src/main/webapp/scripts/dataacquisitionprojectmanagement/services/outdatedVersionNotifierService.js @@ -1,8 +1,9 @@ -/* globals _ */ +/* globals _, bowser */ 'use strict'; angular.module('metadatamanagementApp').service('OutdatedVersionNotifier', - function($state, SimpleMessageToastService, $document, $mdToast, Principal) { + function($state, SimpleMessageToastService, $document, $mdToast, Principal, + $location) { var createHref = function(item) { return $state.href($state.current.name, { @@ -34,20 +35,22 @@ angular.module('metadatamanagementApp').service('OutdatedVersionNotifier', '-project-management.outdated-version-alert', messageParams); }; - var showLoggedInUserMessage = function(href, version) { + var showLoggedInUserMessage = function(href, version, hidden) { var messageParams = { href: href, - version: version + version: version, + hidden: hidden }; SimpleMessageToastService.openAlertMessageToast('data-acquisition' + '-project-management.not-master-alert', messageParams); }; var checkVersionAndNotify = function(item, fetchFn) { + var versionFromUrl = $location.search().version; if (Principal.loginName() && item.shadow) { var version = _.get(item, 'release.version'); var href = createMasterRef(item); - showLoggedInUserMessage(href, version); + showLoggedInUserMessage(href, version, item.hidden); } else if (item.shadow && angular.isDefined(item.successorId)) { fetchFn().promise.then(function(result) { var oldVersion = _.get(item, 'release.version'); @@ -55,11 +58,22 @@ angular.module('metadatamanagementApp').service('OutdatedVersionNotifier', var href = createHref(result); showPublicUserMessage(href, oldVersion, newVersion); }); + } else if (item.shadow && versionFromUrl && bowser.compareVersions( + [versionFromUrl, item.release.version]) === -1) { + SimpleMessageToastService.openAlertMessageToast('data-acquisition' + + '-project-management.outdated-version-not-found-alert', + { + oldVersion: versionFromUrl, + newVersion: item.release.version + }); } else { if ($document.find('[data-translate="data-acquisition' + '-project-management.outdated-version-alert"]').length > 0 || $document.find('[data-translate="data-acquisition' + - '-project-management.not-master-alert"]').length > 0) { + '-project-management.not-master-alert"]').length > 0 || + $document.find('[data-translate="data-acquisition' + + '-project-management.outdated-version-not-found-alert"]') + .length > 0) { $mdToast.hide(); } } diff --git a/src/main/webapp/scripts/datasetmanagement/configuration/dataSet.js b/src/main/webapp/scripts/datasetmanagement/configuration/dataSet.js index 5658a4e104..aee3c7f8b1 100644 --- a/src/main/webapp/scripts/datasetmanagement/configuration/dataSet.js +++ b/src/main/webapp/scripts/datasetmanagement/configuration/dataSet.js @@ -2,6 +2,30 @@ angular.module('metadatamanagementApp') .config(function($stateProvider, $urlRouterProvider) { + var loadShadowCopy = function(DataSetSearchService, + SimpleMessageToastService, id, version) { + var loadLatestShadowCopyFallback = function() { + return DataSetSearchService.findShadowByIdAndVersion(id, null) + .promise.then(function(result) { + if (result) { + return result; + } else { + SimpleMessageToastService.openAlertMessageToast( + 'data-set-management.detail.not-found', {id: id}); + return null; + } + }); + }; + return DataSetSearchService.findShadowByIdAndVersion(id, version) + .promise.then(function(result) { + if (result) { + return result; + } else { + return loadLatestShadowCopyFallback(); + } + }); + }; + $urlRouterProvider.when('/de/data-sets/', '/de/error'); $urlRouterProvider.when('/en/data-sets/', '/en/error'); $stateProvider @@ -23,13 +47,18 @@ angular.module('metadatamanagementApp') } }, resolve: { - entity: ['$stateParams', 'DataSetSearchService', 'Principal', - function($stateParams, DataSetSearchService, Principal) { + entity: ['$stateParams', 'DataSetSearchService', 'Principal', '$q', + 'SimpleMessageToastService', + function($stateParams, DataSetSearchService, Principal, $q, + SimpleMessageToastService) { if (Principal.loginName() && !$stateParams.version) { return DataSetSearchService.findOneById($stateParams.id); } else { - return DataSetSearchService.findShadowByIdAndVersion( - $stateParams.id, $stateParams.version); + var deferred = $q.defer(); + loadShadowCopy(DataSetSearchService, + SimpleMessageToastService, $stateParams.id, + $stateParams.version).then(deferred.resolve, deferred.reject); + return deferred; } } ] diff --git a/src/main/webapp/scripts/datasetmanagement/configuration/translations-de.js b/src/main/webapp/scripts/datasetmanagement/configuration/translations-de.js index aaff93862e..f81a12cd03 100644 --- a/src/main/webapp/scripts/datasetmanagement/configuration/translations-de.js +++ b/src/main/webapp/scripts/datasetmanagement/configuration/translations-de.js @@ -87,7 +87,7 @@ angular.module('metadatamanagementApp').config( } }, 'title': '{{ description }} ({{ dataSetId }})', - 'not-found': 'Die id {{id}} referenziert auf einen unbekannten Datensatz', + 'not-found': 'Die id {{id}} referenziert auf einen unbekannten Datensatz.', 'not-found-references': 'Die id {{id}} hat keine Referenzen auf Datensätze.', 'content': { 'true': 'Klicken zum maximieren', diff --git a/src/main/webapp/scripts/datasetmanagement/views/dataSet-detail.html.tmpl b/src/main/webapp/scripts/datasetmanagement/views/dataSet-detail.html.tmpl index 87e725e7d2..95c4acfdf2 100644 --- a/src/main/webapp/scripts/datasetmanagement/views/dataSet-detail.html.tmpl +++ b/src/main/webapp/scripts/datasetmanagement/views/dataSet-detail.html.tmpl @@ -48,7 +48,7 @@ {{'study-management.detail.label.study' | translate }}: {{'global.messages.error.unavailable' | translate}}
- + {{'variable-management.detail.label.variable' | translate }}: diff --git a/src/main/webapp/scripts/instrumentmanagement/configuration/instrument.js b/src/main/webapp/scripts/instrumentmanagement/configuration/instrument.js index a560d35808..703a6f92ce 100644 --- a/src/main/webapp/scripts/instrumentmanagement/configuration/instrument.js +++ b/src/main/webapp/scripts/instrumentmanagement/configuration/instrument.js @@ -2,6 +2,30 @@ angular.module('metadatamanagementApp') .config(function($stateProvider, $urlRouterProvider) { + var loadShadowCopy = function(InstrumentSearchService, + SimpleMessageToastService, id, version) { + var loadLatestShadowCopyFallback = function() { + return InstrumentSearchService.findShadowByIdAndVersion(id, null) + .promise.then(function(result) { + if (result) { + return result; + } else { + SimpleMessageToastService.openAlertMessageToast( + 'instrument-management.detail.not-found', {id: id}); + return null; + } + }); + }; + return InstrumentSearchService.findShadowByIdAndVersion(id, version) + .promise.then(function(result) { + if (result) { + return result; + } else { + return loadLatestShadowCopyFallback(); + } + }); + }; + $urlRouterProvider.when('/de/instruments/', '/de/error'); $urlRouterProvider.when('/en/instruments/', '/en/error'); $stateProvider @@ -24,12 +48,17 @@ angular.module('metadatamanagementApp') }, resolve: { entity: ['$stateParams', 'InstrumentSearchService', 'Principal', - function($stateParams, InstrumentSearchService, Principal) { + 'SimpleMessageToastService', '$q', + function($stateParams, InstrumentSearchService, Principal, + SimpleMessageToastService, $q) { if (Principal.loginName() && !$stateParams.version) { return InstrumentSearchService.findOneById($stateParams.id); } else { - return InstrumentSearchService.findShadowByIdAndVersion( - $stateParams.id, $stateParams.version); + var deferred = $q.defer(); + loadShadowCopy(InstrumentSearchService, + SimpleMessageToastService, $stateParams.id, + $stateParams.version).then(deferred.resolve, deferred.reject); + return deferred; } } ] diff --git a/src/main/webapp/scripts/instrumentmanagement/configuration/translations-de.js b/src/main/webapp/scripts/instrumentmanagement/configuration/translations-de.js index 31ce659526..f742de83fc 100644 --- a/src/main/webapp/scripts/instrumentmanagement/configuration/translations-de.js +++ b/src/main/webapp/scripts/instrumentmanagement/configuration/translations-de.js @@ -64,6 +64,7 @@ angular.module('metadatamanagementApp').config( } }, 'page-title': '{{ description }} ({{ instrumentId }})', + 'not-found': 'Die id {{id}} referenziert auf ein unbekanntes Instrument.', 'not-released-toast': 'Das Instrument "{{ id }}" wurde noch nicht für alle Benutzer freigegeben!', 'tooltips': { 'surveys': { diff --git a/src/main/webapp/scripts/instrumentmanagement/configuration/translations-en.js b/src/main/webapp/scripts/instrumentmanagement/configuration/translations-en.js index 86af5735e3..d5a737274b 100644 --- a/src/main/webapp/scripts/instrumentmanagement/configuration/translations-en.js +++ b/src/main/webapp/scripts/instrumentmanagement/configuration/translations-en.js @@ -63,6 +63,7 @@ angular.module('metadatamanagementApp').config(function($translateProvider) { } }, 'page-title': '{{ description }} ({{ instrumentId }})', + 'not-found': 'The {{id}} references to an unknown Instrument.', 'not-released-toast': 'Instrument "{{ id }}" has not yet been released to all users!', 'tooltips': { 'surveys': { diff --git a/src/main/webapp/scripts/instrumentmanagement/views/instrument-detail.html.tmpl b/src/main/webapp/scripts/instrumentmanagement/views/instrument-detail.html.tmpl index edcd7035ab..22de3464fa 100644 --- a/src/main/webapp/scripts/instrumentmanagement/views/instrument-detail.html.tmpl +++ b/src/main/webapp/scripts/instrumentmanagement/views/instrument-detail.html.tmpl @@ -52,7 +52,7 @@ {{'study-management.detail.label.study' | translate }}: {{'global.messages.error.unavailable' | translate}}
- + {{'question-management.detail.label.question' | translate }}: diff --git a/src/main/webapp/scripts/questionmanagement/configuration/question.js b/src/main/webapp/scripts/questionmanagement/configuration/question.js index c680f5fe25..d380f15373 100644 --- a/src/main/webapp/scripts/questionmanagement/configuration/question.js +++ b/src/main/webapp/scripts/questionmanagement/configuration/question.js @@ -2,6 +2,29 @@ angular.module('metadatamanagementApp') .config(function($stateProvider, $urlRouterProvider) { + var loadShadowCopy = function(QuestionSearchService, + SimpleMessageToastService, id, version) { + var loadLatestShadowCopyFallback = function() { + return QuestionSearchService.findShadowByIdAndVersion(id, null) + .promise.then(function(result) { + if (result) { + return result; + } else { + SimpleMessageToastService.openAlertMessageToast( + 'question-management.detail.not-found', {id: id}); + return null; + } + }); + }; + return QuestionSearchService.findShadowByIdAndVersion(id, version) + .promise.then(function(result) { + if (result) { + return result; + } else { + return loadLatestShadowCopyFallback(); + } + }); + }; $urlRouterProvider.when('/de/questions/', '/de/error'); $urlRouterProvider.when('/en/questions/', '/en/error'); $stateProvider @@ -24,15 +47,19 @@ angular.module('metadatamanagementApp') }, resolve: { entity: ['$stateParams', 'QuestionSearchService', 'Principal', - function($stateParams, QuestionSearchService, Principal) { - if (Principal.loginName() && !$stateParams.version) { - return QuestionSearchService.findOneById($stateParams.id); - } else { - return QuestionSearchService.findShadowByIdAndVersion( - $stateParams.id, $stateParams.version); - } + 'SimpleMessageToastService', '$q', + function($stateParams, QuestionSearchService, Principal, + SimpleMessageToastService, $q) { + if (Principal.loginName() && !$stateParams.version) { + return QuestionSearchService.findOneById($stateParams.id); + } else { + var deferred = $q.defer(); + loadShadowCopy(QuestionSearchService, + SimpleMessageToastService, $stateParams.id, + $stateParams.version).then(deferred.resolve, deferred.reject); + return deferred; } - ] + }] } }); }); diff --git a/src/main/webapp/scripts/questionmanagement/views/question-detail.html.tmpl b/src/main/webapp/scripts/questionmanagement/views/question-detail.html.tmpl index f3f1460c29..5f7124a0a7 100644 --- a/src/main/webapp/scripts/questionmanagement/views/question-detail.html.tmpl +++ b/src/main/webapp/scripts/questionmanagement/views/question-detail.html.tmpl @@ -66,7 +66,7 @@ {{'study-management.detail.label.study' | translate }}: {{'global.messages.error.unavailable' | translate}}
- + {{'study-management.detail.label.study' | translate }}: @@ -80,7 +80,7 @@ {{'survey-management.detail.label.surveys' | translate }}: {{'global.messages.error.undocumented' | translate}}
- + {{'variable-management.detail.label.variable' | translate }}: diff --git a/src/main/webapp/scripts/studymanagement/configuration/study.js b/src/main/webapp/scripts/studymanagement/configuration/study.js index 5d09326171..876ad37e63 100644 --- a/src/main/webapp/scripts/studymanagement/configuration/study.js +++ b/src/main/webapp/scripts/studymanagement/configuration/study.js @@ -10,7 +10,7 @@ angular.module('metadatamanagementApp') if (result) { return result; } else { - SimpleMessageToastService.openSimpleMessageToast( + SimpleMessageToastService.openAlertMessageToast( 'study-management.detail.not-found', {id: id}); return null; } diff --git a/src/main/webapp/scripts/studymanagement/configuration/translations-de.js b/src/main/webapp/scripts/studymanagement/configuration/translations-de.js index 182f53b190..ca2bb303b5 100644 --- a/src/main/webapp/scripts/studymanagement/configuration/translations-de.js +++ b/src/main/webapp/scripts/studymanagement/configuration/translations-de.js @@ -71,7 +71,6 @@ angular.module('metadatamanagementApp').config( 'not-found-references': 'Die id {{id}} hat keine Referenzen auf Studien.', 'not-yet-released': 'Aktuell nicht freigegeben', 'not-released-toast': 'Die Studie "{{ id }}" wird aktuell bearbeitet und ist daher nicht für alle Benutzer freigegeben!', - 'old-version': 'Ihr Link verweist auf eine ältere Version ({{versionFromUrl}}) dieser Studie. Hier wird die aktuelle Version ({{actualVersion}}) der Studie "{{title}}" dargestellt.', 'beta-release-no-doi': 'Diese Studie hat noch keine DOI.', 'publications-for-series': 'Publikationen zur Studienreihe "{{studySeries}}"', 'publications-for-study': 'Publikationen zu dieser Studie', diff --git a/src/main/webapp/scripts/studymanagement/configuration/translations-en.js b/src/main/webapp/scripts/studymanagement/configuration/translations-en.js index 688bac7826..996aea998f 100644 --- a/src/main/webapp/scripts/studymanagement/configuration/translations-en.js +++ b/src/main/webapp/scripts/studymanagement/configuration/translations-en.js @@ -71,7 +71,6 @@ angular.module('metadatamanagementApp').config( 'not-found-references': 'The id {{id}} has no References to Studies.', 'not-yet-released': 'Currently not released', 'not-released-toast': 'Study "{{ id }}" is being worked on. Therefore it is not visible to all users at the moment!', - 'old-version': 'Your link refers to a former version ({{versionFromUrl}}) of this study. This page displays the current version ({{actualVersion}}) of the study "{{title}}".', 'beta-release-no-doi': 'This study has no DOI yet.', 'publications-for-series': 'Publications related to Series "{{studySeries}}"', 'publications-for-study': 'Publications related to this Study', diff --git a/src/main/webapp/scripts/studymanagement/views/study-detail.controller.js b/src/main/webapp/scripts/studymanagement/views/study-detail.controller.js index 3fbc0a6650..77dc61ca10 100644 --- a/src/main/webapp/scripts/studymanagement/views/study-detail.controller.js +++ b/src/main/webapp/scripts/studymanagement/views/study-detail.controller.js @@ -25,7 +25,6 @@ angular.module('metadatamanagementApp') } }; - var versionFromUrl = $stateParams.version; var ctrl = this; var activeProject; ctrl.isAuthenticated = Principal.isAuthenticated; @@ -140,7 +139,7 @@ angular.module('metadatamanagementApp') _.set(survey, 'release.version', result.release.version); }); } - /* We need to load search the dataSets cause the contain needed + /* We need to load the dataSet search docs cause they contain needed survey titles */ DataSetSearchService.findByStudyId(result.id, ['id', 'number', 'description', 'type', 'surveys', @@ -150,19 +149,6 @@ angular.module('metadatamanagementApp') ctrl.dataSets = dataSets.hits.hits; }); ctrl.loadAttachments(); - - if (result.release && versionFromUrl) { - if (bowser.compareVersions( - [versionFromUrl, result.release.version]) === -1) { - SimpleMessageToastService.openAlertMessageToast( - 'study-management.detail.old-version', - { - title: result.title[LanguageService.getCurrentInstantly()], - versionFromUrl: versionFromUrl, - actualVersion: result.release.version - }); - } - } } else { SimpleMessageToastService.openAlertMessageToast( 'study-management.detail.not-released-toast', {id: result.id} diff --git a/src/main/webapp/scripts/studymanagement/views/study-detail.html.tmpl b/src/main/webapp/scripts/studymanagement/views/study-detail.html.tmpl index 90fe3f9c1a..a93a168269 100644 --- a/src/main/webapp/scripts/studymanagement/views/study-detail.html.tmpl +++ b/src/main/webapp/scripts/studymanagement/views/study-detail.html.tmpl @@ -108,7 +108,7 @@ {{'survey-management.detail.label.surveys' | translate }}: {{'global.messages.error.undocumented' | translate}}
- + {{'variable-management.detail.label.variable' | translate }}: diff --git a/src/main/webapp/scripts/surveymanagement/configuration/survey.js b/src/main/webapp/scripts/surveymanagement/configuration/survey.js index f165e8e240..dd8d0a96d3 100644 --- a/src/main/webapp/scripts/surveymanagement/configuration/survey.js +++ b/src/main/webapp/scripts/surveymanagement/configuration/survey.js @@ -2,6 +2,30 @@ angular.module('metadatamanagementApp') .config(function($stateProvider, $urlRouterProvider) { + var loadShadowCopy = function(SurveySearchService, + SimpleMessageToastService, id, version) { + var loadLatestShadowCopyFallback = function() { + return SurveySearchService.findShadowByIdAndVersion(id, null).promise + .then(function(result) { + if (result) { + return result; + } else { + SimpleMessageToastService.openAlertMessageToast( + 'survey-management.detail.not-found', {id: id}); + return null; + } + }); + }; + return SurveySearchService.findShadowByIdAndVersion(id, version).promise + .then(function(result) { + if (result) { + return result; + } else { + return loadLatestShadowCopyFallback(); + } + }); + }; + $urlRouterProvider.when('/de/surveys/', '/de/error'); $urlRouterProvider.when('/en/surveys/', '/en/error'); $stateProvider @@ -24,12 +48,17 @@ angular.module('metadatamanagementApp') }, resolve: { entity: ['$stateParams', 'SurveySearchService', 'Principal', - function($stateParams, SurveySearchService, Principal) { + 'SimpleMessageToastService', '$q', + function($stateParams, SurveySearchService, Principal, + SimpleMessageToastService, $q) { if (Principal.loginName() && !$stateParams.version) { return SurveySearchService.findOneById($stateParams.id); } else { - return SurveySearchService.findShadowByIdAndVersion( - $stateParams.id, $stateParams.version); + var deferred = $q.defer(); + loadShadowCopy(SurveySearchService, + SimpleMessageToastService, $stateParams.id, + $stateParams.version).then(deferred.resolve, deferred.reject); + return deferred; } } ] diff --git a/src/main/webapp/scripts/surveymanagement/views/survey-detail.html.tmpl b/src/main/webapp/scripts/surveymanagement/views/survey-detail.html.tmpl index 1b7b65db67..9a8728909a 100644 --- a/src/main/webapp/scripts/surveymanagement/views/survey-detail.html.tmpl +++ b/src/main/webapp/scripts/surveymanagement/views/survey-detail.html.tmpl @@ -80,7 +80,7 @@ {{'study-management.detail.label.study' | translate }}: {{'global.messages.error.unavailable' | translate}}
- + {{'data-set-management.detail.label.data-set' | translate }}: diff --git a/src/main/webapp/scripts/variablemanagement/configuration/variable.js b/src/main/webapp/scripts/variablemanagement/configuration/variable.js index 2a23316859..131e7378f8 100644 --- a/src/main/webapp/scripts/variablemanagement/configuration/variable.js +++ b/src/main/webapp/scripts/variablemanagement/configuration/variable.js @@ -2,6 +2,29 @@ angular.module('metadatamanagementApp') .config(function($stateProvider, $urlRouterProvider) { + var loadShadowCopy = function(VariableSearchService, + SimpleMessageToastService, id, version) { + var loadLatestShadowCopyFallback = function() { + return VariableSearchService.findShadowByIdAndVersion(id, null) + .promise.then(function(result) { + if (result) { + return result; + } else { + SimpleMessageToastService.openAlertMessageToast( + 'variable-management.detail.not-found', {id: id}); + return null; + } + }); + }; + return VariableSearchService.findShadowByIdAndVersion(id, version) + .promise.then(function(result) { + if (result) { + return result; + } else { + return loadLatestShadowCopyFallback(); + } + }); + }; $urlRouterProvider.when('/de/variables/', '/de/error'); $urlRouterProvider.when('/en/variables/', '/en/error'); $stateProvider @@ -23,12 +46,17 @@ angular.module('metadatamanagementApp') }, resolve: { entity: ['$stateParams', 'VariableSearchService', 'Principal', - function($stateParams, VariableSearchService, Principal) { + 'SimpleMessageToastService', '$q', + function($stateParams, VariableSearchService, Principal, + SimpleMessageToastService, $q) { if (Principal.loginName() && !$stateParams.version) { return VariableSearchService.findOneById($stateParams.id); } else { - return VariableSearchService.findShadowByIdAndVersion( - $stateParams.id, $stateParams.version); + var deferred = $q.defer(); + loadShadowCopy(VariableSearchService, + SimpleMessageToastService, $stateParams.id, + $stateParams.version).then(deferred.resolve, deferred.reject); + return deferred; } } ] diff --git a/src/main/webapp/scripts/variablemanagement/views/variable-detail.html.tmpl b/src/main/webapp/scripts/variablemanagement/views/variable-detail.html.tmpl index fd52c64bc5..caaf7cb58f 100644 --- a/src/main/webapp/scripts/variablemanagement/views/variable-detail.html.tmpl +++ b/src/main/webapp/scripts/variablemanagement/views/variable-detail.html.tmpl @@ -82,7 +82,7 @@ {{'study-management.detail.label.study' | translate }}: {{'global.messages.error.unavailable' | translate}}
- + {{'question-management.detail.label.question' | translate }}: From e62c4095215271ed34209a9b096877baf011f44e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Reitmann?= Date: Wed, 11 Sep 2019 10:30:11 +0200 Subject: [PATCH 05/16] #2278 show progress indicator instead of state icon --- .../directives/project-cockpit-versions.html.tmpl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/webapp/scripts/dataacquisitionprojectmanagement/directives/project-cockpit-versions.html.tmpl b/src/main/webapp/scripts/dataacquisitionprojectmanagement/directives/project-cockpit-versions.html.tmpl index 60352442d0..492fcc71b5 100644 --- a/src/main/webapp/scripts/dataacquisitionprojectmanagement/directives/project-cockpit-versions.html.tmpl +++ b/src/main/webapp/scripts/dataacquisitionprojectmanagement/directives/project-cockpit-versions.html.tmpl @@ -10,14 +10,14 @@ - - + + visibility_on {{'data-acquisition-project-management.project-cockpit.versions.button.hide-shadow' | translate}} - + visibility_off {{'data-acquisition-project-management.project-cockpit.versions.button.unhide-shadow' | translate}} From bf0e0fa3bcab568a6e3c36df05db08a6c90c5232 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Reitmann?= Date: Wed, 11 Sep 2019 14:13:37 +0200 Subject: [PATCH 06/16] fix robottest xpath for undo icon (#2278) --- .../surveymanagement/check_attachment_versioning.robot | 2 +- .../data_provider/surveymanagement/check_versioning.robot | 2 +- .../Check Roll Back to Previous Version of a Concept.robot | 4 ++-- ...hers Project Releasing and Unreleasing Access Rights.robot | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/test/robotframework/data_provider/surveymanagement/check_attachment_versioning.robot b/src/test/robotframework/data_provider/surveymanagement/check_attachment_versioning.robot index 8ba680d20a..66a41027bc 100644 --- a/src/test/robotframework/data_provider/surveymanagement/check_attachment_versioning.robot +++ b/src/test/robotframework/data_provider/surveymanagement/check_attachment_versioning.robot @@ -30,4 +30,4 @@ Revise to second latest version Click Element Through Tooltips xpath=//md-dialog//table//tr[2] Click Attachment Restore Dialogue - Click Element Through Tooltips xpath=//form//button[md-icon[text()='undo']] + Click Element Through Tooltips xpath=//form//button[md-icon[text()='history']] diff --git a/src/test/robotframework/data_provider/surveymanagement/check_versioning.robot b/src/test/robotframework/data_provider/surveymanagement/check_versioning.robot index dc87682ed1..3821f9e359 100644 --- a/src/test/robotframework/data_provider/surveymanagement/check_versioning.robot +++ b/src/test/robotframework/data_provider/surveymanagement/check_versioning.robot @@ -23,7 +23,7 @@ Click Submit Button Click Element Through Tooltips xpath=//button[@type='submit'] Click Restore Dialogue - Click Element Through Tooltips xpath=//button[md-icon[text()='undo']] + Click Element Through Tooltips xpath=//button[md-icon[text()='history']] Cancel Restore Dialoge Click Element Through Tooltips xpath=//button[span[text()='Abbrechen']] diff --git a/src/test/robotframework/publisher/Conceptmanagement/Check Roll Back to Previous Version of a Concept.robot b/src/test/robotframework/publisher/Conceptmanagement/Check Roll Back to Previous Version of a Concept.robot index 5ff508eba4..9e444b4d1e 100644 --- a/src/test/robotframework/publisher/Conceptmanagement/Check Roll Back to Previous Version of a Concept.robot +++ b/src/test/robotframework/publisher/Conceptmanagement/Check Roll Back to Previous Version of a Concept.robot @@ -17,10 +17,10 @@ Concept Roll Back Run Keyword if '${BROWSER}' == 'chrome' Sleep 3s #chrome is too fast Click on the first search result Click Element Through Tooltips xpath=//button[@ng-click="ctrl.conceptEdit()"]//md-icon[contains(., "mode_edit")] - Click Element Through Tooltips xpath=//button[@ng-click="ctrl.openRestorePreviousVersionDialog($event)"]//md-icon[contains(., "undo")] + Click Element Through Tooltips xpath=//button[@ng-click="ctrl.openRestorePreviousVersionDialog($event)"]//md-icon[contains(., "history")] Click Element Through Tooltips xpath=//md-dialog-content//table//tr//td[contains(., "Roll Back Concept ${BROWSER} De_Rollback")] Click Element Through Tooltips xpath=//button[@ng-click="ctrl.saveConcept()"]//md-icon[contains(., "save")] - Click Element Through Tooltips xpath=//button[@ng-click="ctrl.openRestorePreviousVersionDialog($event)"]//md-icon[contains(., "undo")] + Click Element Through Tooltips xpath=//button[@ng-click="ctrl.openRestorePreviousVersionDialog($event)"]//md-icon[contains(., "history")] Click Element Through Tooltips xpath=//md-dialog-content//table//tr[@class="ng-scope"]//td[contains(., "Roll Back Concept ${BROWSER} De")] Click Element Through Tooltips xpath=//button[@ng-click="ctrl.saveConcept()"]//md-icon[contains(., "save")] diff --git a/src/test/robotframework/publisher/Projectmanagement/Check Publishers Project Releasing and Unreleasing Access Rights.robot b/src/test/robotframework/publisher/Projectmanagement/Check Publishers Project Releasing and Unreleasing Access Rights.robot index caee982487..8256070e2e 100644 --- a/src/test/robotframework/publisher/Projectmanagement/Check Publishers Project Releasing and Unreleasing Access Rights.robot +++ b/src/test/robotframework/publisher/Projectmanagement/Check Publishers Project Releasing and Unreleasing Access Rights.robot @@ -48,7 +48,7 @@ Click Study Save Button Click Element Through Tooltips xpath=//button[@type="submit"]//md-icon[contains(. , "save")] Click Restore Button - Click Element Through Tooltips xpath=//div[@ng-if="ctrl.study.id"]//button[@type="button"]//md-icon[contains(.,"undo")] + Click Element Through Tooltips xpath=//div[@ng-if="ctrl.study.id"]//button[@type="button"]//md-icon[contains(.,"history")] Revise to second latest version Click Element Through Tooltips xpath=//md-dialog//table//tbody//tr[2]//td From 76bd3d8770b9447d3835b4eb777ca3cc3d445d4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Reitmann?= Date: Wed, 11 Sep 2019 14:25:28 +0200 Subject: [PATCH 07/16] fix wrong page details references (#2365) --- .../choose-attachment-version.controller.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/webapp/scripts/common/dialogs/choose-previous-attachment-version/choose-attachment-version.controller.js b/src/main/webapp/scripts/common/dialogs/choose-previous-attachment-version/choose-attachment-version.controller.js index f8c8d5369a..9b544a1f98 100644 --- a/src/main/webapp/scripts/common/dialogs/choose-previous-attachment-version/choose-attachment-version.controller.js +++ b/src/main/webapp/scripts/common/dialogs/choose-previous-attachment-version/choose-attachment-version.controller.js @@ -18,8 +18,9 @@ angular.module('metadatamanagementApp') }; $scope.getAttachmentVersions = function() { - getAttachmentVersionsCallback(domainId, filename, $scope.limit, - $scope.skip).then( + getAttachmentVersionsCallback(domainId, filename, + $scope.currentPage.limit, + $scope.currentPage.skip).then( function(attachments) { $scope.attachments = attachments; }); From d4a110ebd47733d309a7232140fcdaf186b95aca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Reitmann?= Date: Wed, 11 Sep 2019 14:27:29 +0200 Subject: [PATCH 08/16] Remove hossain from travis mails :( (#2365) --- .travis.yml | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index ec897516c0..181301c2bf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,17 +19,17 @@ addons: - g++-4.9 stages: - name: build - if: NOT (branch =~ /^saikotitis.*$/ || branch =~ /^(development|master|test)$/) + if: NOT branch =~ /^(development|master|test)$/ - name: build and deploy if: branch =~ /^(development|master|test)$/ - name: e2e smoketests - if: type = cron || branch =~ /^saikotitis.*$/ + if: type = cron - name: nightly e2e tests publicuser - if: type = cron || branch =~ /^saikotitis.*$/ + if: type = cron - name: nightly e2e tests dataprovider - if: type = cron || branch =~ /^saikotitis.*$/ + if: type = cron - name: nightly e2e tests publisher - if: type = cron || branch =~ /^saikotitis.*$/ + if: type = cron jobs: include: - stage: build @@ -202,5 +202,4 @@ jobs: notifications: email: recipients: - - secure: "oyEkjrcti+bTYz/TLA6tw6F6aTpeiWxMGyAsKOyYxYCjWw8sNsagiqzzLxcIdqy62ETCKmkGrYlJr1dofPT27j4pQgSuPT9EWkaviNfFG6AllGkW4+N6RdpMw3gXr0O/qtpy2LdXr1D8cP8Pji4V9DKriPkOMcE7tlBUHTCuDlchheenqszKpWBhQGtSipR0dDGo9AyhmbfUu9mnyl73A8Xi2XegKeie5J0JZzuiacwjbVZXO8JexyYN06rFpcyMIkdTUq4JHMENenszqYmZ4/P8QIymdxY/rBsNRXVl2vIXoFtOkIA+fjcPj6CuOxlGrs6+C5BvGc951uaicwFHDeZ15Csx2YpTTuqjNclgUYffGvaqwlUDrQhQ45paxYTqqLzStdbNJBaQEw8Oh3P6BdUKldDv93Y6ydkOeQlLBNS/+F1irNo8HtzUmHew3aF9unNAB1BD6x5jFlGUrO/xXra0RWiVD2p/q97cF8iEHyqlodRCtBFMZ+5F13fYbVPaIzwPWPgysvc0eDBE2W+hUPip7em/9pehhaVbhcy5fvmesHlMsmQc0UK/Rimfl2y3RXobGMNbyZheGWn+HJHn4K2Vy3D05AUPRn1z+XHh0H8i8L9M15JgvHq4hQVZtpyUbq1bgHcKFezB8v32Sd22bBMHXHbDe3h1hnlW7I3U+V8=" - - secure: "l0q3avI4nJTwPKKfJldH/SdmeHB1grxsRiM/x2TX3bQE5JfYdureNVNAi85JXBiq/BilURWPNq+jYO+qJQRP4h5mwywJLmFy1JRWyfirglbu0fuC3NuB29qszhJ4ZVazoQM6Q46htXtignrDwABzn4sro20ns6L44ATBHT+npJmbVnfTTyWnhrGjJDlzp8uqNy//TbXWHMIVPgnCPv1w+9IdFxIIRbiVkSCRGkQMHxq4lMMqsg5x+wcyPnQYY+oLw2jx962lJQ2kXpD5yBTI22/0Kv9UxMXS4wYCPbhYeOF3xf4gVeTa1WSm0JjQRA/xI/o3lEPIp+FYubF+bpC+gOND1triu7mfn1VSbLr22xxYaevOzGDwc1dlEkm5wepakt6JyvzjCijafsi3rd6KhJ3QXXIvOeKFnmutaOR3zwBibeNuFDsc9nqd6dI+oQpKhmO3DVBZv/ftIccWZBHV7Z1N2F+GzKIpH3iE+cMjDIxRAQykql0p17/Bu2TvBUebnbMXiT8zKRnrFu6CHnOh3KroQl3KktNDqhVkcVLin4EP0RH9RjUds1M6N7den9IUJk49KF4gYtkPNEtdGekqv9BubAwc02XfseeEuyxK4t2f1xBPBLnzLgqqxkK5ZB1evJZ7oC8ShG9wyOCYjoJVEfwxOKJJ27dBjZWi5QX+n7M=" + - secure: "rCV85HWYYl5lzvMatGA8h3O3t522tbxuSKIF3H6drTewXW17IRMuKaeBehF71Dva5vReIK6oLRx0YlAZK/SOZzY9+TDWwXFv7QeyDq/0c0cUaI9UX3wbf0puX9AZAIflNpkrc+NmV1vXci8A/MyZAfZFxKGJqE8wn1mGQnzJCD5D1sbcCXSrnQA0fOyyFq6ugr4vyIRY4iiu008WMFqP6V58dlxC3PJax3rPugXTUNzOHU1qiHdTA17R4q47hsmdJGtCNsAjemo+/D+w8nWp+DJokHsYv/SSngB5GprKv22vXiZWy3wnqjagvOfPHYZGfMYEtc7kMylOmrxrjx15cQiyIncJQKjabYCDQ2lkjjNS1bZTnobe/CHy+IkWxT/qiV/miDLOI0Tm6B6OQGJRhJoErBjRSnihZZo9fg8YVRJdApG3ZoWmuXwwOTi41rsHRdhClKzJzmSO+7paea7CPaobzvn54n2Lu1azp05GNG1hlxtNVlp7r7xh+e+W0JHj9trFmXq+vkO7nQtS3rtnnWnz8xqDBqXE3xWtRD0tiG0f9qev7AiMo+UTWEsvXuXI68ywHThppO2rHFN6RntLNgAwFzwwGBG0U4AblljYV7zT56f1xiEaAbe77Fyryi6uFTX7wJPLBLKfylWwt9vLgcDon/plVRuDivEvwBdgwQ8=" From 44dff336a9a23838e8943550d83a198dcabdd373 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Reitmann?= Date: Wed, 11 Sep 2019 15:34:05 +0200 Subject: [PATCH 09/16] fixes for test results (#2278 ) --- src/main/scss/main.scss | 4 ++++ .../configuration/translations-en.js | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/scss/main.scss b/src/main/scss/main.scss index 893d36e17b..1afdec9382 100644 --- a/src/main/scss/main.scss +++ b/src/main/scss/main.scss @@ -1284,3 +1284,7 @@ geographic-coverage { } } } + +.md-button[disabled] { + pointer-events: none; +} diff --git a/src/main/webapp/scripts/dataacquisitionprojectmanagement/configuration/translations-en.js b/src/main/webapp/scripts/dataacquisitionprojectmanagement/configuration/translations-en.js index 3d07af2230..0125e5b732 100644 --- a/src/main/webapp/scripts/dataacquisitionprojectmanagement/configuration/translations-en.js +++ b/src/main/webapp/scripts/dataacquisitionprojectmanagement/configuration/translations-en.js @@ -195,13 +195,13 @@ angular.module('metadatamanagementApp').config( }, 'confirm-unhide' : { 'title': 'Make version {{version}} of the project {{id}} available again?', - 'content': 'Are you sure you want to make version {{version}} of the project {{id}} availabl for all users again? Data users will then be able to see this version again.' + 'content': 'Are you sure you want to make version {{version}} of the project {{id}} available for all users again? Data users will then be able to see this version again.' }, 'hiding-toast': 'The version {{version}} of the project {{id}} will be visible only for registered users in about 10 minutes!', 'unhiding-toast': 'The version {{version}} of the project {{id}} will be visible again for all users in about 10 minutes!', 'button': { 'hide-shadow': 'This version is currently visible for all users. Click here to hide this version!', - 'unhide-shadow': 'This version is currently not visible for all users. Click here to make it availabe for all users!' + 'unhide-shadow': 'This version is currently not visible for all users. Click here to make it available for all users!' } } }, From bb621d6f767100525806f657481b450d19cd5b5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Reitmann?= Date: Wed, 11 Sep 2019 16:17:04 +0200 Subject: [PATCH 10/16] #2366 upgrade spring boot, javers, log4j --- pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index afb21af8b8..eaa9f10391 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.boot spring-boot-starter-parent - 2.1.7.RELEASE + 2.1.8.RELEASE @@ -135,7 +135,7 @@ org.apache.logging.log4j log4j-core - 2.8.2 + 2.11.2 org.apache.tika @@ -149,7 +149,7 @@ org.javers javers-spring-boot-starter-mongo - 5.6.3 + 5.7.2 org.mapstruct From 233638d7596d240fa26ac8cad4fd3af357d52acb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Reitmann?= Date: Thu, 12 Sep 2019 10:24:22 +0200 Subject: [PATCH 11/16] #2278 immediately update elasticsearch --- .../service/ShadowCopyQueueItemService.java | 29 +++++++------------ 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/service/ShadowCopyQueueItemService.java b/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/service/ShadowCopyQueueItemService.java index c71253a3d7..0cf673ed91 100644 --- a/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/service/ShadowCopyQueueItemService.java +++ b/src/main/java/eu/dzhw/fdz/metadatamanagement/projectmanagement/service/ShadowCopyQueueItemService.java @@ -20,7 +20,9 @@ import eu.dzhw.fdz.metadatamanagement.projectmanagement.domain.ShadowCopyQueueItem.Action; import eu.dzhw.fdz.metadatamanagement.projectmanagement.repository.DataAcquisitionProjectRepository; import eu.dzhw.fdz.metadatamanagement.projectmanagement.repository.ShadowCopyQueueItemRepository; +import eu.dzhw.fdz.metadatamanagement.searchmanagement.service.ElasticsearchUpdateQueueService; import eu.dzhw.fdz.metadatamanagement.usermanagement.security.SecurityUtils; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; /** @@ -30,34 +32,22 @@ */ @Service @Slf4j +@RequiredArgsConstructor public class ShadowCopyQueueItemService { private String jvmId = ManagementFactory.getRuntimeMXBean().getName(); - private ApplicationEventPublisher applicationEventPublisher; + private final ApplicationEventPublisher applicationEventPublisher; - private DataAcquisitionProjectRepository dataAcquisitionProjectRepository; + private final DataAcquisitionProjectRepository dataAcquisitionProjectRepository; - private ShadowCopyQueueItemRepository shadowCopyQueueItemRepository; + private final ShadowCopyQueueItemRepository shadowCopyQueueItemRepository; - private DataAcquisitionProjectVersionsService dataAcquisitionProjectVersionsService; + private final DataAcquisitionProjectVersionsService dataAcquisitionProjectVersionsService; - private UserDetailsService userDetailsService; + private final ElasticsearchUpdateQueueService elasticsearchUpdateQueueService; - /** - * Create a new instance. - */ - public ShadowCopyQueueItemService(ApplicationEventPublisher applicationEventPublisher, - DataAcquisitionProjectRepository dataAcquisitionProjectRepository, - ShadowCopyQueueItemRepository shadowCopyQueueItemRepository, - DataAcquisitionProjectVersionsService dataAcquisitionProjectVersionsService, - UserDetailsService userDetailsService) { - this.applicationEventPublisher = applicationEventPublisher; - this.dataAcquisitionProjectRepository = dataAcquisitionProjectRepository; - this.shadowCopyQueueItemRepository = shadowCopyQueueItemRepository; - this.dataAcquisitionProjectVersionsService = dataAcquisitionProjectVersionsService; - this.userDetailsService = userDetailsService; - } + private final UserDetailsService userDetailsService; /** * Create a new shadow copy queue item. @@ -153,6 +143,7 @@ public void executeShadowCopyActions() { log.warn("A shadow copy task was scheduled for project {}, but it could not be found!", dataAcquisitionProjectId); } + elasticsearchUpdateQueueService.processAllQueueItems(); shadowCopyQueueItemRepository.delete(task); } finally { clearSecurityContext(); From 45797eceac5726745efab1f209f495e0bb0ab1c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Reitmann?= Date: Thu, 12 Sep 2019 17:52:10 +0200 Subject: [PATCH 12/16] fixing broken xpaths, remove unrequired aria labels (#2278) --- .../joblogging/views/job-complete-toast.html.tmpl | 4 ++-- .../scripts/common/navbar/views/navbar.html.tmpl | 2 +- .../common/toast/simple-message-toast.html.tmpl | 2 +- .../scripts/common/toolbar/views/toolbar.html.tmpl | 12 ++++++------ .../directives/user-list.html.tmpl | 4 ++-- ...ng From Stack Rights and Verify Check Icons.robot | 4 ++-- .../resources/project_management_resource.robot | 4 ++-- 7 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/main/webapp/scripts/common/joblogging/views/job-complete-toast.html.tmpl b/src/main/webapp/scripts/common/joblogging/views/job-complete-toast.html.tmpl index f9531f7779..8aaac58ace 100644 --- a/src/main/webapp/scripts/common/joblogging/views/job-complete-toast.html.tmpl +++ b/src/main/webapp/scripts/common/joblogging/views/job-complete-toast.html.tmpl @@ -1,13 +1,13 @@ - + {{'global.joblogging.job-complete-toast.show-log' | translate}} remove_red_eye Show log - + {{'global.dialog.tooltip.close' | translate}} diff --git a/src/main/webapp/scripts/common/navbar/views/navbar.html.tmpl b/src/main/webapp/scripts/common/navbar/views/navbar.html.tmpl index 5f9b0eba24..627d51406f 100644 --- a/src/main/webapp/scripts/common/navbar/views/navbar.html.tmpl +++ b/src/main/webapp/scripts/common/navbar/views/navbar.html.tmpl @@ -68,7 +68,7 @@
  • - + diff --git a/src/main/webapp/scripts/common/toast/simple-message-toast.html.tmpl b/src/main/webapp/scripts/common/toast/simple-message-toast.html.tmpl index 56eb1ae696..0f5691b47a 100644 --- a/src/main/webapp/scripts/common/toast/simple-message-toast.html.tmpl +++ b/src/main/webapp/scripts/common/toast/simple-message-toast.html.tmpl @@ -4,7 +4,7 @@

  • - + {{'global.toast.tooltip.close' | translate}} diff --git a/src/main/webapp/scripts/common/toolbar/views/toolbar.html.tmpl b/src/main/webapp/scripts/common/toolbar/views/toolbar.html.tmpl index d12aaa3287..e1554bfd54 100644 --- a/src/main/webapp/scripts/common/toolbar/views/toolbar.html.tmpl +++ b/src/main/webapp/scripts/common/toolbar/views/toolbar.html.tmpl @@ -10,9 +10,9 @@
    - {{item.icon}} - {{item.icon}} - + {{item.icon}} + {{item.icon}} + {{item.type | translate}} ({{item.tabName | translate}}) {{item.id}} @@ -30,15 +30,15 @@ - {{item.icon}} - + {{item.icon}} + {{item.type | translate}} {{item.notFound}} forward {{item.icon}} - + {{item.type | translate}} ({{item.tabName | translate}}) {{item.id}} diff --git a/src/main/webapp/scripts/dataacquisitionprojectmanagement/directives/user-list.html.tmpl b/src/main/webapp/scripts/dataacquisitionprojectmanagement/directives/user-list.html.tmpl index 381facf642..5a1f96c908 100644 --- a/src/main/webapp/scripts/dataacquisitionprojectmanagement/directives/user-list.html.tmpl +++ b/src/main/webapp/scripts/dataacquisitionprojectmanagement/directives/user-list.html.tmpl @@ -35,8 +35,8 @@ {{user.login}} ({{user.email}})
    - - + + delete_forever {{'data-acquisition-project-management.project-cockpit.button.remove-user' | translate}} diff --git a/src/test/robotframework/publisher/Projectmanagement/Check Deleting From Stack Rights and Verify Check Icons.robot b/src/test/robotframework/publisher/Projectmanagement/Check Deleting From Stack Rights and Verify Check Icons.robot index 6ad9e1768a..519e8fd870 100644 --- a/src/test/robotframework/publisher/Projectmanagement/Check Deleting From Stack Rights and Verify Check Icons.robot +++ b/src/test/robotframework/publisher/Projectmanagement/Check Deleting From Stack Rights and Verify Check Icons.robot @@ -15,11 +15,11 @@ Check Deleting The Last Dataprovider and Publisher From Stack is Not Possible Assign Dataprovider From List Click Element Through Tooltips xpath=//md-card[@group='dataProviders']//md-list-item//div//strong[contains(.,'dataprovidertest1')]//following::md-icon[contains(.,'delete_forever')] Click Element Through Tooltips xpath=//md-card[@group='dataProviders']//md-list-item//div//strong[contains(.,'dataprovidertest2')]//following::md-icon[contains(.,'delete_forever')] - Run Keyword And Ignore Error '${BROWSER}' == 'ie' Page Should Contain Element xpath=//md-card[@group='dataProviders']//md-list-item//div//strong[contains(.,'dataprovider')]//following::button[@disabled='disabled'] + Run Keyword And Ignore Error Page Should Contain Element xpath=//md-card[@group='dataProviders']//md-list-item[1]//button[@disabled='disabled']//md-icon[contains(.,'delete_forever')] Assign Publisher From List Click Element Through Tooltips xpath=//md-card[@group='publishers']//md-list-item//div//strong[contains(.,'publishertest1')]//following::md-icon[contains(.,'delete_forever')] Click Element Through Tooltips xpath=//md-card[@group='publishers']//md-list-item//div//strong[contains(.,'publishertest2')]//following::md-icon[contains(.,'delete_forever')] - Run Keyword And Ignore Error '${BROWSER}' == 'ie' xpath=//md-card[@group='publishers']//md-list-item//div//strong[contains(.,'publisher')]//following::button[@disabled='disabled'] + Run Keyword And Ignore Error Page Should Contain Element xpath=//md-card[@group='publishers']//md-list-item[1]//button[@disabled='disabled']//md-icon[contains(.,'delete_forever')] Check The Sentiments of Metadata Select Survey Checkbox diff --git a/src/test/robotframework/resources/project_management_resource.robot b/src/test/robotframework/resources/project_management_resource.robot index 2b6153604d..771bdf6e8c 100644 --- a/src/test/robotframework/resources/project_management_resource.robot +++ b/src/test/robotframework/resources/project_management_resource.robot @@ -27,12 +27,12 @@ Discard Changes No Assign a dataprovider [Arguments] ${dataprovidername} - Input Text xpath=//md-card[@group='dataProviders']//following::input[@type='search'] ${dataprovidername} + Input Text xpath=//md-card[@group='dataProviders']//input[@type='search'] ${dataprovidername} Click Element Through Tooltips xpath=//md-virtual-repeat-container//span[text()='${dataprovidername}'] Assign a publisher [Arguments] ${publishername} - Input Text xpath=//md-card[@group='publishers']//following::input[@type='search'] ${publishername} + Input Text xpath=//md-card[@group='publishers']//input[@type='search'] ${publishername} Click Element Through Tooltips xpath=//md-virtual-repeat-container//span[text()='${publishername}'] Assign to publisher From dfbd7f94cae9ee06208315dda2c1f2dbdcab425c Mon Sep 17 00:00:00 2001 From: Ute H Date: Fri, 13 Sep 2019 11:16:57 +0200 Subject: [PATCH 13/16] Update questions.rst --- docs/source/questions.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/source/questions.rst b/docs/source/questions.rst index 99618531cf..a2cdcdce70 100644 --- a/docs/source/questions.rst +++ b/docs/source/questions.rst @@ -50,3 +50,6 @@ meist "erkennbare" Nummerierung. Es wird zwischen fünf Fragetypen differenziert Die technische Dokumentation zum erstellen der Frage-Metadaten finden Sie hier: https://dzhw.github.io/questionMetadataPreparation/index.html + +Die Anleitung zur Zusammenstellung der Metadaten (inkl. Beschreibung der Attribute) finden Sie hier: +https://dzhw.github.io/questionMetadataPreparation/articles/question_metadata_preparation_introduction.html From e6d70f44c4e60b316caadb2e05e6563fe51ac982 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Reitmann?= Date: Fri, 13 Sep 2019 11:38:17 +0200 Subject: [PATCH 14/16] Add sroll into view for ie to fix tests (#2278) --- .../robotframework/resources/project_management_resource.robot | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/test/robotframework/resources/project_management_resource.robot b/src/test/robotframework/resources/project_management_resource.robot index 771bdf6e8c..718502049f 100644 --- a/src/test/robotframework/resources/project_management_resource.robot +++ b/src/test/robotframework/resources/project_management_resource.robot @@ -27,11 +27,13 @@ Discard Changes No Assign a dataprovider [Arguments] ${dataprovidername} + Run Keyword If '${BROWSER}' == 'ie' Scroll Element Into View xpath=//md-card[@group='dataProviders']//input[@type='search'] Input Text xpath=//md-card[@group='dataProviders']//input[@type='search'] ${dataprovidername} Click Element Through Tooltips xpath=//md-virtual-repeat-container//span[text()='${dataprovidername}'] Assign a publisher [Arguments] ${publishername} + Run Keyword If '${BROWSER}' == 'ie' Scroll Element Into View xpath=//md-card[@group='publishers']//input[@type='search'] Input Text xpath=//md-card[@group='publishers']//input[@type='search'] ${publishername} Click Element Through Tooltips xpath=//md-virtual-repeat-container//span[text()='${publishername}'] From 471452afb8562baefb578943fcffba13bd1aa1bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Reitmann?= Date: Mon, 16 Sep 2019 11:28:31 +0200 Subject: [PATCH 15/16] #2278 hide attachments as well --- .../filemanagement/service/FileService.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/main/java/eu/dzhw/fdz/metadatamanagement/filemanagement/service/FileService.java b/src/main/java/eu/dzhw/fdz/metadatamanagement/filemanagement/service/FileService.java index 5cc2648001..8603223360 100644 --- a/src/main/java/eu/dzhw/fdz/metadatamanagement/filemanagement/service/FileService.java +++ b/src/main/java/eu/dzhw/fdz/metadatamanagement/filemanagement/service/FileService.java @@ -19,6 +19,8 @@ import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; +import com.mongodb.client.gridfs.model.GridFSFile; + import lombok.RequiredArgsConstructor; /** @@ -56,7 +58,12 @@ protected void setupFileNameIndex() { */ @Nullable public GridFsResource findFile(String fileName) { - return this.gridfsOperations.getResource(fileName); + Query query = new Query(GridFsCriteria.whereFilename().is(fileName)); + GridFSFile file = this.gridfsOperations.findOne(query); + if (file != null && !file.getMetadata().getBoolean("hidden", false)) { + return this.gridfsOperations.getResource(fileName); + } + return null; } /** From 883fc776608d0e482115972b279f23fbe2ab3d16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Reitmann?= Date: Mon, 16 Sep 2019 20:56:21 +0200 Subject: [PATCH 16/16] #2358 bumb version number --- pom.xml | 2 +- src/main/webapp/scripts/app.constants.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index eaa9f10391..8662bb2108 100644 --- a/pom.xml +++ b/pom.xml @@ -11,7 +11,7 @@ eu.dzhw.fdz.metadatamanagement metadatamanagement - 1.0.91-SNAPSHOT + 1.0.91 war metadatamanagement diff --git a/src/main/webapp/scripts/app.constants.js b/src/main/webapp/scripts/app.constants.js index b51651351b..7b6279c852 100644 --- a/src/main/webapp/scripts/app.constants.js +++ b/src/main/webapp/scripts/app.constants.js @@ -6,7 +6,7 @@ angular.module('metadatamanagementApp') .constant('ENV', 'local') -.constant('VERSION', '1.0.91-SNAPSHOT') +.constant('VERSION', '1.0.91') .constant('ElasticSearchProperties', {apiVersion:'6.3',logLevel:'error',pageSize:10})