Merge branch 'dmp-refactoring' of https://code-repo.d4science.org/MaDgiK-CITE/argos into dmp-refactoring

This commit is contained in:
Sofia Papacharalampous 2024-07-08 10:52:24 +03:00
commit 730863212a
21 changed files with 1115 additions and 174 deletions

View File

@ -7,7 +7,7 @@ import org.opencdmp.commons.validation.BaseValidator;
import org.opencdmp.convention.ConventionService;
import org.opencdmp.data.PlanBlueprintEntity;
import org.opencdmp.errorcode.ErrorThesaurusProperties;
import org.opencdmp.model.persist.dmpblueprintdefinition.DefinitionPersist;
import org.opencdmp.model.persist.planblueprintdefinition.DefinitionPersist;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Scope;

View File

@ -1,14 +1,14 @@
package org.opencdmp.model.persist;
import org.opencdmp.commons.enums.PlanBlueprintStatus;
import org.opencdmp.commons.validation.BaseValidator;
import gr.cite.tools.validation.ValidatorFactory;
import gr.cite.tools.validation.specification.Specification;
import jakarta.validation.constraints.Size;
import org.opencdmp.commons.enums.PlanBlueprintStatus;
import org.opencdmp.commons.validation.BaseValidator;
import org.opencdmp.convention.ConventionService;
import org.opencdmp.data.PlanBlueprintEntity;
import org.opencdmp.errorcode.ErrorThesaurusProperties;
import org.opencdmp.model.persist.dmpblueprintdefinition.DefinitionPersist;
import jakarta.validation.constraints.Size;
import org.opencdmp.model.persist.planblueprintdefinition.DefinitionPersist;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Scope;
@ -26,11 +26,11 @@ public class PlanBlueprintPersist {
public static final String _id = "id";
@Size(max = PlanBlueprintEntity._labelLength, message = "{validation.largerthanmax}")
private String label = null;
private String label;
public static final String _label = "label";
private DefinitionPersist definition = null;
private DefinitionPersist definition;
public static final String _definition = "definition";
@ -43,7 +43,7 @@ public class PlanBlueprintPersist {
public static final String _hash = "hash";
public UUID getId() {
return id;
return this.id;
}
public void setId(UUID id) {
@ -51,7 +51,7 @@ public class PlanBlueprintPersist {
}
public String getLabel() {
return label;
return this.label;
}
public void setLabel(String label) {
@ -59,7 +59,7 @@ public class PlanBlueprintPersist {
}
public DefinitionPersist getDefinition() {
return definition;
return this.definition;
}
public void setDefinition(DefinitionPersist definition) {
@ -67,7 +67,7 @@ public class PlanBlueprintPersist {
}
public PlanBlueprintStatus getStatus() {
return status;
return this.status;
}
public void setStatus(PlanBlueprintStatus status) {
@ -75,7 +75,7 @@ public class PlanBlueprintPersist {
}
public String getHash() {
return hash;
return this.hash;
}
public void setHash(String hash) {
@ -109,26 +109,26 @@ public class PlanBlueprintPersist {
this.spec()
.iff(() -> this.isValidGuid(item.getId()))
.must(() -> this.isValidHash(item.getHash()))
.failOn(PlanBlueprintPersist._hash).failWith(messageSource.getMessage("Validation_Required", new Object[]{PlanBlueprintPersist._hash}, LocaleContextHolder.getLocale())),
.failOn(PlanBlueprintPersist._hash).failWith(this.messageSource.getMessage("Validation_Required", new Object[]{PlanBlueprintPersist._hash}, LocaleContextHolder.getLocale())),
this.spec()
.iff(() -> !this.isValidGuid(item.getId()))
.must(() -> !this.isValidHash(item.getHash()))
.failOn(PlanBlueprintPersist._hash).failWith(messageSource.getMessage("Validation_OverPosting", new Object[]{}, LocaleContextHolder.getLocale())),
.failOn(PlanBlueprintPersist._hash).failWith(this.messageSource.getMessage("Validation_OverPosting", new Object[]{}, LocaleContextHolder.getLocale())),
this.spec()
.must(() -> !this.isEmpty(item.getLabel()))
.failOn(PlanBlueprintPersist._label).failWith(messageSource.getMessage("Validation_Required", new Object[]{PlanBlueprintPersist._label}, LocaleContextHolder.getLocale())),
.failOn(PlanBlueprintPersist._label).failWith(this.messageSource.getMessage("Validation_Required", new Object[]{PlanBlueprintPersist._label}, LocaleContextHolder.getLocale())),
this.spec()
.iff(() -> !this.isEmpty(item.getLabel()))
.must(() -> this.lessEqualLength(item.getLabel(), PlanBlueprintEntity._labelLength))
.failOn(PlanBlueprintPersist._label).failWith(messageSource.getMessage("Validation_MaxLength", new Object[]{PlanBlueprintPersist._label}, LocaleContextHolder.getLocale())),
.failOn(PlanBlueprintPersist._label).failWith(this.messageSource.getMessage("Validation_MaxLength", new Object[]{PlanBlueprintPersist._label}, LocaleContextHolder.getLocale())),
this.spec()
.must(() -> !this.isNull(item.getStatus()))
.failOn(PlanBlueprintPersist._status).failWith(messageSource.getMessage("Validation_Required", new Object[]{PlanBlueprintPersist._status}, LocaleContextHolder.getLocale())),
.failOn(PlanBlueprintPersist._status).failWith(this.messageSource.getMessage("Validation_Required", new Object[]{PlanBlueprintPersist._status}, LocaleContextHolder.getLocale())),
this.spec()
.iff(() -> item.getStatus() == PlanBlueprintStatus.Finalized)
.must(() -> !this.isNull(item.getDefinition()))
.failOn(PlanBlueprintPersist._definition).failWith(messageSource.getMessage("Validation_Required", new Object[]{PlanBlueprintPersist._definition}, LocaleContextHolder.getLocale())),
.failOn(PlanBlueprintPersist._definition).failWith(this.messageSource.getMessage("Validation_Required", new Object[]{PlanBlueprintPersist._definition}, LocaleContextHolder.getLocale())),
this.refSpec()
.iff(() -> !this.isNull(item.getDefinition()))
.on(PlanBlueprintPersist._definition)

View File

@ -1,8 +1,8 @@
package org.opencdmp.model.persist.dmpblueprintdefinition;
package org.opencdmp.model.persist.planblueprintdefinition;
import org.opencdmp.commons.validation.BaseValidator;
import gr.cite.tools.validation.ValidatorFactory;
import gr.cite.tools.validation.specification.Specification;
import org.opencdmp.commons.validation.BaseValidator;
import org.opencdmp.convention.ConventionService;
import org.opencdmp.errorcode.ErrorThesaurusProperties;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
@ -16,12 +16,12 @@ import java.util.List;
public class DefinitionPersist {
private List<SectionPersist> sections = null;
private List<SectionPersist> sections;
public static final String _sections = "sections";
public List<SectionPersist> getSections() {
return sections;
return this.sections;
}
public void setSections(List<SectionPersist> sections) {
@ -57,7 +57,7 @@ public class DefinitionPersist {
return Arrays.asList(
this.spec()
.must(() -> !this.isListNullOrEmpty(item.getSections()))
.failOn(DefinitionPersist._sections).failWith(messageSource.getMessage("Validation_Required", new Object[]{DefinitionPersist._sections}, LocaleContextHolder.getLocale())),
.failOn(DefinitionPersist._sections).failWith(this.messageSource.getMessage("Validation_Required", new Object[]{DefinitionPersist._sections}, LocaleContextHolder.getLocale())),
this.navSpec()
.iff(() -> !this.isListNullOrEmpty(item.getSections()))
.on(DefinitionPersist._sections)

View File

@ -1,7 +1,7 @@
package org.opencdmp.model.persist.dmpblueprintdefinition;
package org.opencdmp.model.persist.planblueprintdefinition;
import org.opencdmp.commons.validation.BaseValidator;
import gr.cite.tools.validation.specification.Specification;
import org.opencdmp.commons.validation.BaseValidator;
import org.opencdmp.convention.ConventionService;
import org.opencdmp.errorcode.ErrorThesaurusProperties;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
@ -16,24 +16,24 @@ import java.util.UUID;
public class DescriptionTemplatePersist {
private UUID descriptionTemplateGroupId = null;
private UUID descriptionTemplateGroupId;
public static final String _descriptionTemplateGroupId = "descriptionTemplateGroupId";
private String label = null;
private String label;
public static final String _label = "label";
private Integer minMultiplicity = null;
private Integer minMultiplicity;
public static final String _minMultiplicity = "minMultiplicity";
private Integer maxMultiplicity = null;
private Integer maxMultiplicity;
public static final String _maxMultiplicity = "maxMultiplicity";
public UUID getDescriptionTemplateGroupId() {
return descriptionTemplateGroupId;
return this.descriptionTemplateGroupId;
}
public void setDescriptionTemplateGroupId(UUID descriptionTemplateGroupId) {
@ -41,7 +41,7 @@ public class DescriptionTemplatePersist {
}
public String getLabel() {
return label;
return this.label;
}
public void setLabel(String label) {
@ -49,7 +49,7 @@ public class DescriptionTemplatePersist {
}
public Integer getMinMultiplicity() {
return minMultiplicity;
return this.minMultiplicity;
}
public void setMinMultiplicity(Integer minMultiplicity) {
@ -57,7 +57,7 @@ public class DescriptionTemplatePersist {
}
public Integer getMaxMultiplicity() {
return maxMultiplicity;
return this.maxMultiplicity;
}
public void setMaxMultiplicity(Integer maxMultiplicity) {
@ -87,15 +87,15 @@ public class DescriptionTemplatePersist {
return Arrays.asList(
this.spec()
.must(() -> this.isValidGuid(item.getDescriptionTemplateGroupId()))
.failOn(DescriptionTemplatePersist._descriptionTemplateGroupId).failWith(messageSource.getMessage("Validation_Required", new Object[]{DescriptionTemplatePersist._descriptionTemplateGroupId}, LocaleContextHolder.getLocale())),
.failOn(DescriptionTemplatePersist._descriptionTemplateGroupId).failWith(this.messageSource.getMessage("Validation_Required", new Object[]{DescriptionTemplatePersist._descriptionTemplateGroupId}, LocaleContextHolder.getLocale())),
this.spec()
.iff(() -> !this.isNull(item.getMinMultiplicity()))
.must(() -> item.getMinMultiplicity() >= 0)
.failOn(DescriptionTemplatePersist._minMultiplicity).failWith(messageSource.getMessage("Validation_UnexpectedValue", new Object[]{DescriptionTemplatePersist._minMultiplicity}, LocaleContextHolder.getLocale())),
.failOn(DescriptionTemplatePersist._minMultiplicity).failWith(this.messageSource.getMessage("Validation_UnexpectedValue", new Object[]{DescriptionTemplatePersist._minMultiplicity}, LocaleContextHolder.getLocale())),
this.spec()
.iff(() -> !this.isNull(item.getMaxMultiplicity()))
.must(() -> item.getMaxMultiplicity() > 0)
.failOn(DescriptionTemplatePersist._maxMultiplicity).failWith(messageSource.getMessage("Validation_UnexpectedValue", new Object[]{DescriptionTemplatePersist._maxMultiplicity}, LocaleContextHolder.getLocale()))
.failOn(DescriptionTemplatePersist._maxMultiplicity).failWith(this.messageSource.getMessage("Validation_UnexpectedValue", new Object[]{DescriptionTemplatePersist._maxMultiplicity}, LocaleContextHolder.getLocale()))
);
}
}

View File

@ -1,7 +1,7 @@
package org.opencdmp.model.persist.dmpblueprintdefinition;
package org.opencdmp.model.persist.planblueprintdefinition;
import org.opencdmp.commons.enums.PlanBlueprintExtraFieldDataType;
import gr.cite.tools.validation.specification.Specification;
import org.opencdmp.commons.enums.PlanBlueprintExtraFieldDataType;
import org.opencdmp.convention.ConventionService;
import org.opencdmp.errorcode.ErrorThesaurusProperties;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
@ -20,7 +20,7 @@ public class ExtraFieldPersist extends FieldPersist {
public static final String _dataType = "dataType";
public PlanBlueprintExtraFieldDataType getDataType() {
return dataType;
return this.dataType;
}
public void setDataType(PlanBlueprintExtraFieldDataType dataType) {
@ -44,14 +44,14 @@ public class ExtraFieldPersist extends FieldPersist {
@Override
protected List<Specification> specifications(ExtraFieldPersist item) {
List<Specification> specifications = getBaseSpecifications(item);
List<Specification> specifications = this.getBaseSpecifications(item);
specifications.addAll(Arrays.asList(
this.spec()
.must(() -> !this.isEmpty(item.getLabel()))
.failOn(FieldPersist._label).failWith(messageSource.getMessage("Validation_Required", new Object[]{FieldPersist._label}, LocaleContextHolder.getLocale())),
.failOn(FieldPersist._label).failWith(this.messageSource.getMessage("Validation_Required", new Object[]{FieldPersist._label}, LocaleContextHolder.getLocale())),
this.spec()
.must(() -> !this.isNull(item.getDataType()))
.failOn(ExtraFieldPersist._dataType).failWith(messageSource.getMessage("Validation_Required", new Object[]{ExtraFieldPersist._dataType}, LocaleContextHolder.getLocale()))
.failOn(ExtraFieldPersist._dataType).failWith(this.messageSource.getMessage("Validation_Required", new Object[]{ExtraFieldPersist._dataType}, LocaleContextHolder.getLocale()))
));
return specifications;
}

View File

@ -1,10 +1,10 @@
package org.opencdmp.model.persist.dmpblueprintdefinition;
package org.opencdmp.model.persist.planblueprintdefinition;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import gr.cite.tools.validation.specification.Specification;
import org.opencdmp.commons.enums.PlanBlueprintFieldCategory;
import org.opencdmp.commons.validation.BaseValidator;
import gr.cite.tools.validation.specification.Specification;
import org.opencdmp.convention.ConventionService;
import org.opencdmp.errorcode.ErrorThesaurusProperties;
import org.springframework.context.MessageSource;
@ -27,7 +27,7 @@ import java.util.UUID;
})
public abstract class FieldPersist {
private UUID id = null;
private UUID id;
public static final String _id = "id";
@ -35,29 +35,29 @@ public abstract class FieldPersist {
public static final String _category = "category";
private String label = null;
private String label;
public static final String _label = "label";
private String placeholder = null;
private String placeholder;
public static final String _placeholder = "placeholder";
private String description;
private List<String> semantics = null;
private List<String> semantics;
public final static String _semantics = "semantics";
private Integer ordinal = null;
private Integer ordinal;
public static final String _ordinal = "ordinal";
private Boolean required = null;
private Boolean required;
public static final String _required = "required";
public UUID getId() {
return id;
return this.id;
}
public void setId(UUID id) {
@ -65,7 +65,7 @@ public abstract class FieldPersist {
}
public PlanBlueprintFieldCategory getCategory() {
return category;
return this.category;
}
public void setCategory(PlanBlueprintFieldCategory category) {
@ -73,7 +73,7 @@ public abstract class FieldPersist {
}
public String getLabel() {
return label;
return this.label;
}
public void setLabel(String label) {
@ -81,7 +81,7 @@ public abstract class FieldPersist {
}
public String getPlaceholder() {
return placeholder;
return this.placeholder;
}
public void setPlaceholder(String placeholder) {
@ -89,7 +89,7 @@ public abstract class FieldPersist {
}
public List<String> getSemantics() {
return semantics;
return this.semantics;
}
public void setSemantics(List<String> semantics) {
@ -97,7 +97,7 @@ public abstract class FieldPersist {
}
public String getDescription() {
return description;
return this.description;
}
public void setDescription(String description) {
@ -105,7 +105,7 @@ public abstract class FieldPersist {
}
public Integer getOrdinal() {
return ordinal;
return this.ordinal;
}
public void setOrdinal(Integer ordinal) {
@ -113,7 +113,7 @@ public abstract class FieldPersist {
}
public Boolean getRequired() {
return required;
return this.required;
}
public void setRequired(Boolean required) {
@ -134,16 +134,16 @@ public abstract class FieldPersist {
specifications.addAll( Arrays.asList(
this.spec()
.must(() -> this.isValidGuid(item.getId()))
.failOn(FieldPersist._id).failWith(messageSource.getMessage("Validation_Required", new Object[]{FieldPersist._id}, LocaleContextHolder.getLocale())),
.failOn(FieldPersist._id).failWith(this.messageSource.getMessage("Validation_Required", new Object[]{FieldPersist._id}, LocaleContextHolder.getLocale())),
this.spec()
.must(() -> !this.isNull(item.getCategory()))
.failOn(FieldPersist._category).failWith(messageSource.getMessage("Validation_Required", new Object[]{FieldPersist._category}, LocaleContextHolder.getLocale())),
.failOn(FieldPersist._category).failWith(this.messageSource.getMessage("Validation_Required", new Object[]{FieldPersist._category}, LocaleContextHolder.getLocale())),
this.spec()
.must(() -> !this.isNull(item.getOrdinal()))
.failOn(FieldPersist._ordinal).failWith(messageSource.getMessage("Validation_Required", new Object[]{FieldPersist._ordinal}, LocaleContextHolder.getLocale())),
.failOn(FieldPersist._ordinal).failWith(this.messageSource.getMessage("Validation_Required", new Object[]{FieldPersist._ordinal}, LocaleContextHolder.getLocale())),
this.spec()
.must(() -> !this.isNull(item.getRequired()))
.failOn(FieldPersist._required).failWith(messageSource.getMessage("Validation_Required", new Object[]{FieldPersist._required}, LocaleContextHolder.getLocale()))
.failOn(FieldPersist._required).failWith(this.messageSource.getMessage("Validation_Required", new Object[]{FieldPersist._required}, LocaleContextHolder.getLocale()))
));
return specifications;
}

View File

@ -1,8 +1,8 @@
package org.opencdmp.model.persist.dmpblueprintdefinition;
package org.opencdmp.model.persist.planblueprintdefinition;
import gr.cite.tools.validation.specification.Specification;
import org.opencdmp.convention.ConventionService;
import org.opencdmp.errorcode.ErrorThesaurusProperties;
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;
@ -25,7 +25,7 @@ public class ReferenceTypeFieldPersist extends FieldPersist {
public UUID getReferenceTypeId() {
return referenceTypeId;
return this.referenceTypeId;
}
public void setReferenceTypeId(UUID referenceTypeId) {
@ -33,7 +33,7 @@ public class ReferenceTypeFieldPersist extends FieldPersist {
}
public Boolean getMultipleSelect() {
return multipleSelect;
return this.multipleSelect;
}
public void setMultipleSelect(Boolean multipleSelect) {
@ -57,14 +57,14 @@ public class ReferenceTypeFieldPersist extends FieldPersist {
@Override
protected List<Specification> specifications(ReferenceTypeFieldPersist item) {
List<Specification> specifications = getBaseSpecifications(item);
List<Specification> specifications = this.getBaseSpecifications(item);
specifications.addAll(Arrays.asList(
this.spec()
.must(() -> !this.isNull(item.getReferenceTypeId()))
.failOn(ReferenceTypeFieldPersist._referenceTypeId).failWith(messageSource.getMessage("Validation_Required", new Object[]{ReferenceTypeFieldPersist._referenceTypeId}, LocaleContextHolder.getLocale())),
.failOn(ReferenceTypeFieldPersist._referenceTypeId).failWith(this.messageSource.getMessage("Validation_Required", new Object[]{ReferenceTypeFieldPersist._referenceTypeId}, LocaleContextHolder.getLocale())),
this.spec()
.must(() -> !this.isNull(item.getMultipleSelect()))
.failOn(ReferenceTypeFieldPersist._multipleSelect).failWith(messageSource.getMessage("Validation_Required", new Object[]{ReferenceTypeFieldPersist._multipleSelect}, LocaleContextHolder.getLocale())))
.failOn(ReferenceTypeFieldPersist._multipleSelect).failWith(this.messageSource.getMessage("Validation_Required", new Object[]{ReferenceTypeFieldPersist._multipleSelect}, LocaleContextHolder.getLocale())))
);
return specifications;

View File

@ -1,9 +1,9 @@
package org.opencdmp.model.persist.dmpblueprintdefinition;
package org.opencdmp.model.persist.planblueprintdefinition;
import org.opencdmp.commons.validation.BaseValidator;
import gr.cite.tools.exception.MyApplicationException;
import gr.cite.tools.validation.ValidatorFactory;
import gr.cite.tools.validation.specification.Specification;
import org.opencdmp.commons.validation.BaseValidator;
import org.opencdmp.convention.ConventionService;
import org.opencdmp.errorcode.ErrorThesaurusProperties;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
@ -19,38 +19,38 @@ import java.util.stream.Collectors;
public class SectionPersist {
private UUID id = null;
private UUID id;
public static final String _id = "id";
private String description;
private String label = null;
private String label;
public static final String _label = "label";
private Integer ordinal = null;
private Integer ordinal;
public static final String _ordinal = "ordinal";
private Boolean hasTemplates = null;
private Boolean hasTemplates;
public static final String _hasTemplates = "hasTemplates";
private List<FieldPersist> fields = null;
private List<FieldPersist> fields;
public static final String _fields = "fields";
private List<DescriptionTemplatePersist> descriptionTemplates = null;
private List<DescriptionTemplatePersist> descriptionTemplates;
public static final String _descriptionTemplates = "descriptionTemplates";
private List<UUID> prefillingSourcesIds= null;
private List<UUID> prefillingSourcesIds;
public static final String _prefillingSourcesIds = "prefillingSourcesIds";
public UUID getId() {
return id;
return this.id;
}
public void setId(UUID id) {
@ -58,7 +58,7 @@ public class SectionPersist {
}
public String getLabel() {
return label;
return this.label;
}
public void setLabel(String label) {
@ -66,7 +66,7 @@ public class SectionPersist {
}
public String getDescription() {
return description;
return this.description;
}
public void setDescription(String description) {
@ -74,7 +74,7 @@ public class SectionPersist {
}
public Integer getOrdinal() {
return ordinal;
return this.ordinal;
}
public void setOrdinal(Integer ordinal) {
@ -82,7 +82,7 @@ public class SectionPersist {
}
public Boolean getHasTemplates() {
return hasTemplates;
return this.hasTemplates;
}
public void setHasTemplates(Boolean hasTemplates) {
@ -90,7 +90,7 @@ public class SectionPersist {
}
public List<FieldPersist> getFields() {
return fields;
return this.fields;
}
public void setFields(List<FieldPersist> fields) {
@ -98,7 +98,7 @@ public class SectionPersist {
}
public List<DescriptionTemplatePersist> getDescriptionTemplates() {
return descriptionTemplates;
return this.descriptionTemplates;
}
public void setDescriptionTemplates(List<DescriptionTemplatePersist> descriptionTemplates) {
@ -106,7 +106,7 @@ public class SectionPersist {
}
public List<UUID> getPrefillingSourcesIds() {
return prefillingSourcesIds;
return this.prefillingSourcesIds;
}
public void setPrefillingSourcesIds(List<UUID> prefillingSourcesIds) {
@ -139,16 +139,16 @@ public class SectionPersist {
return Arrays.asList(
this.spec()
.must(() -> this.isValidGuid(item.getId()))
.failOn(SectionPersist._id).failWith(messageSource.getMessage("Validation_Required", new Object[]{SectionPersist._id}, LocaleContextHolder.getLocale())),
.failOn(SectionPersist._id).failWith(this.messageSource.getMessage("Validation_Required", new Object[]{SectionPersist._id}, LocaleContextHolder.getLocale())),
this.spec()
.must(() -> !this.isEmpty(item.getLabel()))
.failOn(SectionPersist._label).failWith(messageSource.getMessage("Validation_Required", new Object[]{SectionPersist._label}, LocaleContextHolder.getLocale())),
.failOn(SectionPersist._label).failWith(this.messageSource.getMessage("Validation_Required", new Object[]{SectionPersist._label}, LocaleContextHolder.getLocale())),
this.spec()
.must(() -> !this.isNull(item.getOrdinal()))
.failOn(SectionPersist._ordinal).failWith(messageSource.getMessage("Validation_Required", new Object[]{SectionPersist._ordinal}, LocaleContextHolder.getLocale())),
.failOn(SectionPersist._ordinal).failWith(this.messageSource.getMessage("Validation_Required", new Object[]{SectionPersist._ordinal}, LocaleContextHolder.getLocale())),
this.spec()
.must(() -> !this.isNull(item.getHasTemplates()))
.failOn(SectionPersist._hasTemplates).failWith(messageSource.getMessage("Validation_Required", new Object[]{SectionPersist._hasTemplates}, LocaleContextHolder.getLocale())),
.failOn(SectionPersist._hasTemplates).failWith(this.messageSource.getMessage("Validation_Required", new Object[]{SectionPersist._hasTemplates}, LocaleContextHolder.getLocale())),
this.navSpec()
.iff(() -> !this.isListNullOrEmpty(item.getFields()))
.on(SectionPersist._fields)
@ -175,7 +175,7 @@ public class SectionPersist {
this.spec()
.iff(() -> !this.isListNullOrEmpty(item.getDescriptionTemplates()))
.must(() -> item.getDescriptionTemplates().stream().map(DescriptionTemplatePersist::getDescriptionTemplateGroupId).distinct().collect(Collectors.toList()).size() == item.getDescriptionTemplates().size())
.failOn(SectionPersist._descriptionTemplates).failWith(messageSource.getMessage("Validation_Unique", new Object[]{SectionPersist._descriptionTemplates}, LocaleContextHolder.getLocale()))
.failOn(SectionPersist._descriptionTemplates).failWith(this.messageSource.getMessage("Validation_Unique", new Object[]{SectionPersist._descriptionTemplates}, LocaleContextHolder.getLocale()))
);
}

View File

@ -1,7 +1,7 @@
package org.opencdmp.model.persist.dmpblueprintdefinition;
package org.opencdmp.model.persist.planblueprintdefinition;
import org.opencdmp.commons.enums.PlanBlueprintSystemFieldType;
import gr.cite.tools.validation.specification.Specification;
import org.opencdmp.commons.enums.PlanBlueprintSystemFieldType;
import org.opencdmp.convention.ConventionService;
import org.opencdmp.errorcode.ErrorThesaurusProperties;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
@ -19,7 +19,7 @@ public class SystemFieldPersist extends FieldPersist {
public static final String _systemFieldType = "systemFieldType";
public PlanBlueprintSystemFieldType getSystemFieldType() {
return systemFieldType;
return this.systemFieldType;
}
public void setSystemFieldType(PlanBlueprintSystemFieldType systemFieldType) {
@ -43,11 +43,11 @@ public class SystemFieldPersist extends FieldPersist {
@Override
protected List<Specification> specifications(SystemFieldPersist item) {
List<Specification> specifications = getBaseSpecifications(item);
List<Specification> specifications = this.getBaseSpecifications(item);
specifications.add(
this.spec()
.must(() -> !this.isNull(item.getSystemFieldType()))
.failOn(SystemFieldPersist._systemFieldType).failWith(messageSource.getMessage("Validation_Required", new Object[]{SystemFieldPersist._systemFieldType}, LocaleContextHolder.getLocale()))
.failOn(SystemFieldPersist._systemFieldType).failWith(this.messageSource.getMessage("Validation_Required", new Object[]{SystemFieldPersist._systemFieldType}, LocaleContextHolder.getLocale()))
);
return specifications;
}

View File

@ -1,10 +1,9 @@
package org.opencdmp.query.lookup;
import org.opencdmp.commons.enums.LockTargetType;
import org.opencdmp.query.LockQuery;
import gr.cite.tools.data.query.Lookup;
import gr.cite.tools.data.query.QueryFactory;
import org.opencdmp.commons.enums.LockTargetType;
import org.opencdmp.query.LockQuery;
import java.util.List;
import java.util.UUID;
@ -20,8 +19,8 @@ public class LockLookup extends Lookup {
private List<LockTargetType> targetTypes;
private List<UUID> excludedIds;
private List<UUID> userIds;
private List<UUID> userIds;
public String getLike() {
return like;
@ -73,12 +72,18 @@ public class LockLookup extends Lookup {
public LockQuery enrich(QueryFactory queryFactory) {
LockQuery query = queryFactory.query(LockQuery.class);
if (this.like != null) query.like(this.like);
if (this.ids != null) query.ids(this.ids);
if (this.targetIds != null) query.targetIds(this.targetIds);
if (this.targetTypes != null) query.targetTypes(this.targetTypes);
if (this.excludedIds != null) query.excludedIds(this.excludedIds);
if (this.userIds != null) query.userIds(this.userIds);
if (this.like != null)
query.like(this.like);
if (this.ids != null)
query.ids(this.ids);
if (this.targetIds != null)
query.targetIds(this.targetIds);
if (this.targetTypes != null)
query.targetTypes(this.targetTypes);
if (this.excludedIds != null)
query.excludedIds(this.excludedIds);
if (this.userIds != null)
query.userIds(this.userIds);
this.enrichCommon(query);

View File

@ -1,9 +1,9 @@
package org.opencdmp.query.lookup;
import org.opencdmp.commons.enums.IsActive;
import org.opencdmp.query.UserQuery;
import gr.cite.tools.data.query.Lookup;
import gr.cite.tools.data.query.QueryFactory;
import org.opencdmp.commons.enums.IsActive;
import org.opencdmp.query.UserQuery;
import java.util.List;
import java.util.UUID;
@ -13,11 +13,15 @@ public class UserLookup extends Lookup {
private String like;
private List<UUID> ids;
private List<String> emails;
private List<UUID> excludedIds;
private List<IsActive> isActive;
private UserRoleLookup userRoleSubQuery;
private TenantUserLookup tenantUserSubQuery;
public String getLike() {
@ -78,13 +82,20 @@ public class UserLookup extends Lookup {
public UserQuery enrich(QueryFactory queryFactory) {
UserQuery query = queryFactory.query(UserQuery.class);
if (this.like != null) query.like(this.like);
if (this.ids != null) query.ids(this.ids);
if (this.emails != null) query.emails(this.emails);
if (this.userRoleSubQuery != null) query.userRoleSubQuery(this.userRoleSubQuery.enrich(queryFactory));
if (this.tenantUserSubQuery != null) query.tenantUserSubQuery(this.tenantUserSubQuery.enrich(queryFactory));
if (this.excludedIds != null) query.excludedIds(this.excludedIds);
if (this.isActive != null) query.isActive(this.isActive);
if (this.like != null)
query.like(this.like);
if (this.ids != null)
query.ids(this.ids);
if (this.emails != null)
query.emails(this.emails);
if (this.userRoleSubQuery != null)
query.userRoleSubQuery(this.userRoleSubQuery.enrich(queryFactory));
if (this.tenantUserSubQuery != null)
query.tenantUserSubQuery(this.tenantUserSubQuery.enrich(queryFactory));
if (this.excludedIds != null)
query.excludedIds(this.excludedIds);
if (this.isActive != null)
query.isActive(this.isActive);
this.enrichCommon(query);

View File

@ -33,13 +33,13 @@ import org.opencdmp.errorcode.ErrorThesaurusProperties;
import org.opencdmp.model.builder.planblueprint.PlanBlueprintBuilder;
import org.opencdmp.model.deleter.PlanBlueprintDeleter;
import org.opencdmp.model.descriptiontemplate.DescriptionTemplate;
import org.opencdmp.model.planblueprint.Definition;
import org.opencdmp.model.planblueprint.PlanBlueprint;
import org.opencdmp.model.planblueprint.Field;
import org.opencdmp.model.planblueprint.Section;
import org.opencdmp.model.persist.PlanBlueprintPersist;
import org.opencdmp.model.persist.NewVersionPlanBlueprintPersist;
import org.opencdmp.model.persist.dmpblueprintdefinition.*;
import org.opencdmp.model.persist.PlanBlueprintPersist;
import org.opencdmp.model.persist.planblueprintdefinition.*;
import org.opencdmp.model.planblueprint.Definition;
import org.opencdmp.model.planblueprint.Field;
import org.opencdmp.model.planblueprint.PlanBlueprint;
import org.opencdmp.model.planblueprint.Section;
import org.opencdmp.model.prefillingsource.PrefillingSource;
import org.opencdmp.model.referencetype.ReferenceType;
import org.opencdmp.query.DescriptionTemplateQuery;

View File

@ -12,6 +12,13 @@ import gr.cite.tools.fieldset.FieldSet;
import gr.cite.tools.logging.LoggerService;
import gr.cite.tools.logging.MapLogEntry;
import gr.cite.tools.validation.ValidationFilterAnnotation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.ExampleObject;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.transaction.Transactional;
import org.opencdmp.audit.AuditableAction;
import org.opencdmp.authorization.AffiliatedResource;
@ -19,6 +26,11 @@ import org.opencdmp.authorization.AuthorizationFlags;
import org.opencdmp.authorization.Permission;
import org.opencdmp.authorization.authorizationcontentresolver.AuthorizationContentResolver;
import org.opencdmp.commons.enums.LockTargetType;
import org.opencdmp.controllers.swagger.SwaggerHelpers;
import org.opencdmp.controllers.swagger.annotation.OperationWithTenantHeader;
import org.opencdmp.controllers.swagger.annotation.Swagger400;
import org.opencdmp.controllers.swagger.annotation.Swagger404;
import org.opencdmp.controllers.swagger.annotation.SwaggerCommonErrorResponses;
import org.opencdmp.data.LockEntity;
import org.opencdmp.model.Lock;
import org.opencdmp.model.LockStatus;
@ -26,6 +38,7 @@ import org.opencdmp.model.builder.LockBuilder;
import org.opencdmp.model.censorship.LockCensor;
import org.opencdmp.model.persist.LockPersist;
import org.opencdmp.model.result.QueryResult;
import org.opencdmp.model.user.User;
import org.opencdmp.query.LockQuery;
import org.opencdmp.query.lookup.LockLookup;
import org.opencdmp.service.lock.LockService;
@ -49,6 +62,8 @@ import java.util.UUID;
@RestController
@RequestMapping(path = "api/lock")
@Tag(name = "Locks", description = "Manage locked entities")
@SwaggerCommonErrorResponses
public class LockController {
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(LockController.class));
@ -66,7 +81,9 @@ public class LockController {
private final MessageSource messageSource;
private final AuthorizationService authService;
private final AuthorizationContentResolver authorizationContentResolver;
@Autowired
public LockController(BuilderFactory builderFactory,
AuditService auditService,
@ -81,10 +98,29 @@ public class LockController {
this.queryFactory = queryFactory;
this.messageSource = messageSource;
this.authService = authService;
this.authorizationContentResolver = authorizationContentResolver;
this.authorizationContentResolver = authorizationContentResolver;
}
@PostMapping("query")
@OperationWithTenantHeader(summary = "Query all locked entities", description = SwaggerHelpers.Lock.endpoint_query, requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(description = SwaggerHelpers.Lock.endpoint_query_request_body, content = @Content(
examples = {
@ExampleObject(
name = "Pagination and projection",
description = "Simple paginated request using a property projection list and pagination info",
value = SwaggerHelpers.Lock.endpoint_query_request_body_example
)
}
)), responses = @ApiResponse(description = "OK", responseCode = "200", content = @Content(
array = @ArraySchema(
schema = @Schema(
implementation = Lock.class
)
),
examples = @ExampleObject(
name = "First page",
description = "Example with the first page of paginated results",
value = SwaggerHelpers.Lock.endpoint_query_response_example
))))
public QueryResult<Lock> query(@RequestBody LockLookup lookup) throws MyApplicationException, MyForbiddenException, InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException {
logger.debug("querying {}", Lock.class.getSimpleName());
@ -101,7 +137,17 @@ public class LockController {
}
@GetMapping("{id}")
public Lock get(@PathVariable("id") UUID id, FieldSet fieldSet) throws MyApplicationException, MyForbiddenException, MyNotFoundException {
@OperationWithTenantHeader(summary = "Fetch a specific lock by id", description = "",
responses = @ApiResponse(description = "OK", responseCode = "200", content = @Content(
schema = @Schema(
implementation = Lock.class
))
))
@Swagger404
public Lock get(
@Parameter(name = "id", description = "The id of a user to fetch", example = "c0c163dc-2965-45a5-9608-f76030578609", required = true) @PathVariable("id") UUID id,
@Parameter(name = "fieldSet", description = SwaggerHelpers.Commons.fieldset_description, required = true) FieldSet fieldSet
) throws MyApplicationException, MyForbiddenException, MyNotFoundException {
logger.debug(new MapLogEntry("retrieving" + Lock.class.getSimpleName()).And("id", id).And("fields", fieldSet));
this.censorFactory.censor(LockCensor.class).censor(fieldSet, null);
@ -120,9 +166,20 @@ public class LockController {
}
@PostMapping("persist")
@OperationWithTenantHeader(summary = "Create a new or update an existing lock", description = "",
responses = @ApiResponse(description = "OK", responseCode = "200", content = @Content(
schema = @Schema(
implementation = Lock.class
))
))
@Swagger400
@Swagger404
@Transactional
@ValidationFilterAnnotation(validator = LockPersist.LockPersistValidator.ValidatorName, argumentName = "model")
public Lock persist(@RequestBody LockPersist model, FieldSet fieldSet) throws MyApplicationException, MyForbiddenException, MyNotFoundException, InvalidApplicationException {
public Lock persist(
@RequestBody LockPersist model,
@Parameter(name = "fieldSet", description = SwaggerHelpers.Commons.fieldset_description, required = true) FieldSet fieldSet
) throws MyApplicationException, MyForbiddenException, MyNotFoundException, InvalidApplicationException {
logger.debug(new MapLogEntry("persisting" + Lock.class.getSimpleName()).And("model", model).And("fieldSet", fieldSet));
this.censorFactory.censor(LockCensor.class).censor(fieldSet, null);
@ -137,7 +194,17 @@ public class LockController {
}
@GetMapping("target/{id}")
public Lock getWithTarget(@PathVariable("id") UUID targetId, FieldSet fieldSet) throws MyApplicationException, MyForbiddenException, MyNotFoundException {
@OperationWithTenantHeader(summary = "Fetch a specific lock by target id", description = "",
responses = @ApiResponse(description = "OK", responseCode = "200", content = @Content(
schema = @Schema(
implementation = Lock.class
))
))
@Swagger404
public Lock getWithTarget(
@Parameter(name = "id", description = "The target id of a lock to fetch", example = "c0c163dc-2965-45a5-9608-f76030578609", required = true) @PathVariable("id") UUID targetId,
@Parameter(name = "fieldSet", description = SwaggerHelpers.Commons.fieldset_description, required = true) FieldSet fieldSet
) throws MyApplicationException, MyForbiddenException, MyNotFoundException {
logger.debug(new MapLogEntry("retrieving" + Lock.class.getSimpleName()).And("targetId", targetId).And("fields", fieldSet));
this.censorFactory.censor(LockCensor.class).censor(fieldSet, null);
@ -157,7 +224,16 @@ public class LockController {
@Transactional
@GetMapping("target/status/{id}")
public LockStatus getLocked(@PathVariable("id") UUID targetId, FieldSet fieldSet) throws Exception {
@OperationWithTenantHeader(summary = "Fetch a lock status by target id", description = "",
responses = @ApiResponse(description = "OK", responseCode = "200", content = @Content(
schema = @Schema(
implementation = LockStatus.class
))
))
public LockStatus getLocked(
@Parameter(name = "id", description = "The target id of a lock to fetch the status", example = "c0c163dc-2965-45a5-9608-f76030578609", required = true) @PathVariable("id") UUID targetId,
@Parameter(name = "fieldSet", description = SwaggerHelpers.Commons.fieldset_description, required = true) FieldSet fieldSet
) throws Exception {
logger.debug(new MapLogEntry("is locked" + Lock.class.getSimpleName()).And("targetId", targetId).And("fields", fieldSet));
this.authService.authorizeForce(Permission.BrowseLock);
@ -171,7 +247,16 @@ public class LockController {
@Transactional
@GetMapping("target/lock/{id}/{targetType}")
public boolean lock(@PathVariable("id") UUID targetId, @PathVariable("targetType") int targetType) throws Exception {
@OperationWithTenantHeader(summary = "Lock a target", description = "",
responses = @ApiResponse(description = "OK", responseCode = "200", content = @Content(
schema = @Schema(
implementation = Boolean.class
))
))
public boolean lock(
@Parameter(name = "id", description = "The target id to be locked", example = "c0c163dc-2965-45a5-9608-f76030578609", required = true) @PathVariable("id") UUID targetId,
@Parameter(name = "targetType", description = "The target type to be locked", example = "0", required = true) @PathVariable("targetType") int targetType
) throws Exception {
AffiliatedResource affiliatedResourcePlan = this.authorizationContentResolver.planAffiliation(targetId);
AffiliatedResource affiliatedResourceDescription = this.authorizationContentResolver.descriptionAffiliation(targetId);
AffiliatedResource affiliatedResourceDescriptionTemplate = this.authorizationContentResolver.descriptionTemplateAffiliation(targetId);
@ -187,7 +272,15 @@ public class LockController {
@Transactional
@GetMapping("target/touch/{id}")
public boolean touch(@PathVariable("id") UUID targetId) throws Exception {
@OperationWithTenantHeader(summary = "Touch a locked target", description = "",
responses = @ApiResponse(description = "OK", responseCode = "200", content = @Content(
schema = @Schema(
implementation = Boolean.class
))
))
public boolean touch(
@Parameter(name = "id", description = "The target id to be touched", example = "c0c163dc-2965-45a5-9608-f76030578609", required = true) @PathVariable("id") UUID targetId
) throws Exception {
AffiliatedResource affiliatedResourcePlan = this.authorizationContentResolver.planAffiliation(targetId);
AffiliatedResource affiliatedResourceDescription = this.authorizationContentResolver.descriptionAffiliation(targetId);
AffiliatedResource affiliatedResourceDescriptionTemplate = this.authorizationContentResolver.descriptionTemplateAffiliation(targetId);
@ -202,7 +295,15 @@ public class LockController {
@Transactional
@DeleteMapping("target/unlock/{id}")
public boolean unlock(@PathVariable("id") UUID targetId) throws Exception {
@OperationWithTenantHeader(summary = "Unlock a target", description = "",
responses = @ApiResponse(description = "OK", responseCode = "200", content = @Content(
schema = @Schema(
implementation = Boolean.class
))
))
public boolean unlock(
@Parameter(name = "id", description = "The target id to be unlocked", example = "c0c163dc-2965-45a5-9608-f76030578609", required = true) @PathVariable("id") UUID targetId
) throws Exception {
AffiliatedResource affiliatedResourcePlan = this.authorizationContentResolver.planAffiliation(targetId);
AffiliatedResource affiliatedResourceDescription = this.authorizationContentResolver.descriptionAffiliation(targetId);
AffiliatedResource affiliatedResourceDescriptionTemplate = this.authorizationContentResolver.descriptionTemplateAffiliation(targetId);
@ -216,8 +317,13 @@ public class LockController {
}
@DeleteMapping("{id}/{target}")
@OperationWithTenantHeader(summary = "Delete a lock by id and target", description = "",
responses = @ApiResponse(description = "OK", responseCode = "200"))
@Transactional
public void delete(@PathVariable("id") UUID id, @PathVariable("target") UUID target) throws MyForbiddenException, InvalidApplicationException {
public void delete(
@Parameter(name = "id", description = "The id of the lock to be deleted", example = "c0c163dc-2965-45a5-9608-f76030578609", required = true) @PathVariable("id") UUID id,
@Parameter(name = "target", description = "The target id of the lock", example = "c0c163dc-2965-45a5-9608-f76030578609", required = true) @PathVariable("target") UUID target
) throws MyForbiddenException, InvalidApplicationException {
logger.debug(new MapLogEntry("retrieving" + Lock.class.getSimpleName()).And("id", id));
this.lockService.deleteAndSave(id, target);

View File

@ -146,15 +146,11 @@ public class PlanController {
}
@PostMapping("query")
@OperationWithTenantHeader(summary = "Query all plans", description = SwaggerHelpers.Plan.endpoint_query, requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(description = SwaggerHelpers.Plan.endpoint_query_request_body, content = @Content(
examples = {
@ExampleObject(
name = "Pagination and projection",
description = "Simple paginated request using a property projection list and pagination info",
value = SwaggerHelpers.Plan.endpoint_query_request_body_example
)
}
)), responses = @ApiResponse(description = "OK", responseCode = "200", content = @Content(
@OperationWithTenantHeader(summary = "Query all plans", description = SwaggerHelpers.Plan.endpoint_query, requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(description = SwaggerHelpers.Plan.endpoint_query_request_body, content = @Content(examples = @ExampleObject(
name = "Pagination and projection",
description = "Simple paginated request using a property projection list and pagination info",
value = SwaggerHelpers.Plan.endpoint_query_request_body_example
))), responses = @ApiResponse(description = "OK", responseCode = "200", content = @Content(
array = @ArraySchema(
schema = @Schema(
implementation = Plan.class
@ -506,7 +502,7 @@ public class PlanController {
public PreprocessingPlanModel preprocessing(
@RequestParam("fileId") UUID fileId,
@RequestParam("repositoryId") String repositoryId
) throws InvalidAlgorithmParameterException, JAXBException, NoSuchPaddingException, IllegalBlockSizeException, InvalidApplicationException, IOException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException {
) throws InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, InvalidApplicationException, IOException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException {
logger.debug(new MapLogEntry("preprocessing plan" + Plan.class.getSimpleName()).And("transformerId", repositoryId).And("fileId", fileId));
PreprocessingPlanModel model = this.planService.preprocessingPlan(fileId, repositoryId);

View File

@ -6,7 +6,15 @@ import gr.cite.tools.auditing.AuditService;
import gr.cite.tools.fieldset.BaseFieldSet;
import gr.cite.tools.fieldset.FieldSet;
import gr.cite.tools.logging.LoggerService;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.opencdmp.audit.AuditableAction;
import org.opencdmp.controllers.swagger.SwaggerHelpers;
import org.opencdmp.controllers.swagger.annotation.OperationWithTenantHeader;
import org.opencdmp.model.Lock;
import org.opencdmp.model.Tenant;
import org.opencdmp.models.Account;
import org.opencdmp.models.AccountBuilder;
@ -23,6 +31,7 @@ import java.util.List;
@RestController
@RequestMapping("/api/principal/")
@Tag(name = "Principal", description = "Get user account information")
public class PrincipalController {
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(PrincipalController.class));
private final AuditService auditService;
@ -43,7 +52,15 @@ public class PrincipalController {
}
@RequestMapping(path = "me", method = RequestMethod.GET )
public Account me(FieldSet fieldSet) throws InvalidApplicationException {
@OperationWithTenantHeader(summary = "Fetch auth information of the logged in user", description = "",
responses = @ApiResponse(description = "OK", responseCode = "200", content = @Content(
schema = @Schema(
implementation = Account.class
))
))
public Account me(
@Parameter(name = "fieldSet", description = SwaggerHelpers.Commons.fieldset_description, required = true) FieldSet fieldSet
) throws InvalidApplicationException {
logger.debug("me");
if (fieldSet == null || fieldSet.isEmpty()) {
@ -80,7 +97,11 @@ public class PrincipalController {
}
@GetMapping("my-tenants")
public List<Tenant> myTenants(FieldSet fieldSet) {
@OperationWithTenantHeader(summary = "Fetch a list with the tenants the user belongs to", description = "",
responses = @ApiResponse(description = "OK", responseCode = "200"))
public List<Tenant> myTenants(
@Parameter(name = "fieldSet", description = SwaggerHelpers.Commons.fieldset_description, required = true) FieldSet fieldSet
) {
logger.debug("my-tenants");
List<Tenant> models = this.tenantService.myTenants(fieldSet);

View File

@ -12,11 +12,24 @@ import gr.cite.tools.fieldset.FieldSet;
import gr.cite.tools.logging.LoggerService;
import gr.cite.tools.logging.MapLogEntry;
import gr.cite.tools.validation.ValidationFilterAnnotation;
import io.swagger.v3.oas.annotations.Hidden;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.ExampleObject;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.xml.bind.JAXBException;
import org.opencdmp.audit.AuditableAction;
import org.opencdmp.authorization.AuthorizationFlags;
import org.opencdmp.commons.enums.IsActive;
import org.opencdmp.commons.scope.user.UserScope;
import org.opencdmp.controllers.swagger.SwaggerHelpers;
import org.opencdmp.controllers.swagger.annotation.OperationWithTenantHeader;
import org.opencdmp.controllers.swagger.annotation.Swagger400;
import org.opencdmp.controllers.swagger.annotation.Swagger404;
import org.opencdmp.controllers.swagger.annotation.SwaggerCommonErrorResponses;
import org.opencdmp.data.UserEntity;
import org.opencdmp.model.PlanAssociatedUser;
import org.opencdmp.model.UserRole;
@ -26,6 +39,7 @@ import org.opencdmp.model.censorship.PlanAssociatedUserCensor;
import org.opencdmp.model.censorship.UserCensor;
import org.opencdmp.model.persist.*;
import org.opencdmp.model.persist.actionconfirmation.RemoveCredentialRequestPersist;
import org.opencdmp.model.plan.Plan;
import org.opencdmp.model.result.QueryResult;
import org.opencdmp.model.user.User;
import org.opencdmp.query.UserQuery;
@ -51,6 +65,8 @@ import java.util.UUID;
@RestController
@RequestMapping(path = "api/user")
@Tag(name = "Users", description = "Manage users")
@SwaggerCommonErrorResponses
public class UserController {
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(UserController.class));
@ -91,6 +107,25 @@ public class UserController {
}
@PostMapping("query")
@OperationWithTenantHeader(summary = "Query all users", description = SwaggerHelpers.User.endpoint_query, requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(description = SwaggerHelpers.User.endpoint_query_request_body, content = @Content(
examples = {
@ExampleObject(
name = "Pagination and projection",
description = "Simple paginated request using a property projection list and pagination info",
value = SwaggerHelpers.User.endpoint_query_request_body_example
)
}
)), responses = @ApiResponse(description = "OK", responseCode = "200", content = @Content(
array = @ArraySchema(
schema = @Schema(
implementation = User.class
)
),
examples = @ExampleObject(
name = "First page",
description = "Example with the first page of paginated results",
value = SwaggerHelpers.User.endpoint_query_response_example
))))
public QueryResult<User> query(@RequestBody UserLookup lookup) throws MyApplicationException, MyForbiddenException {
logger.debug("querying {}", User.class.getSimpleName());
@ -108,6 +143,7 @@ public class UserController {
}
@PostMapping("plan-associated/query")
@Hidden
public QueryResult<PlanAssociatedUser> queryPlanAssociated(@RequestBody UserLookup lookup) throws MyApplicationException, MyForbiddenException {
logger.debug("querying {}", User.class.getSimpleName());
@ -125,7 +161,17 @@ public class UserController {
}
@GetMapping("{id}")
public User get(@PathVariable("id") UUID id, FieldSet fieldSet) throws MyApplicationException, MyForbiddenException, MyNotFoundException {
@OperationWithTenantHeader(summary = "Fetch a specific user by id", description = "",
responses = @ApiResponse(description = "OK", responseCode = "200", content = @Content(
schema = @Schema(
implementation = User.class
))
))
@Swagger404
public User get(
@Parameter(name = "id", description = "The id of a user to fetch", example = "c0c163dc-2965-45a5-9608-f76030578609", required = true) @PathVariable("id") UUID id,
@Parameter(name = "fieldSet", description = SwaggerHelpers.Commons.fieldset_description, required = true) FieldSet fieldSet
) throws MyApplicationException, MyForbiddenException, MyNotFoundException {
logger.debug(new MapLogEntry("retrieving" + User.class.getSimpleName()).And("id", id).And("fields", fieldSet));
this.censorFactory.censor(UserCensor.class).censor(fieldSet, id);
@ -144,7 +190,17 @@ public class UserController {
}
@GetMapping("/by-email/{email}")
public User get(@PathVariable("email") String email, FieldSet fieldSet) throws MyApplicationException, MyForbiddenException, MyNotFoundException {
@OperationWithTenantHeader(summary = "Fetch a specific user by email", description = "",
responses = @ApiResponse(description = "OK", responseCode = "200", content = @Content(
schema = @Schema(
implementation = User.class
))
))
@Swagger404
public User get(
@Parameter(name = "email", description = "The email of a user to fetch", example = "admin@cite.gr", required = true) @PathVariable("email") String email,
@Parameter(name = "fieldSet", description = SwaggerHelpers.Commons.fieldset_description, required = true) FieldSet fieldSet
) throws MyApplicationException, MyForbiddenException, MyNotFoundException {
logger.debug(new MapLogEntry("retrieving" + User.class.getSimpleName()).And("email", email).And("fields", fieldSet));
this.censorFactory.censor(UserCensor.class).censor(fieldSet, null);
@ -163,6 +219,7 @@ public class UserController {
}
@GetMapping("/export/csv/{hasTenantAdminMode}")
@Hidden
public ResponseEntity<byte[]> exportCsv(@PathVariable("hasTenantAdminMode") Boolean hasTenantAdminMode) throws MyApplicationException, MyForbiddenException, MyNotFoundException, IOException, InvalidApplicationException {
logger.debug(new MapLogEntry("export" + User.class.getSimpleName()).And("hasTenantAdminMode", hasTenantAdminMode));
@ -177,7 +234,16 @@ public class UserController {
}
@GetMapping("mine")
public User getMine(FieldSet fieldSet) throws MyApplicationException, MyForbiddenException, MyNotFoundException, InvalidApplicationException {
@OperationWithTenantHeader(summary = "Fetch information for the logged in user", description = "",
responses = @ApiResponse(description = "OK", responseCode = "200", content = @Content(
schema = @Schema(
implementation = User.class
))
))
@Swagger404
public User getMine(
@Parameter(name = "fieldSet", description = SwaggerHelpers.Commons.fieldset_description, required = true) FieldSet fieldSet
) throws MyApplicationException, MyForbiddenException, MyNotFoundException, InvalidApplicationException {
logger.debug(new MapLogEntry("retrieving me" + User.class.getSimpleName()).And("fields", fieldSet));
this.censorFactory.censor(UserCensor.class).censor(fieldSet, this.userScope.getUserId());
@ -195,8 +261,12 @@ public class UserController {
}
@GetMapping("mine/language/{language}")
@OperationWithTenantHeader(summary = "Update the language for the logged in user", description = "",
responses = @ApiResponse(description = "OK", responseCode = "200"))
@Transactional
public void updateLanguageMine(@PathVariable("language") String language) throws MyApplicationException, MyForbiddenException, MyNotFoundException, InvalidApplicationException, JsonProcessingException {
public void updateLanguageMine(
@Parameter(name = "language", description = "The updated language", example = "en", required = true) @PathVariable("language") String language
) throws MyApplicationException, MyForbiddenException, MyNotFoundException, InvalidApplicationException, JsonProcessingException {
logger.debug(new MapLogEntry("persisting" + User.class.getSimpleName()).And("language", language));
this.userTypeService.updateLanguageMine(language);
@ -206,8 +276,12 @@ public class UserController {
}
@GetMapping("mine/timezone/{timezone}")
@OperationWithTenantHeader(summary = "Update the timezone for the logged in user", description = "",
responses = @ApiResponse(description = "OK", responseCode = "200"))
@Transactional
public void updateTimezoneMine(@PathVariable("timezone") String timezone) throws MyApplicationException, MyForbiddenException, MyNotFoundException, InvalidApplicationException, JsonProcessingException {
public void updateTimezoneMine(
@Parameter(name = "timezone", description = "The updated timezone", example = "Europe/Budapest", required = true) @PathVariable("timezone") String timezone
) throws MyApplicationException, MyForbiddenException, MyNotFoundException, InvalidApplicationException, JsonProcessingException {
logger.debug(new MapLogEntry("persisting" + User.class.getSimpleName()).And("timezone", timezone));
this.userTypeService.updateTimezoneMine(timezone);
@ -217,8 +291,12 @@ public class UserController {
}
@GetMapping("mine/culture/{culture}")
@OperationWithTenantHeader(summary = "Update the culture for the logged in user", description = "",
responses = @ApiResponse(description = "OK", responseCode = "200"))
@Transactional
public void updateCultureMine(@PathVariable("culture") String culture) throws MyApplicationException, MyForbiddenException, MyNotFoundException, InvalidApplicationException, JsonProcessingException {
public void updateCultureMine(
@Parameter(name = "culture", description = "The updated culture", example = "en-US", required = true) @PathVariable("culture") String culture
) throws MyApplicationException, MyForbiddenException, MyNotFoundException, InvalidApplicationException, JsonProcessingException {
logger.debug(new MapLogEntry("persisting" + User.class.getSimpleName()).And("culture", culture));
this.userTypeService.updateCultureMine(culture);
@ -228,9 +306,20 @@ public class UserController {
}
@PostMapping("persist")
@OperationWithTenantHeader(summary = "Create a new or update an existing user", description = "",
responses = @ApiResponse(description = "OK", responseCode = "200", content = @Content(
schema = @Schema(
implementation = User.class
))
))
@Swagger400
@Swagger404
@Transactional
@ValidationFilterAnnotation(validator = UserPersist.UserPersistValidator.ValidatorName, argumentName = "model")
public User persist(@RequestBody UserPersist model, FieldSet fieldSet) throws MyApplicationException, MyForbiddenException, MyNotFoundException, InvalidApplicationException, JAXBException, ParserConfigurationException, JsonProcessingException, TransformerException {
public User persist(
@RequestBody UserPersist model,
@Parameter(name = "fieldSet", description = SwaggerHelpers.Commons.fieldset_description, required = true) FieldSet fieldSet
) throws MyApplicationException, MyForbiddenException, MyNotFoundException, InvalidApplicationException, JAXBException, ParserConfigurationException, JsonProcessingException, TransformerException {
logger.debug(new MapLogEntry("persisting" + User.class.getSimpleName()).And("model", model).And("fieldSet", fieldSet));
User persisted = this.userTypeService.persist(model, fieldSet);
@ -243,9 +332,20 @@ public class UserController {
}
@PostMapping("persist/roles")
@OperationWithTenantHeader(summary = "Update user roles", description = "",
responses = @ApiResponse(description = "OK", responseCode = "200", content = @Content(
schema = @Schema(
implementation = User.class
))
))
@Swagger400
@Swagger404
@Transactional
@ValidationFilterAnnotation(validator = UserRolePatchPersist.UserRolePatchPersistValidator.ValidatorName, argumentName = "model")
public User persistRoles(@RequestBody UserRolePatchPersist model, FieldSet fieldSet) throws MyApplicationException, MyForbiddenException, MyNotFoundException, InvalidApplicationException, JAXBException, ParserConfigurationException, JsonProcessingException, TransformerException {
public User persistRoles(
@RequestBody UserRolePatchPersist model,
@Parameter(name = "fieldSet", description = SwaggerHelpers.Commons.fieldset_description, required = true) FieldSet fieldSet
) throws MyApplicationException, MyForbiddenException, MyNotFoundException, InvalidApplicationException, JAXBException, ParserConfigurationException, JsonProcessingException, TransformerException {
logger.debug(new MapLogEntry("persisting" + UserRole.class.getSimpleName()).And("model", model).And("fieldSet", fieldSet));
User persisted = this.userTypeService.patchRoles(model, fieldSet);
@ -258,8 +358,13 @@ public class UserController {
}
@DeleteMapping("{id}")
@OperationWithTenantHeader(summary = "Delete a user by id", description = "",
responses = @ApiResponse(description = "OK", responseCode = "200"))
@Swagger404
@Transactional
public void delete(@PathVariable("id") UUID id) throws MyForbiddenException, InvalidApplicationException {
public void delete(
@Parameter(name = "id", description = "The id of a user to delete", example = "c0c163dc-2965-45a5-9608-f76030578609", required = true) @PathVariable("id") UUID id
) throws MyForbiddenException, InvalidApplicationException {
logger.debug(new MapLogEntry("retrieving" + User.class.getSimpleName()).And("id", id));
this.userTypeService.deleteAndSave(id);
@ -268,6 +373,10 @@ public class UserController {
}
@PostMapping("mine/merge-account-request")
@OperationWithTenantHeader(summary = "Merge user accounts", description = "",
responses = @ApiResponse(description = "OK", responseCode = "200"))
@Swagger400
@Swagger404
@Transactional
@ValidationFilterAnnotation(validator = UserMergeRequestPersist.UserMergeRequestPersistValidator.ValidatorName, argumentName = "model")
public Boolean mergeAccount(@RequestBody UserMergeRequestPersist model) throws InvalidApplicationException, JAXBException {
@ -283,8 +392,12 @@ public class UserController {
}
@GetMapping("mine/confirm-merge-account/token/{token}")
@OperationWithTenantHeader(summary = "Confirm the merge of user accounts", description = "",
responses = @ApiResponse(description = "OK", responseCode = "200"))
@Transactional
public Boolean confirmMergeAccount(@PathVariable("token") String token) throws InvalidApplicationException, IOException {
public Boolean confirmMergeAccount(
@Parameter(name = "token", description = "The token for the action", example = "c0c163dc-2965-45a5-9608-f76030578609", required = true) @PathVariable("token") String token
) throws InvalidApplicationException, IOException {
logger.debug(new MapLogEntry("confirm merge account to user").And("token", token));
this.userTypeService.confirmMergeAccount(token);
@ -297,7 +410,11 @@ public class UserController {
}
@GetMapping("mine/allow-merge-account/token/{token}")
public Boolean getUserTokenPermission(@PathVariable("token") String token) throws InvalidApplicationException, IOException {
@OperationWithTenantHeader(summary = "Allow the merge of user accounts", description = "",
responses = @ApiResponse(description = "OK", responseCode = "200"))
public Boolean getUserTokenPermission(
@Parameter(name = "token", description = "The token for the action", example = "c0c163dc-2965-45a5-9608-f76030578609", required = true) @PathVariable("token") String token
) throws InvalidApplicationException, IOException {
logger.debug(new MapLogEntry("allow merge account to user").And("token", token));
this.auditService.track(AuditableAction.User_AllowMergeAccount);
@ -306,6 +423,9 @@ public class UserController {
}
@PostMapping("mine/remove-credential-request")
@OperationWithTenantHeader(summary = "Remove user credentials", description = "",
responses = @ApiResponse(description = "OK", responseCode = "200"))
@Swagger400
@Transactional
@ValidationFilterAnnotation(validator = RemoveCredentialRequestPersist.RemoveCredentialRequestPersistValidator.ValidatorName, argumentName = "model")
public Boolean removeCredentialAccount(@RequestBody RemoveCredentialRequestPersist model) throws InvalidApplicationException, JAXBException {
@ -321,8 +441,12 @@ public class UserController {
}
@GetMapping("mine/confirm-remove-credential/token/{token}")
@OperationWithTenantHeader(summary = "Confirm the removal of user credentials", description = "",
responses = @ApiResponse(description = "OK", responseCode = "200"))
@Transactional
public Boolean confirmRemoveCredentialAccount(@PathVariable("token") String token) throws InvalidApplicationException, JAXBException {
public Boolean confirmRemoveCredentialAccount(
@Parameter(name = "token", description = "The token for the action", example = "c0c163dc-2965-45a5-9608-f76030578609", required = true) @PathVariable("token") String token
) throws InvalidApplicationException, JAXBException {
logger.debug(new MapLogEntry("confirm remove credential to user").And("token", token));
this.userTypeService.confirmRemoveCredential(token);
@ -335,6 +459,9 @@ public class UserController {
}
@PostMapping("invite-users-to-tenant")
@OperationWithTenantHeader(summary = "Invite users to a tenant", description = "",
responses = @ApiResponse(description = "OK", responseCode = "200"))
@Swagger400
@Transactional
@ValidationFilterAnnotation(validator = UserTenantUsersInviteRequest.UserTenantUsersInviteRequestValidator.ValidatorName, argumentName = "model")
public Boolean inviteUsersToTenant(@RequestBody UserTenantUsersInviteRequest users) throws InvalidApplicationException, JAXBException {
@ -350,8 +477,13 @@ public class UserController {
}
@GetMapping("confirm-invite-user-to-tenant/token/{token}")
@OperationWithTenantHeader(summary = "Confirm user tenant invitation", description = "",
responses = @ApiResponse(description = "OK", responseCode = "200"))
@Swagger400
@Transactional
public Boolean confirmInviteUserToTenant(@PathVariable("token") String token) throws InvalidApplicationException {
public Boolean confirmInviteUserToTenant(
@Parameter(name = "token", description = "The token for the action", example = "c0c163dc-2965-45a5-9608-f76030578609", required = true) @PathVariable("token") String token
) throws InvalidApplicationException {
logger.debug(new MapLogEntry("confirm merge account to user").And("token", token));
this.userTypeService.confirmUserInviteToTenant(token);

View File

@ -1,8 +1,8 @@
package org.opencdmp.controllers.swagger;
public class SwaggerHelpers {
public final class SwaggerHelpers {
public static class Commons {
public static final class Commons {
public static final String fieldset_description =
"""
@ -10,7 +10,7 @@ public class SwaggerHelpers {
""";
}
public static class Errors {
public static final class Errors {
public static final String message_400 =
"""
@ -51,7 +51,7 @@ public class SwaggerHelpers {
}
public static class Plan {
public static final class Plan {
public static final String endpoint_query =
"""
@ -905,7 +905,7 @@ public class SwaggerHelpers {
""";
}
public static class Description {
public static final class Description {
public static final String endpoint_query =
"""
@ -1760,7 +1760,7 @@ public class SwaggerHelpers {
""";
}
public static class DescriptionTemplate {
public static final class DescriptionTemplate {
public static final String endpoint_query =
"""
@ -2144,7 +2144,7 @@ public class SwaggerHelpers {
""";
}
public static class DescriptionTemplateType {
public static final class DescriptionTemplateType {
public static final String endpoint_query =
"""
@ -2307,7 +2307,7 @@ public class SwaggerHelpers {
}
public static class PlanBlueprint {
public static final class PlanBlueprint {
public static final String endpoint_query =
"""
@ -2548,7 +2548,7 @@ public class SwaggerHelpers {
}
public static class FileTransformer {
public static final class FileTransformer {
public static final String endpoint_get_available_transformers =
"""
@ -2569,7 +2569,7 @@ public class SwaggerHelpers {
}
public static class EntityDoi {
public static final class EntityDoi {
public static final String endpoint_query =
"""
@ -2835,7 +2835,7 @@ public class SwaggerHelpers {
}
public static class Deposit {
public static final class Deposit {
public static final String endpoint_get_available_repos =
"""
@ -2859,7 +2859,7 @@ public class SwaggerHelpers {
}
public static class Tag {
public static final class Tag {
public static final String endpoint_query =
"""
@ -3086,7 +3086,7 @@ public class SwaggerHelpers {
}
public static class Reference {
public static final class Reference {
public static final String endpoint_query =
"""
@ -3348,7 +3348,7 @@ public class SwaggerHelpers {
}
public static class ReferenceType {
public static final class ReferenceType {
public static final String endpoint_query =
"""
@ -3579,4 +3579,672 @@ public class SwaggerHelpers {
}
public static final class Lock {
public static final String endpoint_query =
"""
This endpoint is used to fetch all the current entity locks.<br/>
It also allows to restrict the results using a query object passed in the request body.<br/>
""";
public static final String endpoint_query_request_body =
"""
Let's explore the options this object gives us.
### <u>General query parameters:</u>
<ul>
<li><b>page:</b>
This is an object controlling the pagination of the results. It contains two properties.
</li>
<ul>
<li><b>offset:</b>
How many records to omit.
</li>
<li><b>size:</b>
How many records to include in each page.
</li>
</ul>
</ul>
For example, if we want the third page, and our pages to contain 15 elements, we would pass the following object:
```JSON
{
"offset": 30,
"size": 15
}
```
<ul>
<li><b>order:</b>
This is an object controlling the ordering of the results.
It contains a list of strings called <i>items</i> with the names of the properties to use.
<br/>If the name of the property is prefixed with a <b>'-'</b>, the ordering direction is <b>DESC</b>. Otherwise, it is <b>ASC</b>.
</li>
</ul>
For example, if we wanted to order based on the field 'createdAt' in descending order, we would pass the following object:
```JSON
{
"items": [
"-createdAt"
],
}
```
<ul>
<li><b>metadata:</b>
This is an object containing metadata for the request. There is only one available option.
<ul>
<li><b>countAll:</b>
If this is set to true, the count property included in the response will account for all the records regardless the pagination,
with all the rest of filtering options applied of course.
Otherwise, if it is set to false or not present, only the returned results will be counted.
<br/>The first option is useful for the UI clients to calculate how many result pages are available.
</li>
</ul>
</li>
<li><b>project:</b>
This is an object controlling the data projection of the results.
It contains a list of strings called <i>fields</i> with the names of the properties to project.
<br/>You can also include properties that are deeper in the object tree by prefixing them with dots.
</li>
</ul>
### <u>Lock specific query parameters:</u>
<ul>
<li><b>like:</b>
If there is a like parameter present in the query, only the locks locking the provided target id will be in the response.
</li>
<li><b>ids:</b>
This is a list and contains the ids we want to include in the response. <br/>If empty, every record is included.
</li>
<li><b>excludedIds:</b>
This is a list and contains the ids we want to exclude from the response. <br/>If empty, no record gets excluded.
</li>
<li><b>targetIds:</b>
This is a list and contains the ids of the locked targets of the locks we want to include in the response. <br/>If empty, every record is included.
</li>
<li><b>userIds:</b>
This is a list and contains the ids of the users of the locks we want to include in the response. <br/>If empty, every record is included.
</li>
<li><b>targetTypes:</b>
This is a list and determines which records we want to include in the response, based on their target type.
The target type can be <i>Plan</i>, <i>Description</i>, <i>PlanBlueprint</i> or <i>DescriptionTemplate</i>. We add 0, 1, 2 or 3 to the list respectively.
<br/>If not present, every record is included.
</li>
</ul>
""";
public static final String endpoint_query_request_body_example =
"""
{
"project":{
"fields":[
"id",
"target",
"targetType",
"lockedAt",
"lockedBy.name",
"touchedAt",
"hash",
"belongsToCurrentTenant"
]
},
"metadata":{
"countAll":true
},
"page":{
"offset":0,
"size":10
},
"isActive":[
1
],
"order":{
"items":[
"-lockedAt"
]
}
}
""";
public static final String endpoint_query_response_example =
"""
{
"items":[
{
"id":"d0423a02-abe8-4210-8ee3-504deb79d8c6",
"target":"39fabf73-546c-49a3-8789-6401f65d56b6",
"targetType":1,
"lockedBy":{
"name":"admin admin"
},
"lockedAt":"2024-06-28T08:47:03.784241Z",
"touchedAt":"2024-07-04T11:01:10.762955Z",
"hash":"1720090870",
"belongsToCurrentTenant":true
},
{
"id":"74b2ae7e-0a28-4ebc-aec9-3f849ccb3e60",
"target":"37701076-e0ff-4e4f-95aa-9f3d6a23083a",
"targetType":2,
"lockedBy":{
"name":"admin admin"
},
"lockedAt":"2024-07-04T08:29:46.591493Z",
"touchedAt":"2024-07-04T08:33:13.451444Z",
"hash":"1720081993",
"belongsToCurrentTenant":true
},
{
"id":"642d6756-bf62-4555-9ca5-bec50c5cdb85",
"target":"212342fe-ab6f-4604-b80e-ac23aca93c76",
"targetType":3,
"lockedBy":{
"name":"admin admin"
},
"lockedAt":"2024-07-02T11:36:17.926775Z",
"touchedAt":"2024-07-02T11:39:24.278433Z",
"hash":"1719920364",
"belongsToCurrentTenant":true
},
{
"id":"4a7fd0b4-1b2e-4148-a5fc-152f73caa7e5",
"target":"0e58f8b7-a91e-432a-8de2-edf03679c313",
"targetType":1,
"lockedBy":{
"name":"admin"
},
"lockedAt":"2024-07-01T11:16:14.806474Z",
"touchedAt":"2024-07-01T11:23:21.922533Z",
"hash":"1719833001",
"belongsToCurrentTenant":true
}
],
"count":4
}
""";
}
public static final class User {
public static final String endpoint_query =
"""
This endpoint is used to fetch all the available users.<br/>
It also allows to restrict the results using a query object passed in the request body.<br/>
""";
public static final String endpoint_query_request_body =
"""
Let's explore the options this object gives us.
### <u>General query parameters:</u>
<ul>
<li><b>page:</b>
This is an object controlling the pagination of the results. It contains two properties.
</li>
<ul>
<li><b>offset:</b>
How many records to omit.
</li>
<li><b>size:</b>
How many records to include in each page.
</li>
</ul>
</ul>
For example, if we want the third page, and our pages to contain 15 elements, we would pass the following object:
```JSON
{
"offset": 30,
"size": 15
}
```
<ul>
<li><b>order:</b>
This is an object controlling the ordering of the results.
It contains a list of strings called <i>items</i> with the names of the properties to use.
<br/>If the name of the property is prefixed with a <b>'-'</b>, the ordering direction is <b>DESC</b>. Otherwise, it is <b>ASC</b>.
</li>
</ul>
For example, if we wanted to order based on the field 'createdAt' in descending order, we would pass the following object:
```JSON
{
"items": [
"-createdAt"
],
}
```
<ul>
<li><b>metadata:</b>
This is an object containing metadata for the request. There is only one available option.
<ul>
<li><b>countAll:</b>
If this is set to true, the count property included in the response will account for all the records regardless the pagination,
with all the rest of filtering options applied of course.
Otherwise, if it is set to false or not present, only the returned results will be counted.
<br/>The first option is useful for the UI clients to calculate how many result pages are available.
</li>
</ul>
</li>
<li><b>project:</b>
This is an object controlling the data projection of the results.
It contains a list of strings called <i>fields</i> with the names of the properties to project.
<br/>You can also include properties that are deeper in the object tree by prefixing them with dots.
</li>
</ul>
### <u>User specific query parameters:</u>
<ul>
<li><b>like:</b>
If there is a like parameter present in the query, only the users that include the contents of the parameter in their names will be in the response.
</li>
<li><b>ids:</b>
This is a list and contains the ids we want to include in the response. <br/>If empty, every record is included.
</li>
<li><b>excludedIds:</b>
This is a list and contains the ids we want to exclude from the response. <br/>If empty, no record gets excluded.
</li>
<li><b>isActive:</b>
This is a list and determines which records we want to include in the response, based on if they are deleted or not.
This filter works like this. If we want to view only the active records we pass [1] and for only the deleted records we pass [0].
<br/>If not present or if we pass [0,1], every record is included.
</li>
<li><b>emails:</b>
This is a list and determines which records we want to include in the response, based on their emails.
<br/>If not present, every record is included.
</li>
</ul>
""";
public static final String endpoint_query_request_body_example =
"""
{
"project":{
"fields":[
"id",
"name",
"contacts.id",
"contacts.type",
"contacts.value",
"globalRoles.id",
"globalRoles.role",
"tenantRoles.id",
"tenantRoles.role",
"additionalInfo.avatarUrl",
"updatedAt",
"createdAt",
"hash",
"isActive"
]
},
"metadata":{
"countAll":true
},
"page":{
"offset":0,
"size":10
},
"isActive":[
1
],
"order":{
"items":[
"-createdAt"
]
}
}
""";
public static final String endpoint_query_response_example =
"""
{
"items":[
{
"id":"fc97ad11-2c73-4fc4-835e-e1ca0cf7b918",
"name":"user5 user5",
"createdAt":"2024-07-03T09:59:05.005425Z",
"updatedAt":"2024-07-03T09:59:05.005425Z",
"isActive":1,
"hash":"1720000745",
"additionalInfo":{
\s
},
"contacts":[
{
"id":"8b0972d2-e9d8-4c61-b69b-907ee452dade",
"value":"user5@user5.gr",
"type":0,
"ordinal":0,
"user":{
\s
}
}
],
"globalRoles":[
{
"id":"50b8e8e8-eb02-40cb-aa6f-a99eb0f48721",
"role":"User",
"user":{
\s
}
}
],
"tenantRoles":[
{
"id":"cc0307e5-4421-4e46-b7a1-b1326e6e786b",
"role":"TenantUser",
"user":{
\s
}
}
]
},
{
"id":"b494c989-60f1-4584-bc52-b56c40c66ade",
"name":"installationadmin installationadmin",
"createdAt":"2024-06-28T13:23:24.957340Z",
"updatedAt":"2024-06-28T13:23:24.957340Z",
"isActive":1,
"hash":"1719581004",
"additionalInfo":{
\s
},
"contacts":[
{
"id":"cd281a02-f851-400f-ba7f-391e16884051",
"value":"installationadmin@dmp.gr",
"type":0,
"ordinal":0,
"user":{
\s
}
}
],
"globalRoles":[
{
"id":"1d4088c3-7d42-4227-93d9-ee46ead5f500",
"role":"InstallationAdmin",
"user":{
\s
}
}
],
"tenantRoles":[
{
"id":"b606b428-f404-4232-81fa-a313fcbab25a",
"role":"TenantUser",
"user":{
\s
}
}
]
},
{
"id":"5119e0a6-53ee-4cad-ae58-aa3c1fc79683",
"name":"user3 user3",
"createdAt":"2024-06-28T11:23:22.962858Z",
"updatedAt":"2024-06-28T11:23:22.962858Z",
"isActive":1,
"hash":"1719573802",
"additionalInfo":{
\s
},
"contacts":[
{
"id":"18f1f3f2-77d6-4258-a7d0-1623d7282b82",
"value":"user3@dmp.gr",
"type":0,
"ordinal":0,
"user":{
\s
}
}
],
"globalRoles":[
{
"id":"116ec22c-3b3a-44ae-9de0-be31c8d621c2",
"role":"User",
"user":{
\s
}
}
],
"tenantRoles":[
{
"id":"618b266b-ecdb-46cd-a5c5-686dc76bba12",
"role":"TenantUser",
"user":{
\s
}
}
]
},
{
"id":"d1873841-3ae3-4a1c-8cfc-841327552313",
"name":"dmproot dmproot",
"createdAt":"2024-06-28T07:19:37.150149Z",
"updatedAt":"2024-06-28T07:19:37.150149Z",
"isActive":1,
"hash":"1719559177",
"additionalInfo":{
\s
},
"contacts":[
{
"id":"20d108c6-8277-40d0-a2b8-e6d8c9c332f0",
"value":"dmproot@cite.gr",
"type":0,
"ordinal":0,
"user":{
\s
}
}
],
"globalRoles":[
{
"id":"209b7b67-5374-4b11-a1cf-ecfba6da5f16",
"role":"Admin",
"user":{
\s
}
},
{
"id":"5d7ee923-5456-456c-b46f-b53458b0e10a",
"role":"User",
"user":{
\s
}
}
],
"tenantRoles":[
{
"id":"4a14b1fd-2e35-4817-89fa-9d8bf741aee7",
"role":"TenantUser",
"user":{
\s
}
}
]
},
{
"id":"890667ae-7efd-49d9-8ab5-3d48b84a48d1",
"name":"admin admin",
"createdAt":"2024-06-28T07:07:18.589432Z",
"updatedAt":"2024-06-28T07:07:18.589432Z",
"isActive":1,
"hash":"1719558438",
"additionalInfo":{
\s
},
"contacts":[
{
"id":"9739739b-b5d9-4e13-bc47-637b3760b340",
"value":"admin@dmp.gr",
"type":0,
"ordinal":0,
"user":{
\s
}
}
],
"globalRoles":[
{
"id":"718dd2d0-cbda-4b33-b8be-a25ec30a53f3",
"role":"User",
"user":{
\s
}
},
{
"id":"c2c4129e-dcec-448a-8e7c-e4dd7cbc3d9d",
"role":"Admin",
"user":{
\s
}
}
],
"tenantRoles":[
{
"id":"6961542d-6ea7-4064-a0ad-20d82896b9de",
"role":"TenantAdmin",
"user":{
\s
}
}
]
},
{
"id":"1f709343-353b-4787-a8e0-f71020b53f94",
"name":"user5847",
"createdAt":"2024-06-26T22:46:43Z",
"updatedAt":"2024-06-26T22:46:43Z",
"isActive":1,
"hash":"1719442003",
"additionalInfo":{
"avatarUrl":"null"
},
"contacts":[
{
"id":"b8c17fa6-c8e1-49d8-9c7b-173dad43d995",
"value":"user5847@dmp.gr",
"type":0,
"ordinal":0,
"user":{
\s
}
}
]
},
{
"id":"ac633bd9-ac0b-4258-adc5-24246e1dacbc",
"name":"user5846",
"createdAt":"2024-06-26T22:08:44Z",
"updatedAt":"2024-06-26T22:08:44Z",
"isActive":1,
"hash":"1719439724",
"additionalInfo":{
"avatarUrl":"null"
},
"contacts":[
{
"id":"0126a7d6-c2f3-4f2e-85cc-9c999d74fa85",
"value":"user5846@dmp.gr",
"type":0,
"ordinal":0,
"user":{
\s
}
}
]
},
{
"id":"2b4e633b-5451-46fb-a1ad-34c1f8fb8fe7",
"name":"user5844",
"createdAt":"2024-06-26T17:04:01Z",
"updatedAt":"2024-06-26T17:04:01Z",
"isActive":1,
"hash":"1719421441",
"additionalInfo":{
"avatarUrl":"null"
},
"contacts":[
{
"id":"138b9b60-8bfb-4900-8f0f-32dd70c8841c",
"value":"user5844@dmp.gr",
"type":0,
"ordinal":0,
"user":{
\s
}
}
]
},
{
"id":"d9d0ae8b-8037-403e-a155-28d2387d6d7f",
"name":"user5842",
"createdAt":"2024-06-26T13:38:58Z",
"updatedAt":"2024-06-26T13:38:58Z",
"isActive":1,
"hash":"1719409138",
"additionalInfo":{
"avatarUrl":"null"
},
"contacts":[
{
"id":"12bb3f67-941c-4731-8de0-b8d43ff6e17a",
"value":"user5842@dmp.gr",
"type":0,
"ordinal":0,
"user":{
\s
}
}
]
},
{
"id":"3748e22c-3760-4ada-88ef-8addd247fc76",
"name":"user5841",
"createdAt":"2024-06-26T13:19:52Z",
"updatedAt":"2024-06-26T13:22:19Z",
"isActive":1,
"hash":"1719408139",
"additionalInfo":{
"avatarUrl":"null"
},
"contacts":[
{
"id":"d536278f-9714-43f8-846c-cb5c6bcf2f59",
"value":"user5841@dmp.gr",
"type":0,
"ordinal":0,
"user":{
\s
}
}
]
}
],
"count":5821
}
""";
}
public static final class Principal {
}
}

View File

@ -11,7 +11,7 @@ springdoc:
displayName: Current
packagesToScan: org.opencdmp.controllers
packagesToExclude: org.opencdmp.controllers.publicapi
pathsToMatch: "/api/plan/**, /api/description/**, /api/description-template/**, /api/description-template-type/**, /api/plan-blueprint/**, /api/entity-doi/**, /api/deposit/**, /api/file-transformer/**, /api/tag/**, /api/reference/**, /api/reference-type/**"
pathsToMatch: "/api/plan/**, /api/description/**, /api/description-template/**, /api/description-template-type/**, /api/plan-blueprint/**, /api/entity-doi/**, /api/deposit/**, /api/file-transformer/**, /api/tag/**, /api/reference/**, /api/reference-type/**, /api/lock/**, /api/user/**, /api/principal/**"
swaggerUi:
enabled: true
useRootPath: true

View File

@ -279,7 +279,7 @@ export class DescriptionPropertyDefinitionFieldSetEditorModel implements Descrip
public fromModel(item: DescriptionPropertyDefinitionFieldSet, descriptionReferences: DescriptionReference[], definitionFieldSet: DescriptionTemplateFieldSet): DescriptionPropertyDefinitionFieldSetEditorModel {
this.fieldSetDefinition = definitionFieldSet;
if (item) {
if (item.items) { item.items.map(x => this.items.push(new DescriptionPropertyDefinitionFieldSetItemEditorModel(this.validationErrorModel).fromModel(x, descriptionReferences, definitionFieldSet))); }
if (item.items) { item.items.sort(x=> x.ordinal).map(x => this.items.push(new DescriptionPropertyDefinitionFieldSetItemEditorModel(this.validationErrorModel).fromModel(x, descriptionReferences, definitionFieldSet))); }
}
return this;
}

View File

@ -39,17 +39,17 @@
<dependency>
<groupId>org.opencdmp</groupId>
<artifactId>repositorydepositbase</artifactId>
<version>2.0.15</version>
<version>2.0.16</version>
</dependency>
<dependency>
<groupId>org.opencdmp</groupId>
<artifactId>file-transformer-base</artifactId>
<version>0.0.23</version>
<version>0.0.24</version>
</dependency>
<dependency>
<groupId>org.opencdmp</groupId>
<artifactId>common-models</artifactId>
<version>0.0.18</version>
<version>0.0.19</version>
</dependency>
<dependency>

View File

@ -296,6 +296,8 @@ public class DatasetMigrationService {
this.ensureDescriptionReferenceOrdinal(fieldSet, descriptionReferenceEntitiesMap, descriptionReferenceDataEntityById, ordinal);
fieldSet.setOrdinal(ordinal);
}
fieldSetEntity.setItems(fieldSetEntity.getItems().stream().sorted(Comparator.comparingInt(PropertyDefinitionFieldSetItemEntity::getOrdinal)).toList());
}
this.entityManager.flush();