Added versioning fields on DmpBlueprintEntity and stack

This commit is contained in:
Thomas Georgios Giannos 2024-02-02 14:59:11 +02:00
parent acc754823f
commit e4c1efe98c
18 changed files with 693 additions and 130 deletions

View File

@ -19,8 +19,10 @@ public class AuditableAction {
public static final EventId DmpBlueprint_Persist = new EventId(3002, "DmpBlueprint_Persist"); public static final EventId DmpBlueprint_Persist = new EventId(3002, "DmpBlueprint_Persist");
public static final EventId DmpBlueprint_Delete = new EventId(3003, "DmpBlueprint_Delete"); public static final EventId DmpBlueprint_Delete = new EventId(3003, "DmpBlueprint_Delete");
public static final EventId DmpBlueprint_Clone = new EventId(3004, "DmpBlueprint_Clone"); public static final EventId DmpBlueprint_Clone = new EventId(3004, "DmpBlueprint_Clone");
public static final EventId DmpBlueprint_GetXml = new EventId(3005, "DmpBlueprint_GetXml");
public static final EventId DmpBlueprint_Import = new EventId(3006, "DmpBlueprint_Import"); public static final EventId DmpBlueprint_PersistNewVersion = new EventId(3005, "DmpBlueprint_PersistNewVersion");
public static final EventId DmpBlueprint_GetXml = new EventId(3006, "DmpBlueprint_GetXml");
public static final EventId DmpBlueprint_Import = new EventId(3007, "DmpBlueprint_Import");
public static final EventId User_Settings_Query = new EventId(4000, "User_Settings_Query"); public static final EventId User_Settings_Query = new EventId(4000, "User_Settings_Query");
public static final EventId User_Settings_Lookup = new EventId(4001, "User_Settings_Lookup"); public static final EventId User_Settings_Lookup = new EventId(4001, "User_Settings_Lookup");

View File

@ -85,6 +85,7 @@ public final class Permission {
public static String EditDmpBlueprint = "EditDmpBlueprint"; public static String EditDmpBlueprint = "EditDmpBlueprint";
public static String DeleteDmpBlueprint = "DeleteDmpBlueprint"; public static String DeleteDmpBlueprint = "DeleteDmpBlueprint";
public static String CloneDmpBlueprint = "CloneDmpBlueprint"; public static String CloneDmpBlueprint = "CloneDmpBlueprint";
public static String CreateNewVersionDmpBlueprint = "CreateNewVersionDmpBlueprint";
public static String ExportDmpBlueprint = "ExportDmpBlueprint"; public static String ExportDmpBlueprint = "ExportDmpBlueprint";
public static String ImportDmpBlueprint = "ImportDmpBlueprint"; public static String ImportDmpBlueprint = "ImportDmpBlueprint";

View File

@ -7,7 +7,9 @@ import java.util.Map;
public enum DescriptionTemplateVersionStatus implements DatabaseEnum<Short> { public enum DescriptionTemplateVersionStatus implements DatabaseEnum<Short> {
Current((short) 0), Previous ((short) 1), NotFinalized ((short) 2); Current((short) 0),
Previous((short) 1),
NotFinalized((short) 2);
private final Short value; private final Short value;

View File

@ -0,0 +1,32 @@
package eu.eudat.commons.enums;
import com.fasterxml.jackson.annotation.JsonValue;
import eu.eudat.data.converters.enums.DatabaseEnum;
import java.util.Map;
public enum DmpBlueprintVersionStatus implements DatabaseEnum<Short> {
Current((short) 0),
Previous((short) 1),
NotFinalized((short) 2);
private final Short value;
DmpBlueprintVersionStatus(Short value) {
this.value = value;
}
@Override
@JsonValue
public Short getValue() {
return value;
}
private static final Map<Short, DmpBlueprintVersionStatus> map = EnumUtils.getEnumValueMap(DmpBlueprintVersionStatus.class);
public static DmpBlueprintVersionStatus of(Short i) {
return map.get(i);
}
}

View File

@ -1,7 +1,9 @@
package eu.eudat.data; package eu.eudat.data;
import eu.eudat.commons.enums.DmpBlueprintStatus; import eu.eudat.commons.enums.DmpBlueprintStatus;
import eu.eudat.commons.enums.DmpBlueprintVersionStatus;
import eu.eudat.commons.enums.IsActive; import eu.eudat.commons.enums.IsActive;
import eu.eudat.data.converters.DmpBlueprintVersionStatusConverter;
import eu.eudat.data.converters.enums.DmpBlueprintStatusConverter; import eu.eudat.data.converters.enums.DmpBlueprintStatusConverter;
import eu.eudat.data.converters.enums.IsActiveConverter; import eu.eudat.data.converters.enums.IsActiveConverter;
import eu.eudat.data.tenant.TenantScopedBaseEntity; import eu.eudat.data.tenant.TenantScopedBaseEntity;
@ -15,41 +17,64 @@ import java.util.UUID;
@Entity @Entity
@Table(name = "\"DmpBlueprint\"") @Table(name = "\"DmpBlueprint\"")
public class DmpBlueprintEntity extends TenantScopedBaseEntity { public class DmpBlueprintEntity extends TenantScopedBaseEntity {
@Id @Id
@Column(name = "id", columnDefinition = "uuid", updatable = false, nullable = false) @Column(name = "id", columnDefinition = "uuid", updatable = false, nullable = false)
private UUID id; private UUID id;
public static final String _id = "id"; public static final String _id = "id";
@Column(name = "label", length = DmpBlueprintEntity._labelLength, nullable = false) @Column(name = "label", length = DmpBlueprintEntity._labelLength, nullable = false)
private String label; private String label;
public static final String _label = "label"; public static final String _label = "label";
public static final int _labelLength = 250; public static final int _labelLength = 250;
@Type(value = SQLXMLType.class) @Type(value = SQLXMLType.class)
@Column(name = "definition", nullable = true, columnDefinition = "xml") @Column(name = "definition", columnDefinition = "xml")
private String definition; private String definition;
public static final String _definition = "definition";
public static final String _definition = "definition";
@Column(name = "status", nullable = false) @Column(name = "status", nullable = false)
@Convert(converter = DmpBlueprintStatusConverter.class) @Convert(converter = DmpBlueprintStatusConverter.class)
private DmpBlueprintStatus status; private DmpBlueprintStatus status;
public static final String _status = "status"; public static final String _status = "status";
@Column(name = "is_active", nullable = false) @Column(name = "group_id", columnDefinition = "uuid", nullable = false)
@Convert(converter = IsActiveConverter.class) private UUID groupId;
private IsActive isActive;
public static final String _isActive = "isActive";
public static final String _groupId = "groupId";
@Column(name = "version", nullable = false)
private Short version;
public static final String _version = "version";
@Column(name = "version_status", nullable = false)
@Convert(converter = DmpBlueprintVersionStatusConverter.class)
private DmpBlueprintVersionStatus versionStatus;
public static final String _versionStatus = "versionStatus";
@Column(name = "created_at", nullable = false) @Column(name = "created_at", nullable = false)
private Instant createdAt = null; private Instant createdAt = null;
public static final String _createdAt = "createdAt"; public static final String _createdAt = "createdAt";
@Column(name = "updated_at", nullable = false) @Column(name = "updated_at", nullable = false)
private Instant updatedAt; private Instant updatedAt;
public static final String _updatedAt = "updatedAt"; public static final String _updatedAt = "updatedAt";
@Column(name = "is_active", nullable = false)
@Convert(converter = IsActiveConverter.class)
private IsActive isActive;
public static final String _isActive = "isActive";
public UUID getId() { public UUID getId() {
return id; return id;
} }
@ -82,12 +107,28 @@ public class DmpBlueprintEntity extends TenantScopedBaseEntity {
this.status = status; this.status = status;
} }
public IsActive getIsActive() { public UUID getGroupId() {
return isActive; return groupId;
} }
public void setIsActive(IsActive isActive) { public void setGroupId(UUID groupId) {
this.isActive = isActive; this.groupId = groupId;
}
public Short getVersion() {
return version;
}
public void setVersion(Short version) {
this.version = version;
}
public DmpBlueprintVersionStatus getVersionStatus() {
return versionStatus;
}
public void setVersionStatus(DmpBlueprintVersionStatus versionStatus) {
this.versionStatus = versionStatus;
} }
public Instant getCreatedAt() { public Instant getCreatedAt() {
@ -105,4 +146,12 @@ public class DmpBlueprintEntity extends TenantScopedBaseEntity {
public void setUpdatedAt(Instant updatedAt) { public void setUpdatedAt(Instant updatedAt) {
this.updatedAt = updatedAt; this.updatedAt = updatedAt;
} }
public IsActive getIsActive() {
return isActive;
}
public void setIsActive(IsActive isActive) {
this.isActive = isActive;
}
} }

View File

@ -0,0 +1,15 @@
package eu.eudat.data.converters;
import eu.eudat.commons.enums.DmpBlueprintVersionStatus;
import eu.eudat.data.converters.enums.DatabaseEnumConverter;
import jakarta.persistence.Converter;
@Converter
public class DmpBlueprintVersionStatusConverter extends DatabaseEnumConverter<DmpBlueprintVersionStatus, Short> {
@Override
protected DmpBlueprintVersionStatus of(Short i) {
return DmpBlueprintVersionStatus.of(i);
}
}

View File

@ -65,6 +65,16 @@ public class ErrorThesaurusProperties {
this.dmpNewVersionConflict = dmpNewVersionConflict; this.dmpNewVersionConflict = dmpNewVersionConflict;
} }
public ErrorDescription dmpBlueprintNewVersionConflict;
public ErrorDescription getDmpBlueprintNewVersionConflict() {
return dmpBlueprintNewVersionConflict;
}
public void setDmpBlueprintNewVersionConflict(ErrorDescription dmpBlueprintNewVersionConflict) {
this.dmpBlueprintNewVersionConflict = dmpBlueprintNewVersionConflict;
}
private ErrorDescription dmpIsFinalized; private ErrorDescription dmpIsFinalized;
public ErrorDescription getDmpIsFinalized() { public ErrorDescription getDmpIsFinalized() {

View File

@ -1,39 +1,59 @@
package eu.eudat.model; package eu.eudat.model;
import eu.eudat.commons.enums.DmpBlueprintStatus; import eu.eudat.commons.enums.DmpBlueprintStatus;
import eu.eudat.commons.enums.DmpBlueprintVersionStatus;
import eu.eudat.commons.enums.IsActive; import eu.eudat.commons.enums.IsActive;
import eu.eudat.model.dmpblueprintdefinition.Definition; import eu.eudat.model.dmpblueprintdefinition.Definition;
import java.time.Instant; import java.time.Instant;
import java.util.List;
import java.util.UUID; import java.util.UUID;
public class DmpBlueprint { public class DmpBlueprint {
public final static String _id = "id";
private UUID id; private UUID id;
public final static String _label= "label"; public static final String _id = "id";
private String label; private String label;
public final static String _createdAt = "createdAt"; public static final String _label = "label";
private Definition definition; private Definition definition;
public final static String _definition = "definition"; public static final String _definition = "definition";
private Instant createdAt;
public final static String _updatedAt = "updatedAt";
private Instant updatedAt;
public final static String _isActive = "isActive";
private IsActive isActive;
public final static String _status = "status";
private DmpBlueprintStatus status; private DmpBlueprintStatus status;
public final static String _hash = "hash"; public static final String _status = "status";
private UUID groupId;
public static final String _groupId = "groupId";
private Short version;
public static final String _version = "version";
private DmpBlueprintVersionStatus versionStatus;
public static final String _versionStatus = "versionStatus";
private Instant createdAt;
public static final String _createdAt = "createdAt";
private Instant updatedAt;
public static final String _updatedAt = "updatedAt";
private IsActive isActive;
public static final String _isActive = "isActive";
private String hash; private String hash;
public static final String _hash = "hash";
public UUID getId() { public UUID getId() {
return id; return id;
} }
@ -50,6 +70,46 @@ public class DmpBlueprint {
this.label = label; this.label = label;
} }
public Definition getDefinition() {
return definition;
}
public void setDefinition(Definition definition) {
this.definition = definition;
}
public DmpBlueprintStatus getStatus() {
return status;
}
public void setStatus(DmpBlueprintStatus status) {
this.status = status;
}
public UUID getGroupId() {
return groupId;
}
public void setGroupId(UUID groupId) {
this.groupId = groupId;
}
public Short getVersion() {
return version;
}
public void setVersion(Short version) {
this.version = version;
}
public DmpBlueprintVersionStatus getVersionStatus() {
return versionStatus;
}
public void setVersionStatus(DmpBlueprintVersionStatus versionStatus) {
this.versionStatus = versionStatus;
}
public Instant getCreatedAt() { public Instant getCreatedAt() {
return createdAt; return createdAt;
} }
@ -74,14 +134,6 @@ public class DmpBlueprint {
this.isActive = isActive; this.isActive = isActive;
} }
public DmpBlueprintStatus getStatus() {
return status;
}
public void setStatus(DmpBlueprintStatus status) {
this.status = status;
}
public String getHash() { public String getHash() {
return hash; return hash;
} }
@ -90,13 +142,6 @@ public class DmpBlueprint {
this.hash = hash; this.hash = hash;
} }
public Definition getDefinition() {
return definition;
}
public void setDefinition(Definition definition) {
this.definition = definition;
}
} }

View File

@ -32,8 +32,11 @@ import java.util.stream.Collectors;
public class DescriptionTemplateBuilder extends BaseBuilder<DescriptionTemplate, DescriptionTemplateEntity> { public class DescriptionTemplateBuilder extends BaseBuilder<DescriptionTemplate, DescriptionTemplateEntity> {
private EnumSet<AuthorizationFlags> authorize = EnumSet.of(AuthorizationFlags.None); private EnumSet<AuthorizationFlags> authorize = EnumSet.of(AuthorizationFlags.None);
private final QueryFactory queryFactory; private final QueryFactory queryFactory;
private final BuilderFactory builderFactory; private final BuilderFactory builderFactory;
private final XmlHandlingService xmlHandlingService; private final XmlHandlingService xmlHandlingService;
@Autowired @Autowired
@ -67,24 +70,38 @@ public class DescriptionTemplateBuilder extends BaseBuilder<DescriptionTemplate,
List<DescriptionTemplate> models = new ArrayList<>(); List<DescriptionTemplate> models = new ArrayList<>();
for (DescriptionTemplateEntity d : data) { for (DescriptionTemplateEntity d : data) {
DescriptionTemplate m = new DescriptionTemplate(); DescriptionTemplate m = new DescriptionTemplate();
if (fields.hasField(this.asIndexer(DescriptionTemplate._id))) m.setId(d.getId()); if (fields.hasField(this.asIndexer(DescriptionTemplate._id)))
if (fields.hasField(this.asIndexer(DescriptionTemplate._label))) m.setLabel(d.getLabel()); m.setId(d.getId());
if (fields.hasField(this.asIndexer(DescriptionTemplate._description))) m.setDescription(d.getDescription()); if (fields.hasField(this.asIndexer(DescriptionTemplate._label)))
if (fields.hasField(this.asIndexer(DescriptionTemplate._groupId))) m.setGroupId(d.getGroupId()); m.setLabel(d.getLabel());
if (fields.hasField(this.asIndexer(DescriptionTemplate._version))) m.setVersion(d.getVersion()); if (fields.hasField(this.asIndexer(DescriptionTemplate._description)))
if (fields.hasField(this.asIndexer(DescriptionTemplate._language))) m.setLanguage(d.getLanguage()); m.setDescription(d.getDescription());
if (fields.hasField(this.asIndexer(DescriptionTemplate._createdAt))) m.setCreatedAt(d.getCreatedAt()); if (fields.hasField(this.asIndexer(DescriptionTemplate._groupId)))
if (fields.hasField(this.asIndexer(DescriptionTemplate._updatedAt))) m.setUpdatedAt(d.getUpdatedAt()); m.setGroupId(d.getGroupId());
if (fields.hasField(this.asIndexer(DescriptionTemplate._isActive))) m.setIsActive(d.getIsActive()); if (fields.hasField(this.asIndexer(DescriptionTemplate._version)))
if (fields.hasField(this.asIndexer(DescriptionTemplate._versionStatus))) m.setVersionStatus(d.getVersionStatus()); m.setVersion(d.getVersion());
if (fields.hasField(this.asIndexer(DescriptionTemplate._status))) m.setStatus(d.getStatus()); if (fields.hasField(this.asIndexer(DescriptionTemplate._language)))
if (fields.hasField(this.asIndexer(DescriptionTemplate._hash))) m.setHash(this.hashValue(d.getUpdatedAt())); m.setLanguage(d.getLanguage());
if (!definitionFields.isEmpty() && d.getDefinition() != null){ if (fields.hasField(this.asIndexer(DescriptionTemplate._createdAt)))
m.setCreatedAt(d.getCreatedAt());
if (fields.hasField(this.asIndexer(DescriptionTemplate._updatedAt)))
m.setUpdatedAt(d.getUpdatedAt());
if (fields.hasField(this.asIndexer(DescriptionTemplate._isActive)))
m.setIsActive(d.getIsActive());
if (fields.hasField(this.asIndexer(DescriptionTemplate._versionStatus)))
m.setVersionStatus(d.getVersionStatus());
if (fields.hasField(this.asIndexer(DescriptionTemplate._status)))
m.setStatus(d.getStatus());
if (fields.hasField(this.asIndexer(DescriptionTemplate._hash)))
m.setHash(this.hashValue(d.getUpdatedAt()));
if (!definitionFields.isEmpty() && d.getDefinition() != null) {
DefinitionEntity definition = this.xmlHandlingService.fromXmlSafe(DefinitionEntity.class, d.getDefinition()); DefinitionEntity definition = this.xmlHandlingService.fromXmlSafe(DefinitionEntity.class, d.getDefinition());
m.setDefinition(this.builderFactory.builder(DefinitionBuilder.class).authorize(this.authorize).build(definitionFields, definition)); m.setDefinition(this.builderFactory.builder(DefinitionBuilder.class).authorize(this.authorize).build(definitionFields, definition));
} }
if (!usersFields.isEmpty() && usersMap != null && usersMap.containsKey(d.getId())) m.setUsers(usersMap.get(d.getId())); if (!usersFields.isEmpty() && usersMap != null && usersMap.containsKey(d.getId()))
if (!descriptionTemplateTypeFields.isEmpty() && descriptionTemplateTypeMap != null && descriptionTemplateTypeMap.containsKey(d.getTypeId())) m.setType(descriptionTemplateTypeMap.get(d.getTypeId())); m.setUsers(usersMap.get(d.getId()));
if (!descriptionTemplateTypeFields.isEmpty() && descriptionTemplateTypeMap != null && descriptionTemplateTypeMap.containsKey(d.getTypeId()))
m.setType(descriptionTemplateTypeMap.get(d.getTypeId()));
models.add(m); models.add(m);
} }
this.logger.debug("build {} items", Optional.of(models).map(List::size).orElse(0)); this.logger.debug("build {} items", Optional.of(models).map(List::size).orElse(0));
@ -92,7 +109,8 @@ public class DescriptionTemplateBuilder extends BaseBuilder<DescriptionTemplate,
} }
private Map<UUID, DescriptionTemplateType> collectDescriptionTemplateTypes(FieldSet fields, List<DescriptionTemplateEntity> data) throws MyApplicationException { private Map<UUID, DescriptionTemplateType> collectDescriptionTemplateTypes(FieldSet fields, List<DescriptionTemplateEntity> data) throws MyApplicationException {
if (fields.isEmpty() || data.isEmpty()) return null; if (fields.isEmpty() || data.isEmpty())
return null;
this.logger.debug("checking related - {}", DescriptionTemplateType.class.getSimpleName()); this.logger.debug("checking related - {}", DescriptionTemplateType.class.getSimpleName());
Map<UUID, DescriptionTemplateType> itemMap = null; Map<UUID, DescriptionTemplateType> itemMap = null;
@ -121,7 +139,8 @@ public class DescriptionTemplateBuilder extends BaseBuilder<DescriptionTemplate,
} }
private Map<UUID, List<UserDescriptionTemplate>> collectUserDescriptionTemplates(FieldSet fields, List<DescriptionTemplateEntity> data) throws MyApplicationException { private Map<UUID, List<UserDescriptionTemplate>> collectUserDescriptionTemplates(FieldSet fields, List<DescriptionTemplateEntity> data) throws MyApplicationException {
if (fields.isEmpty() || data.isEmpty()) return null; if (fields.isEmpty() || data.isEmpty())
return null;
this.logger.debug("checking related - {}", UserDescriptionTemplate.class.getSimpleName()); this.logger.debug("checking related - {}", UserDescriptionTemplate.class.getSimpleName());
Map<UUID, List<UserDescriptionTemplate>> itemMap = null; Map<UUID, List<UserDescriptionTemplate>> itemMap = null;

View File

@ -25,7 +25,9 @@ import java.util.*;
public class DmpBlueprintBuilder extends BaseBuilder<DmpBlueprint, DmpBlueprintEntity> { public class DmpBlueprintBuilder extends BaseBuilder<DmpBlueprint, DmpBlueprintEntity> {
private final BuilderFactory builderFactory; private final BuilderFactory builderFactory;
private final XmlHandlingService xmlHandlingService; private final XmlHandlingService xmlHandlingService;
private EnumSet<AuthorizationFlags> authorize = EnumSet.of(AuthorizationFlags.None); private EnumSet<AuthorizationFlags> authorize = EnumSet.of(AuthorizationFlags.None);
@Autowired @Autowired
@ -53,14 +55,27 @@ public class DmpBlueprintBuilder extends BaseBuilder<DmpBlueprint, DmpBlueprintE
List<DmpBlueprint> models = new ArrayList<>(); List<DmpBlueprint> models = new ArrayList<>();
for (DmpBlueprintEntity d : data) { for (DmpBlueprintEntity d : data) {
DmpBlueprint m = new DmpBlueprint(); DmpBlueprint m = new DmpBlueprint();
if (fields.hasField(this.asIndexer(DmpBlueprint._id))) m.setId(d.getId()); if (fields.hasField(this.asIndexer(DmpBlueprint._id)))
if (fields.hasField(this.asIndexer(DmpBlueprint._label))) m.setLabel(d.getLabel()); m.setId(d.getId());
if (fields.hasField(this.asIndexer(DmpBlueprint._createdAt))) m.setCreatedAt(d.getCreatedAt()); if (fields.hasField(this.asIndexer(DmpBlueprint._label)))
if (fields.hasField(this.asIndexer(DmpBlueprint._updatedAt))) m.setUpdatedAt(d.getUpdatedAt()); m.setLabel(d.getLabel());
if (fields.hasField(this.asIndexer(DmpBlueprint._isActive))) m.setIsActive(d.getIsActive()); if (fields.hasField(this.asIndexer(DmpBlueprint._status)))
if (fields.hasField(this.asIndexer(DmpBlueprint._status))) m.setStatus(d.getStatus()); m.setStatus(d.getStatus());
if (fields.hasField(this.asIndexer(DmpBlueprint._hash))) m.setHash(this.hashValue(d.getUpdatedAt())); if (fields.hasField(this.asIndexer(DmpBlueprint._groupId)))
if (!definitionFields.isEmpty() && d.getDefinition() != null){ m.setGroupId(d.getGroupId());
if (fields.hasField(this.asIndexer(DmpBlueprint._version)))
m.setVersion(d.getVersion());
if (fields.hasField(this.asIndexer(DmpBlueprint._versionStatus)))
m.setVersionStatus(d.getVersionStatus());
if (fields.hasField(this.asIndexer(DmpBlueprint._createdAt)))
m.setCreatedAt(d.getCreatedAt());
if (fields.hasField(this.asIndexer(DmpBlueprint._updatedAt)))
m.setUpdatedAt(d.getUpdatedAt());
if (fields.hasField(this.asIndexer(DmpBlueprint._isActive)))
m.setIsActive(d.getIsActive());
if (fields.hasField(this.asIndexer(DmpBlueprint._hash)))
m.setHash(this.hashValue(d.getUpdatedAt()));
if (!definitionFields.isEmpty() && d.getDefinition() != null) {
DefinitionEntity definition = this.xmlHandlingService.fromXmlSafe(DefinitionEntity.class, d.getDefinition()); DefinitionEntity definition = this.xmlHandlingService.fromXmlSafe(DefinitionEntity.class, d.getDefinition());
m.setDefinition(this.builderFactory.builder(DefinitionBuilder.class).authorize(this.authorize).build(definitionFields, definition)); m.setDefinition(this.builderFactory.builder(DefinitionBuilder.class).authorize(this.authorize).build(definitionFields, definition));
} }

View File

@ -0,0 +1,132 @@
package eu.eudat.model.persist;
import eu.eudat.commons.enums.DmpBlueprintStatus;
import eu.eudat.commons.validation.BaseValidator;
import eu.eudat.convention.ConventionService;
import eu.eudat.data.DmpBlueprintEntity;
import eu.eudat.errorcode.ErrorThesaurusProperties;
import eu.eudat.model.persist.dmpblueprintdefinition.DefinitionPersist;
import gr.cite.tools.validation.ValidatorFactory;
import gr.cite.tools.validation.specification.Specification;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Scope;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
public class NewVersionDmpBlueprintPersist {
private UUID id = null;
private String label = null;
public static final String _label = "label";
private DefinitionPersist definition = null;
public static final String _definition = "definition";
private DmpBlueprintStatus status;
public static final String _status = "status";
private String hash;
public static final String _hash = "hash";
public UUID getId() {
return id;
}
public void setId(UUID id) {
this.id = id;
}
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
public DefinitionPersist getDefinition() {
return definition;
}
public void setDefinition(DefinitionPersist definition) {
this.definition = definition;
}
public DmpBlueprintStatus getStatus() {
return status;
}
public void setStatus(DmpBlueprintStatus status) {
this.status = status;
}
public String getHash() {
return hash;
}
public void setHash(String hash) {
this.hash = hash;
}
@Component(NewVersionDmpBlueprintPersistValidator.ValidatorName)
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public static class NewVersionDmpBlueprintPersistValidator extends BaseValidator<NewVersionDmpBlueprintPersist> {
public static final String ValidatorName = "NewVersionDmpBlueprintPersistValidator";
private final MessageSource messageSource;
private final ValidatorFactory validatorFactory;
public NewVersionDmpBlueprintPersistValidator(ConventionService conventionService, ErrorThesaurusProperties errors, MessageSource messageSource, ValidatorFactory validatorFactory) {
super(conventionService, errors);
this.messageSource = messageSource;
this.validatorFactory = validatorFactory;
}
@Override
protected Class<NewVersionDmpBlueprintPersist> modelClass() {
return NewVersionDmpBlueprintPersist.class;
}
@Override
protected List<Specification> specifications(NewVersionDmpBlueprintPersist item) {
return Arrays.asList(
this.spec()
.iff(() -> this.isValidGuid(item.getId()))
.must(() -> this.isValidHash(item.getHash()))
.failOn(NewVersionDmpBlueprintPersist._hash).failWith(messageSource.getMessage("Validation_Required", new Object[]{NewVersionDmpBlueprintPersist._hash}, LocaleContextHolder.getLocale())),
this.spec()
.must(() -> !this.isEmpty(item.getLabel()))
.failOn(NewVersionDmpBlueprintPersist._label).failWith(messageSource.getMessage("Validation_Required", new Object[]{NewVersionDmpBlueprintPersist._label}, LocaleContextHolder.getLocale())),
this.spec()
.iff(() -> !this.isEmpty(item.getLabel()))
.must(() -> this.lessEqualLength(item.getLabel(), DmpBlueprintEntity._labelLength))
.failOn(NewVersionDmpBlueprintPersist._label).failWith(messageSource.getMessage("Validation_MaxLength", new Object[]{NewVersionDmpBlueprintPersist._label}, LocaleContextHolder.getLocale())),
this.spec()
.must(() -> !this.isNull(item.getStatus()))
.failOn(NewVersionDmpBlueprintPersist._status).failWith(messageSource.getMessage("Validation_Required", new Object[]{NewVersionDmpBlueprintPersist._status}, LocaleContextHolder.getLocale())),
this.spec()
.must(() -> !this.isNull(item.getDefinition()))
.failOn(NewVersionDmpBlueprintPersist._definition).failWith(messageSource.getMessage("Validation_Required", new Object[]{NewVersionDmpBlueprintPersist._definition}, LocaleContextHolder.getLocale())),
this.refSpec()
.iff(() -> !this.isNull(item.getDefinition()))
.on(NewVersionDmpBlueprintPersist._definition)
.over(item.getDefinition())
.using(() -> this.validatorFactory.validator(DefinitionPersist.DefinitionPersistValidator.class))
);
}
}
}

View File

@ -2,11 +2,10 @@ package eu.eudat.query;
import eu.eudat.authorization.AuthorizationFlags; import eu.eudat.authorization.AuthorizationFlags;
import eu.eudat.commons.enums.DmpBlueprintStatus; import eu.eudat.commons.enums.DmpBlueprintStatus;
import eu.eudat.commons.enums.DmpBlueprintVersionStatus;
import eu.eudat.commons.enums.IsActive; import eu.eudat.commons.enums.IsActive;
import eu.eudat.commons.scope.user.UserScope; import eu.eudat.commons.scope.user.UserScope;
import eu.eudat.data.DescriptionTemplateEntity;
import eu.eudat.data.DmpBlueprintEntity; import eu.eudat.data.DmpBlueprintEntity;
import eu.eudat.model.DescriptionTemplateType;
import eu.eudat.model.DmpBlueprint; import eu.eudat.model.DmpBlueprint;
import gr.cite.commons.web.authz.service.AuthorizationService; import gr.cite.commons.web.authz.service.AuthorizationService;
import gr.cite.tools.data.query.FieldResolver; import gr.cite.tools.data.query.FieldResolver;
@ -30,11 +29,17 @@ public class DmpBlueprintQuery extends QueryBase<DmpBlueprintEntity> {
private Collection<UUID> ids; private Collection<UUID> ids;
private Collection<UUID> excludedIds;
private Collection<IsActive> isActives; private Collection<IsActive> isActives;
private Collection<DmpBlueprintStatus> statuses; private Collection<DmpBlueprintStatus> statuses;
private Collection<UUID> excludedIds; private Collection<UUID> groupIds;
private Collection<Short> versions;
private Collection<DmpBlueprintVersionStatus> versionStatuses;
private EnumSet<AuthorizationFlags> authorize = EnumSet.of(AuthorizationFlags.None); private EnumSet<AuthorizationFlags> authorize = EnumSet.of(AuthorizationFlags.None);
@ -58,6 +63,21 @@ public class DmpBlueprintQuery extends QueryBase<DmpBlueprintEntity> {
return this; return this;
} }
public DmpBlueprintQuery excludedIds(Collection<UUID> values) {
this.excludedIds = values;
return this;
}
public DmpBlueprintQuery excludedIds(UUID value) {
this.excludedIds = List.of(value);
return this;
}
public DmpBlueprintQuery excludedIds(UUID... value) {
this.excludedIds = Arrays.asList(value);
return this;
}
public DmpBlueprintQuery isActive(IsActive value) { public DmpBlueprintQuery isActive(IsActive value) {
this.isActives = List.of(value); this.isActives = List.of(value);
return this; return this;
@ -88,18 +108,48 @@ public class DmpBlueprintQuery extends QueryBase<DmpBlueprintEntity> {
return this; return this;
} }
public DmpBlueprintQuery excludedIds(Collection<UUID> values) { public DmpBlueprintQuery groupIds(UUID value) {
this.excludedIds = values; this.groupIds = List.of(value);
return this; return this;
} }
public DmpBlueprintQuery excludedIds(UUID value) { public DmpBlueprintQuery groupIds(UUID... value) {
this.excludedIds = List.of(value); this.groupIds = Arrays.asList(value);
return this; return this;
} }
public DmpBlueprintQuery excludedIds(UUID... value) { public DmpBlueprintQuery groupIds(Collection<UUID> values) {
this.excludedIds = Arrays.asList(value); this.groupIds = values;
return this;
}
public DmpBlueprintQuery versions(Short value) {
this.versions = List.of(value);
return this;
}
public DmpBlueprintQuery versions(Short... value) {
this.versions = Arrays.asList(value);
return this;
}
public DmpBlueprintQuery versions(Collection<Short> values) {
this.versions = values;
return this;
}
public DmpBlueprintQuery versionStatuses(DmpBlueprintVersionStatus value) {
this.versionStatuses = List.of(value);
return this;
}
public DmpBlueprintQuery versionStatuses(DmpBlueprintVersionStatus... value) {
this.versionStatuses = Arrays.asList(value);
return this;
}
public DmpBlueprintQuery versionStatuses(Collection<DmpBlueprintVersionStatus> values) {
this.versionStatuses = values;
return this; return this;
} }
@ -127,15 +177,25 @@ public class DmpBlueprintQuery extends QueryBase<DmpBlueprintEntity> {
@Override @Override
protected <X, Y> Predicate applyFilters(QueryContext<X, Y> queryContext) { protected <X, Y> Predicate applyFilters(QueryContext<X, Y> queryContext) {
List<Predicate> predicates = new ArrayList<>(); List<Predicate> predicates = new ArrayList<>();
if (this.ids != null) { if (this.ids != null) {
CriteriaBuilder.In<UUID> inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(DmpBlueprintEntity._id)); CriteriaBuilder.In<UUID> inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(DmpBlueprintEntity._id));
for (UUID item : this.ids) for (UUID item : this.ids)
inClause.value(item); inClause.value(item);
predicates.add(inClause); predicates.add(inClause);
} }
if (this.excludedIds != null) {
CriteriaBuilder.In<UUID> notInClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(DmpBlueprintEntity._id));
for (UUID item : this.excludedIds)
notInClause.value(item);
predicates.add(notInClause.not());
}
if (this.like != null && !this.like.isEmpty()) { if (this.like != null && !this.like.isEmpty()) {
predicates.add(queryContext.CriteriaBuilder.like(queryContext.Root.get(DmpBlueprintEntity._label), this.like)); predicates.add(queryContext.CriteriaBuilder.like(queryContext.Root.get(DmpBlueprintEntity._label), this.like));
} }
if (this.isActives != null) { if (this.isActives != null) {
CriteriaBuilder.In<IsActive> inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(DmpBlueprintEntity._isActive)); CriteriaBuilder.In<IsActive> inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(DmpBlueprintEntity._isActive));
for (IsActive item : this.isActives) for (IsActive item : this.isActives)
@ -149,12 +209,28 @@ public class DmpBlueprintQuery extends QueryBase<DmpBlueprintEntity> {
inClause.value(item); inClause.value(item);
predicates.add(inClause); predicates.add(inClause);
} }
if (this.excludedIds != null) {
CriteriaBuilder.In<UUID> notInClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(DmpBlueprintEntity._id)); if (this.groupIds != null) {
for (UUID item : this.excludedIds) CriteriaBuilder.In<UUID> inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(DmpBlueprintEntity._groupId));
notInClause.value(item); for (UUID item : this.groupIds)
predicates.add(notInClause.not()); inClause.value(item);
predicates.add(inClause);
} }
if (this.versions != null) {
CriteriaBuilder.In<Short> inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(DmpBlueprintEntity._version));
for (Short item : this.versions)
inClause.value(item);
predicates.add(inClause);
}
if (this.versionStatuses != null) {
CriteriaBuilder.In<DmpBlueprintVersionStatus> inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(DmpBlueprintEntity._versionStatus));
for (DmpBlueprintVersionStatus item : this.versionStatuses)
inClause.value(item);
predicates.add(inClause);
}
if (!predicates.isEmpty()) { if (!predicates.isEmpty()) {
Predicate[] predicatesArray = predicates.toArray(new Predicate[0]); Predicate[] predicatesArray = predicates.toArray(new Predicate[0]);
return queryContext.CriteriaBuilder.and(predicatesArray); return queryContext.CriteriaBuilder.and(predicatesArray);
@ -168,26 +244,45 @@ public class DmpBlueprintQuery extends QueryBase<DmpBlueprintEntity> {
DmpBlueprintEntity item = new DmpBlueprintEntity(); DmpBlueprintEntity item = new DmpBlueprintEntity();
item.setId(QueryBase.convertSafe(tuple, columns, DmpBlueprintEntity._id, UUID.class)); item.setId(QueryBase.convertSafe(tuple, columns, DmpBlueprintEntity._id, UUID.class));
item.setLabel(QueryBase.convertSafe(tuple, columns, DmpBlueprintEntity._label, String.class)); item.setLabel(QueryBase.convertSafe(tuple, columns, DmpBlueprintEntity._label, String.class));
item.setDefinition(QueryBase.convertSafe(tuple, columns, DmpBlueprintEntity._definition, String.class));
item.setStatus(QueryBase.convertSafe(tuple, columns, DmpBlueprintEntity._status, DmpBlueprintStatus.class));
item.setGroupId(QueryBase.convertSafe(tuple, columns, DmpBlueprintEntity._groupId, UUID.class));
item.setVersion(QueryBase.convertSafe(tuple, columns, DmpBlueprintEntity._version, Short.class));
item.setVersionStatus(QueryBase.convertSafe(tuple, columns, DmpBlueprintEntity._versionStatus, DmpBlueprintVersionStatus.class));
item.setCreatedAt(QueryBase.convertSafe(tuple, columns, DmpBlueprintEntity._createdAt, Instant.class)); item.setCreatedAt(QueryBase.convertSafe(tuple, columns, DmpBlueprintEntity._createdAt, Instant.class));
item.setUpdatedAt(QueryBase.convertSafe(tuple, columns, DmpBlueprintEntity._updatedAt, Instant.class)); item.setUpdatedAt(QueryBase.convertSafe(tuple, columns, DmpBlueprintEntity._updatedAt, Instant.class));
item.setIsActive(QueryBase.convertSafe(tuple, columns, DmpBlueprintEntity._isActive, IsActive.class)); item.setIsActive(QueryBase.convertSafe(tuple, columns, DmpBlueprintEntity._isActive, IsActive.class));
item.setDefinition(QueryBase.convertSafe(tuple, columns, DmpBlueprintEntity._definition, String.class));
item.setStatus(QueryBase.convertSafe(tuple, columns, DmpBlueprintEntity._status, DmpBlueprintStatus.class));
return item; return item;
} }
@Override @Override
protected String fieldNameOf(FieldResolver item) { protected String fieldNameOf(FieldResolver item) {
if (item.match(DmpBlueprint._id)) return DmpBlueprintEntity._id; if (item.match(DmpBlueprint._id))
else if (item.match(DmpBlueprint._label)) return DmpBlueprintEntity._label; return DmpBlueprintEntity._id;
else if (item.match(DmpBlueprint._definition)) return DmpBlueprintEntity._definition; else if (item.match(DmpBlueprint._label))
else if (item.prefix(DmpBlueprint._definition)) return DmpBlueprintEntity._definition; return DmpBlueprintEntity._label;
else if (item.match(DmpBlueprint._createdAt)) return DmpBlueprintEntity._createdAt; else if (item.match(DmpBlueprint._definition))
else if (item.match(DmpBlueprint._updatedAt)) return DmpBlueprintEntity._updatedAt; return DmpBlueprintEntity._definition;
else if (item.match(DmpBlueprint._hash)) return DmpBlueprintEntity._updatedAt; else if (item.prefix(DmpBlueprint._definition))
else if (item.match(DmpBlueprint._isActive)) return DmpBlueprintEntity._isActive; return DmpBlueprintEntity._definition;
else if (item.match(DmpBlueprint._status)) return DmpBlueprintEntity._status; else if (item.match(DmpBlueprint._status))
else return null; return DmpBlueprintEntity._status;
else if (item.match(DmpBlueprint._groupId))
return DmpBlueprintEntity._groupId;
else if (item.match(DmpBlueprint._version))
return DmpBlueprintEntity._version;
else if (item.match(DmpBlueprint._versionStatus))
return DmpBlueprintEntity._versionStatus;
else if (item.match(DmpBlueprint._createdAt))
return DmpBlueprintEntity._createdAt;
else if (item.match(DmpBlueprint._updatedAt))
return DmpBlueprintEntity._updatedAt;
else if (item.match(DmpBlueprint._isActive))
return DmpBlueprintEntity._isActive;
else if (item.match(DmpBlueprint._hash))
return DmpBlueprintEntity._updatedAt;
else
return null;
} }
} }

View File

@ -172,9 +172,12 @@ public class DescriptionTemplateServiceImpl implements DescriptionTemplateServic
DescriptionTemplateEntity data; DescriptionTemplateEntity data;
if (isUpdate) { if (isUpdate) {
data = this.entityManager.find(DescriptionTemplateEntity.class, model.getId()); data = this.entityManager.find(DescriptionTemplateEntity.class, model.getId());
if (data == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{model.getId(), DescriptionTemplate.class.getSimpleName()}, LocaleContextHolder.getLocale())); if (data == null)
if (!this.conventionService.hashValue(data.getUpdatedAt()).equals(model.getHash())) throw new MyValidationException(this.errors.getHashConflict().getCode(), this.errors.getHashConflict().getMessage()); throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{model.getId(), DescriptionTemplate.class.getSimpleName()}, LocaleContextHolder.getLocale()));
if (data.getStatus().equals(DescriptionTemplateStatus.Finalized)) throw new MyForbiddenException("Can not update finalized template"); if (!this.conventionService.hashValue(data.getUpdatedAt()).equals(model.getHash()))
throw new MyValidationException(this.errors.getHashConflict().getCode(), this.errors.getHashConflict().getMessage());
if (data.getStatus().equals(DescriptionTemplateStatus.Finalized))
throw new MyForbiddenException("Can not update finalized template");
} else { } else {
data = new DescriptionTemplateEntity(); data = new DescriptionTemplateEntity();
data.setId(UUID.randomUUID()); data.setId(UUID.randomUUID());
@ -213,24 +216,27 @@ public class DescriptionTemplateServiceImpl implements DescriptionTemplateServic
return this.builderFactory.builder(DescriptionTemplateBuilder.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermissionOrPublic).build(BaseFieldSet.build(fields, DescriptionTemplate._id), data); return this.builderFactory.builder(DescriptionTemplateBuilder.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermissionOrPublic).build(BaseFieldSet.build(fields, DescriptionTemplate._id), data);
} }
private void updateVersionStatusAndSave(DescriptionTemplateEntity data, DescriptionTemplateStatus previousStatus, DescriptionTemplateStatus newStatus){ private void updateVersionStatusAndSave(DescriptionTemplateEntity data, DescriptionTemplateStatus previousStatus, DescriptionTemplateStatus newStatus) {
if (previousStatus.equals(newStatus)) return; if (previousStatus.equals(newStatus))
if (previousStatus.equals(DescriptionTemplateStatus.Finalized)) throw new MyForbiddenException("Can not update finalized template"); return;
if (previousStatus.equals(DescriptionTemplateStatus.Finalized))
throw new MyForbiddenException("Can not update finalized template");
if (newStatus.equals(DescriptionTemplateStatus.Finalized)) { if (newStatus.equals(DescriptionTemplateStatus.Finalized)) {
List<DescriptionTemplateEntity> latestVersionDescriptionTemplates = this.queryFactory.query(DescriptionTemplateQuery.class).versionStatuses(DescriptionTemplateVersionStatus.Current).isActive(IsActive.Active).groupIds(data.getGroupId()).collect(); List<DescriptionTemplateEntity> latestVersionDescriptionTemplates = this.queryFactory.query(DescriptionTemplateQuery.class).versionStatuses(DescriptionTemplateVersionStatus.Current).isActive(IsActive.Active).groupIds(data.getGroupId()).collect();
if (latestVersionDescriptionTemplates.size() > 1) throw new MyValidationException("Multiple previous template found"); if (latestVersionDescriptionTemplates.size() > 1)
throw new MyValidationException("Multiple previous template found");
DescriptionTemplateEntity oldDescriptionTemplateEntity = latestVersionDescriptionTemplates.stream().findFirst().orElse(null); DescriptionTemplateEntity oldDescriptionTemplateEntity = latestVersionDescriptionTemplates.stream().findFirst().orElse(null);
data.setVersionStatus(DescriptionTemplateVersionStatus.Current); data.setVersionStatus(DescriptionTemplateVersionStatus.Current);
if (oldDescriptionTemplateEntity != null){ if (oldDescriptionTemplateEntity != null) {
data.setVersion((short) (oldDescriptionTemplateEntity.getVersion() + 1)); data.setVersion((short) (oldDescriptionTemplateEntity.getVersion() + 1));
oldDescriptionTemplateEntity.setVersionStatus(DescriptionTemplateVersionStatus.Previous); oldDescriptionTemplateEntity.setVersionStatus(DescriptionTemplateVersionStatus.Previous);
this.entityManager.merge(oldDescriptionTemplateEntity); this.entityManager.merge(oldDescriptionTemplateEntity);
} else { } else {
data.setVersion((short)1); data.setVersion((short) 1);
} }
} }
@ -544,20 +550,34 @@ public class DescriptionTemplateServiceImpl implements DescriptionTemplateServic
//region NewVersion //region NewVersion
public DescriptionTemplate createNewVersion(NewVersionDescriptionTemplatePersist model, FieldSet fields) throws MyForbiddenException, MyValidationException, MyApplicationException, MyNotFoundException, InvalidApplicationException, JAXBException, ParserConfigurationException, JsonProcessingException, TransformerException { public DescriptionTemplate createNewVersion(NewVersionDescriptionTemplatePersist model, FieldSet fields) throws MyForbiddenException, MyValidationException, MyApplicationException, MyNotFoundException, InvalidApplicationException, JAXBException, ParserConfigurationException, JsonProcessingException, TransformerException {
logger.debug(new MapLogEntry("persisting data descriptionTemplateType").And("model", model).And("fields", fields)); logger.debug(new MapLogEntry("persisting data descriptionTemplate").And("model", model).And("fields", fields));
this.authorizationService.authorizeForce(Permission.CreateNewVersionDescriptionTemplate); this.authorizationService.authorizeForce(Permission.CreateNewVersionDescriptionTemplate);
DescriptionTemplateEntity oldDescriptionTemplateEntity = this.entityManager.find(DescriptionTemplateEntity.class, model.getId()); DescriptionTemplateEntity oldDescriptionTemplateEntity = this.entityManager.find(DescriptionTemplateEntity.class, model.getId());
if (oldDescriptionTemplateEntity == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{model.getId(), DescriptionTemplate.class.getSimpleName()}, LocaleContextHolder.getLocale())); if (oldDescriptionTemplateEntity == null)
if (!this.conventionService.hashValue(oldDescriptionTemplateEntity.getUpdatedAt()).equals(model.getHash())) throw new MyValidationException(this.errors.getHashConflict().getCode(), this.errors.getHashConflict().getMessage()); throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{model.getId(), DescriptionTemplate.class.getSimpleName()}, LocaleContextHolder.getLocale()));
if (!this.conventionService.hashValue(oldDescriptionTemplateEntity.getUpdatedAt()).equals(model.getHash()))
throw new MyValidationException(this.errors.getHashConflict().getCode(), this.errors.getHashConflict().getMessage());
List<DescriptionTemplateEntity> latestVersionDescriptionTemplates = this.queryFactory.query(DescriptionTemplateQuery.class).versionStatuses(DescriptionTemplateVersionStatus.Current).isActive(IsActive.Active).groupIds(oldDescriptionTemplateEntity.getGroupId()).collect(); List<DescriptionTemplateEntity> latestVersionDescriptionTemplates = this.queryFactory.query(DescriptionTemplateQuery.class)
if (latestVersionDescriptionTemplates.isEmpty()) throw new MyValidationException("Previous template not found"); .versionStatuses(DescriptionTemplateVersionStatus.Current)
if (latestVersionDescriptionTemplates.size() > 1) throw new MyValidationException("Multiple previous template found"); .isActive(IsActive.Active)
if (!latestVersionDescriptionTemplates.getFirst().getVersion().equals(oldDescriptionTemplateEntity.getVersion())) throw new MyValidationException(this.errors.getDescriptionTemplateNewVersionConflict().getCode(), this.errors.getDescriptionTemplateNewVersionConflict().getMessage()); .groupIds(oldDescriptionTemplateEntity.getGroupId())
Long notFinalizedCount = this.queryFactory.query(DescriptionTemplateQuery.class).versionStatuses(DescriptionTemplateVersionStatus.NotFinalized).groupIds(oldDescriptionTemplateEntity.getGroupId()).isActive(IsActive.Active).count(); .collect();
if (notFinalizedCount > 0) throw new MyValidationException("Already created draft for this template"); if (latestVersionDescriptionTemplates.isEmpty())
throw new MyValidationException("Previous template not found");
if (latestVersionDescriptionTemplates.size() > 1)
throw new MyValidationException("Multiple previous template found");
if (!latestVersionDescriptionTemplates.getFirst().getVersion().equals(oldDescriptionTemplateEntity.getVersion()))
throw new MyValidationException(this.errors.getDescriptionTemplateNewVersionConflict().getCode(), this.errors.getDescriptionTemplateNewVersionConflict().getMessage());
Long notFinalizedCount = this.queryFactory.query(DescriptionTemplateQuery.class)
.versionStatuses(DescriptionTemplateVersionStatus.NotFinalized)
.groupIds(oldDescriptionTemplateEntity.getGroupId())
.isActive(IsActive.Active)
.count();
if (notFinalizedCount > 0)
throw new MyValidationException("Already created draft for this template");
DescriptionTemplateEntity data = new DescriptionTemplateEntity(); DescriptionTemplateEntity data = new DescriptionTemplateEntity();
data.setId(UUID.randomUUID()); data.setId(UUID.randomUUID());

View File

@ -5,6 +5,7 @@ import eu.eudat.commons.enums.DmpBlueprintSystemFieldType;
import eu.eudat.data.DmpBlueprintEntity; import eu.eudat.data.DmpBlueprintEntity;
import eu.eudat.model.DmpBlueprint; import eu.eudat.model.DmpBlueprint;
import eu.eudat.model.persist.DmpBlueprintPersist; import eu.eudat.model.persist.DmpBlueprintPersist;
import eu.eudat.model.persist.NewVersionDmpBlueprintPersist;
import gr.cite.tools.exception.MyApplicationException; import gr.cite.tools.exception.MyApplicationException;
import gr.cite.tools.exception.MyForbiddenException; import gr.cite.tools.exception.MyForbiddenException;
import gr.cite.tools.exception.MyNotFoundException; import gr.cite.tools.exception.MyNotFoundException;
@ -31,6 +32,8 @@ public interface DmpBlueprintService {
DmpBlueprint buildClone(UUID id, FieldSet fields) throws MyForbiddenException, MyValidationException, MyApplicationException, MyNotFoundException; DmpBlueprint buildClone(UUID id, FieldSet fields) throws MyForbiddenException, MyValidationException, MyApplicationException, MyNotFoundException;
DmpBlueprint createNewVersion(NewVersionDmpBlueprintPersist model, FieldSet fieldSet) throws MyForbiddenException, MyValidationException, MyApplicationException, MyNotFoundException, InvalidApplicationException, JAXBException, ParserConfigurationException, JsonProcessingException, TransformerException;
ResponseEntity<byte[]> exportXml(UUID id) throws MyForbiddenException, MyNotFoundException, JAXBException, ParserConfigurationException, IOException, InstantiationException, IllegalAccessException, SAXException, TransformerException, InvalidApplicationException; ResponseEntity<byte[]> exportXml(UUID id) throws MyForbiddenException, MyNotFoundException, JAXBException, ParserConfigurationException, IOException, InstantiationException, IllegalAccessException, SAXException, TransformerException, InvalidApplicationException;
DmpBlueprint importXml(byte[] bytes, String label, FieldSet fields) throws MyForbiddenException, MyNotFoundException, JAXBException, ParserConfigurationException, TransformerException, InvalidApplicationException, IOException, InstantiationException, IllegalAccessException, SAXException; DmpBlueprint importXml(byte[] bytes, String label, FieldSet fields) throws MyForbiddenException, MyNotFoundException, JAXBException, ParserConfigurationException, TransformerException, InvalidApplicationException, IOException, InstantiationException, IllegalAccessException, SAXException;
} }

View File

@ -4,10 +4,7 @@ import com.fasterxml.jackson.core.JsonProcessingException;
import eu.eudat.authorization.AuthorizationFlags; import eu.eudat.authorization.AuthorizationFlags;
import eu.eudat.authorization.Permission; import eu.eudat.authorization.Permission;
import eu.eudat.commons.XmlHandlingService; import eu.eudat.commons.XmlHandlingService;
import eu.eudat.commons.enums.DmpBlueprintFieldCategory; import eu.eudat.commons.enums.*;
import eu.eudat.commons.enums.DmpBlueprintStatus;
import eu.eudat.commons.enums.DmpBlueprintSystemFieldType;
import eu.eudat.commons.enums.IsActive;
import eu.eudat.commons.types.dmpblueprint.*; import eu.eudat.commons.types.dmpblueprint.*;
import eu.eudat.commons.types.dmpblueprint.importexport.*; import eu.eudat.commons.types.dmpblueprint.importexport.*;
import eu.eudat.convention.ConventionService; import eu.eudat.convention.ConventionService;
@ -17,11 +14,12 @@ import eu.eudat.model.DmpBlueprint;
import eu.eudat.model.builder.DmpBlueprintBuilder; import eu.eudat.model.builder.DmpBlueprintBuilder;
import eu.eudat.model.deleter.DmpBlueprintDeleter; import eu.eudat.model.deleter.DmpBlueprintDeleter;
import eu.eudat.model.dmpblueprintdefinition.Definition; import eu.eudat.model.dmpblueprintdefinition.Definition;
import eu.eudat.model.dmpblueprintdefinition.DescriptionTemplate;
import eu.eudat.model.dmpblueprintdefinition.Field; import eu.eudat.model.dmpblueprintdefinition.Field;
import eu.eudat.model.dmpblueprintdefinition.Section; import eu.eudat.model.dmpblueprintdefinition.Section;
import eu.eudat.model.persist.DmpBlueprintPersist; import eu.eudat.model.persist.DmpBlueprintPersist;
import eu.eudat.model.persist.NewVersionDmpBlueprintPersist;
import eu.eudat.model.persist.dmpblueprintdefinition.*; import eu.eudat.model.persist.dmpblueprintdefinition.*;
import eu.eudat.query.DescriptionTemplateQuery;
import eu.eudat.query.DmpBlueprintQuery; import eu.eudat.query.DmpBlueprintQuery;
import eu.eudat.service.responseutils.ResponseUtilsService; import eu.eudat.service.responseutils.ResponseUtilsService;
import gr.cite.commons.web.authz.service.AuthorizationService; import gr.cite.commons.web.authz.service.AuthorizationService;
@ -39,6 +37,7 @@ import gr.cite.tools.logging.MapLogEntry;
import gr.cite.tools.validation.ValidatorFactory; import gr.cite.tools.validation.ValidatorFactory;
import jakarta.persistence.EntityManager; import jakarta.persistence.EntityManager;
import jakarta.xml.bind.JAXBException; import jakarta.xml.bind.JAXBException;
import org.apache.bcel.generic.DADD;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -127,13 +126,21 @@ public class DmpBlueprintServiceImpl implements DmpBlueprintService {
throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{model.getId(), DmpBlueprint.class.getSimpleName()}, LocaleContextHolder.getLocale())); throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{model.getId(), DmpBlueprint.class.getSimpleName()}, LocaleContextHolder.getLocale()));
if (!this.conventionService.hashValue(data.getUpdatedAt()).equals(model.getHash())) if (!this.conventionService.hashValue(data.getUpdatedAt()).equals(model.getHash()))
throw new MyValidationException(this.errors.getHashConflict().getCode(), this.errors.getHashConflict().getMessage()); throw new MyValidationException(this.errors.getHashConflict().getCode(), this.errors.getHashConflict().getMessage());
if (data.getStatus().equals(DmpBlueprintStatus.Finalized))
throw new MyForbiddenException("Cannot update finalized blueprint");
} else { } else {
data = new DmpBlueprintEntity(); data = new DmpBlueprintEntity();
data.setId(UUID.randomUUID()); data.setId(UUID.randomUUID());
data.setIsActive(IsActive.Active); data.setStatus(DmpBlueprintStatus.Draft);
data.setGroupId(UUID.randomUUID());
data.setVersion((short) 1);
data.setVersionStatus(DmpBlueprintVersionStatus.NotFinalized);
data.setCreatedAt(Instant.now()); data.setCreatedAt(Instant.now());
data.setIsActive(IsActive.Active);
} }
DmpBlueprintStatus previousStatus = data.getStatus();
if (model.getDefinition() != null && !model.getDefinition().getSections().stream().anyMatch(x -> x.getHasTemplates())) { if (model.getDefinition() != null && !model.getDefinition().getSections().stream().anyMatch(x -> x.getHasTemplates())) {
throw new MyValidationException(this.errors.getDmpBlueprintHasNoDescriptionTemplates().getCode(), this.errors.getDmpBlueprintHasNoDescriptionTemplates().getMessage()); throw new MyValidationException(this.errors.getDmpBlueprintHasNoDescriptionTemplates().getCode(), this.errors.getDmpBlueprintHasNoDescriptionTemplates().getMessage());
} }
@ -150,9 +157,43 @@ public class DmpBlueprintServiceImpl implements DmpBlueprintService {
this.entityManager.flush(); this.entityManager.flush();
this.updateVersionStatusAndSave(data, previousStatus, data.getStatus());
this.entityManager.flush();
return this.builderFactory.builder(DmpBlueprintBuilder.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermissionOrPublic).build(BaseFieldSet.build(fields, DmpBlueprint._id), data); return this.builderFactory.builder(DmpBlueprintBuilder.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermissionOrPublic).build(BaseFieldSet.build(fields, DmpBlueprint._id), data);
} }
private void updateVersionStatusAndSave(DmpBlueprintEntity data, DmpBlueprintStatus previousStatus, DmpBlueprintStatus newStatus) {
if (previousStatus.equals(newStatus))
return;
if (previousStatus.equals(DmpBlueprintStatus.Finalized))
throw new MyForbiddenException("Can not update finalized blueprint");
if (newStatus.equals(DmpBlueprintStatus.Finalized)) {
List<DmpBlueprintEntity> latestVersionDmpBlueprints = this.queryFactory.query(DmpBlueprintQuery.class)
.versionStatuses(DmpBlueprintVersionStatus.Current)
.isActive(IsActive.Active)
.groupIds(data.getGroupId())
.collect();
if (latestVersionDmpBlueprints.size() > 1)
throw new MyValidationException("Multiple previous blueprints found");
DmpBlueprintEntity oldDmpBlueprintEntity = latestVersionDmpBlueprints.stream().findFirst().orElse(null);
data.setVersionStatus(DmpBlueprintVersionStatus.Current);
if (oldDmpBlueprintEntity != null) {
data.setVersion((short) (oldDmpBlueprintEntity.getVersion() + 1));
oldDmpBlueprintEntity.setVersionStatus(DmpBlueprintVersionStatus.Previous);
this.entityManager.merge(oldDmpBlueprintEntity);
} else {
data.setVersion((short) 1);
}
}
}
private @NotNull DefinitionEntity buildDefinitionEntity(DefinitionPersist persist) { private @NotNull DefinitionEntity buildDefinitionEntity(DefinitionPersist persist) {
DefinitionEntity data = new DefinitionEntity(); DefinitionEntity data = new DefinitionEntity();
if (persist == null) if (persist == null)
@ -327,6 +368,63 @@ public class DmpBlueprintServiceImpl implements DmpBlueprintService {
model.setId(UUID.randomUUID()); model.setId(UUID.randomUUID());
} }
//endregion
//region NewVersion
@Override
public DmpBlueprint createNewVersion(NewVersionDmpBlueprintPersist model, FieldSet fields) throws MyForbiddenException, MyValidationException, MyApplicationException, MyNotFoundException, InvalidApplicationException, JAXBException, ParserConfigurationException, JsonProcessingException, TransformerException {
logger.debug(new MapLogEntry("persisting data dmpBlueprint").And("model", model).And("fields", fields));
this.authorizationService.authorizeForce(Permission.CreateNewVersionDmpBlueprint);
DmpBlueprintEntity oldDmpBlueprintEntity = this.entityManager.find(DmpBlueprintEntity.class, model.getId());
if (oldDmpBlueprintEntity == null)
throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{model.getId(), DmpBlueprint.class.getSimpleName()}, LocaleContextHolder.getLocale()));
if (!this.conventionService.hashValue(oldDmpBlueprintEntity.getUpdatedAt()).equals(model.getHash()))
throw new MyValidationException(this.errors.getHashConflict().getCode(), this.errors.getHashConflict().getMessage());
List<DmpBlueprintEntity> latestVersionDmpBlueprints = this.queryFactory.query(DmpBlueprintQuery.class)
.versionStatuses(DmpBlueprintVersionStatus.Current)
.isActive(IsActive.Active)
.groupIds(oldDmpBlueprintEntity.getGroupId())
.collect();
if (latestVersionDmpBlueprints.isEmpty())
throw new MyValidationException("Previous blueprint not found");
if (latestVersionDmpBlueprints.size() > 1)
throw new MyValidationException("Multiple previous blueprints found");
if (!latestVersionDmpBlueprints.getFirst().getVersion().equals(oldDmpBlueprintEntity.getVersion()))
throw new MyValidationException(this.errors.getDmpBlueprintNewVersionConflict().getCode(), this.errors.getDmpBlueprintNewVersionConflict().getMessage());
Long notFinalizedCount = this.queryFactory.query(DmpBlueprintQuery.class)
.versionStatuses(DmpBlueprintVersionStatus.NotFinalized)
.groupIds(oldDmpBlueprintEntity.getGroupId())
.isActive(IsActive.Active)
.count();
if (notFinalizedCount > 0)
throw new MyValidationException("Already created draft for this blueprint");
DmpBlueprintEntity data = new DmpBlueprintEntity();
data.setId(UUID.randomUUID());
data.setLabel(model.getLabel());
data.setStatus(model.getStatus());
data.setDefinition(this.xmlHandlingService.toXml(this.buildDefinitionEntity(model.getDefinition())));
data.setGroupId(oldDmpBlueprintEntity.getGroupId());
data.setVersion((short) (oldDmpBlueprintEntity.getVersion() + 1));
data.setVersionStatus(DmpBlueprintVersionStatus.NotFinalized);
data.setCreatedAt(Instant.now());
data.setUpdatedAt(Instant.now());
data.setIsActive(IsActive.Active);
this.entityManager.persist(data);
this.entityManager.flush();
this.updateVersionStatusAndSave(data, DmpBlueprintStatus.Draft, data.getStatus());
this.entityManager.flush();
return this.builderFactory.builder(DmpBlueprintBuilder.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermissionOrPublic).build(BaseFieldSet.build(fields, DmpBlueprint._id), data);
}
//endregion //endregion

View File

@ -3,6 +3,7 @@ package eu.eudat.controllers.v2;
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonProcessingException;
import eu.eudat.audit.AuditableAction; import eu.eudat.audit.AuditableAction;
import eu.eudat.authorization.AuthorizationFlags; import eu.eudat.authorization.AuthorizationFlags;
import eu.eudat.model.persist.NewVersionDmpBlueprintPersist;
import gr.cite.tools.validation.ValidationFilterAnnotation; import gr.cite.tools.validation.ValidationFilterAnnotation;
import eu.eudat.data.DmpBlueprintEntity; import eu.eudat.data.DmpBlueprintEntity;
import eu.eudat.model.DmpBlueprint; import eu.eudat.model.DmpBlueprint;
@ -153,6 +154,21 @@ public class DmpBlueprintController {
return model; return model;
} }
@PostMapping("new-version")
@Transactional
@ValidationFilterAnnotation(validator = NewVersionDmpBlueprintPersist.NewVersionDmpBlueprintPersistValidator.ValidatorName, argumentName = "model")
public DmpBlueprint createNewVersion(@RequestBody NewVersionDmpBlueprintPersist model, FieldSet fieldSet) throws JAXBException, InvalidApplicationException, ParserConfigurationException, JsonProcessingException, TransformerException {
logger.debug(new MapLogEntry("persisting" + NewVersionDmpBlueprintPersist.class.getSimpleName()).And("model", model).And("fieldSet", fieldSet));
DmpBlueprint persisted = this.dmpBlueprintService.createNewVersion(model, fieldSet);
this.auditService.track(AuditableAction.DmpBlueprint_PersistNewVersion, Map.ofEntries(
new AbstractMap.SimpleEntry<String, Object>("model", model),
new AbstractMap.SimpleEntry<String, Object>("fields", fieldSet)
));
return persisted;
}
@RequestMapping(method = RequestMethod.GET, value = {"/xml/export/{id}"}, produces = "application/xml") @RequestMapping(method = RequestMethod.GET, value = {"/xml/export/{id}"}, produces = "application/xml")
public @ResponseBody ResponseEntity<byte[]> getXml(@PathVariable UUID id) throws JAXBException, ParserConfigurationException, IOException, TransformerException, InstantiationException, IllegalAccessException, SAXException, InvalidApplicationException { public @ResponseBody ResponseEntity<byte[]> getXml(@PathVariable UUID id) throws JAXBException, ParserConfigurationException, IOException, TransformerException, InstantiationException, IllegalAccessException, SAXException, InvalidApplicationException {
logger.debug(new MapLogEntry("export" + DmpBlueprint.class.getSimpleName()).And("id", id)); logger.debug(new MapLogEntry("export" + DmpBlueprint.class.getSimpleName()).And("id", id));

View File

@ -50,3 +50,6 @@ error-thesaurus:
dmp-blueprint-has-no-description-templates: dmp-blueprint-has-no-description-templates:
code: 120 code: 120
message: You need to select Has Description Templates field to at least one Section. message: You need to select Has Description Templates field to at least one Section.
dmp-blueprint-new-version-conflict:
code: 121
message: version to update not the latest

View File

@ -404,6 +404,12 @@ permissions:
clients: [ ] clients: [ ]
allowAnonymous: false allowAnonymous: false
allowAuthenticated: false allowAuthenticated: false
CreateNewVersionDmpBlueprint:
roles:
- Admin
clients: [ ]
allowAnonymous: false
allowAuthenticated: false
ExportDmpBlueprint: ExportDmpBlueprint:
roles: roles:
- Admin - Admin