diff --git a/.gitignore b/.gitignore
index efd255a32..163f4068e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,32 +1,32 @@
dmp-frontend/dist.7z
.idea/
*.iml
-dmp-backend/src/main/ui-resources/static/vendor.bundle.js.map
-dmp-backend/src/main/ui-resources/static/vendor.bundle.js
-dmp-backend/src/main/ui-resources/static/unauthorized.module.chunk.js.map
-dmp-backend/src/main/ui-resources/static/unauthorized.module.chunk.js
-dmp-backend/src/main/ui-resources/static/styles.bundle.js.map
-dmp-backend/src/main/ui-resources/static/styles.bundle.js
-dmp-backend/src/main/ui-resources/static/polyfills.bundle.js.map
-dmp-backend/src/main/ui-resources/static/polyfills.bundle.js
-dmp-backend/src/main/ui-resources/static/main.bundle.js.map
-dmp-backend/src/main/ui-resources/static/main.bundle.js
-dmp-backend/src/main/ui-resources/static/lang/en.json
-dmp-backend/src/main/ui-resources/static/inline.bundle.js.map
-dmp-backend/src/main/ui-resources/static/inline.bundle.js
-dmp-backend/src/main/ui-resources/static/index.html
-dmp-backend/src/main/ui-resources/static/favicon.ico
-dmp-backend/src/main/ui-resources/static/assets/lang/en.json
+backend/src/main/ui-resources/static/vendor.bundle.js.map
+backend/src/main/ui-resources/static/vendor.bundle.js
+backend/src/main/ui-resources/static/unauthorized.module.chunk.js.map
+backend/src/main/ui-resources/static/unauthorized.module.chunk.js
+backend/src/main/ui-resources/static/styles.bundle.js.map
+backend/src/main/ui-resources/static/styles.bundle.js
+backend/src/main/ui-resources/static/polyfills.bundle.js.map
+backend/src/main/ui-resources/static/polyfills.bundle.js
+backend/src/main/ui-resources/static/main.bundle.js.map
+backend/src/main/ui-resources/static/main.bundle.js
+backend/src/main/ui-resources/static/lang/en.json
+backend/src/main/ui-resources/static/inline.bundle.js.map
+backend/src/main/ui-resources/static/inline.bundle.js
+backend/src/main/ui-resources/static/index.html
+backend/src/main/ui-resources/static/favicon.ico
+backend/src/main/ui-resources/static/assets/lang/en.json
dmp-frontend/new 3.xml
-dmp-backend/src/main/ui-resources/static/
-dmp-backend/web/target/
+backend/src/main/ui-resources/static/
+backend/web/target/
*.class
-dmp-backend/web/src/main/ui-resources/static/
-dmp-backend/data/target/data-1.0-SNAPSHOT.jar
-dmp-backend/data/target/
-dmp-backend/queryable/target/
-dmp-backend/elastic/target/
-dmp-backend/queryengine/target/
+backend/web/src/main/ui-resources/static/
+backend/data/target/data-1.0-SNAPSHOT.jar
+backend/data/target/
+backend/queryable/target/
+backend/elastic/target/
+backend/queryengine/target/
*.tar
*.gz
final/
@@ -38,7 +38,7 @@ dmp-frontend/.vscode/
dmp-frontend/package-lock.json
-dmp-backend/logging/target/
+backend/logging/target/
ELK.Docker/shared/data-elk/
# Eclipse
@@ -47,12 +47,12 @@ ELK.Docker/shared/data-elk/
bin/
*.classpath
.run
-openDMP/dmp-backend/uploads/
-openDMP/dmp-backend/tmp/
+openDMP/backend/uploads/
+openDMP/backend/tmp/
logs/
-dmp-backend/web/src/main/resources/certificates/
+backend/web/src/main/resources/certificates/
/storage/
-dmp-backend/target/classes/
-dmp-backend/core/target/maven-archiver/
-dmp-backend/node_modules/.yarn-integrity
+backend/target/classes/
+backend/core/target/maven-archiver/
+backend/node_modules/.yarn-integrity
dmp-frontend/.nx/
diff --git a/dmp-backend/Dockerfile b/backend/Dockerfile
similarity index 100%
rename from dmp-backend/Dockerfile
rename to backend/Dockerfile
diff --git a/dmp-backend/Dockerfile.Sonar b/backend/Dockerfile.Sonar
similarity index 100%
rename from dmp-backend/Dockerfile.Sonar
rename to backend/Dockerfile.Sonar
diff --git a/backend/core/pom.xml b/backend/core/pom.xml
new file mode 100644
index 000000000..afe6aa264
--- /dev/null
+++ b/backend/core/pom.xml
@@ -0,0 +1,109 @@
+
+
+ 4.0.0
+
+ core
+ ${revision}
+
+
+ org.opencdmp
+ opencdmp-backend
+ ${revision}
+ ../pom.xml
+
+
+
+ 21
+ 21
+ 21
+ 21
+ UTF-8
+ 1.0.0-SNAPSHOT
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-validation
+
+
+ org.apache.commons
+ commons-csv
+ 1.10.0
+
+
+ commons-validator
+ commons-validator
+ 1.8.0
+
+
+ gr.cite
+ validation
+ 3.0.3
+
+
+ gr.cite
+ oidc-authz
+ 2.1.0
+
+
+ gr.cite.opendmp
+ repositorydepositbase
+ 2.0.7
+
+
+ gr.cite.opendmp
+ common-models
+ 0.0.10
+
+
+ gr.cite.opendmp
+ file-transformer-base
+ 0.0.14
+
+
+ gr.cite
+ elastic
+ 2.1.2
+
+
+ gr.cite
+ queue-inbox
+ 2.1.1
+
+
+ gr.cite
+ queue-outbox
+ 2.1.1
+
+
+
+ gr.cite
+ oidc-authn
+ 2.2.2
+
+
+
+ gr.cite
+ keycloak-api
+ 2.3.0
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+
+ 21
+
+
+
+
+
+
\ No newline at end of file
diff --git a/backend/core/src/main/java/org/opencdmp/audit/AuditableAction.java b/backend/core/src/main/java/org/opencdmp/audit/AuditableAction.java
new file mode 100644
index 000000000..2b8ad850c
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/audit/AuditableAction.java
@@ -0,0 +1,173 @@
+package org.opencdmp.audit;
+
+import gr.cite.tools.logging.EventId;
+
+public class AuditableAction {
+
+ public static final EventId DescriptionTemplateType_Query = new EventId(1000, "DescriptionTemplateType_Query");
+ public static final EventId DescriptionTemplateType_Lookup = new EventId(1001, "DescriptionTemplateType_Lookup");
+ public static final EventId DescriptionTemplateType_Persist = new EventId(1002, "DescriptionTemplateType_Persist");
+ public static final EventId DescriptionTemplateType_Delete = new EventId(1003, "DescriptionTemplateType_Delete");
+
+ public static final EventId EntityDoi_Query = new EventId(2000, "EntityDoi_Query");
+ public static final EventId EntityDoi_Lookup = new EventId(2001, "EntityDoi_Lookup");
+ public static final EventId EntityDoi_Persist = new EventId(2002, "EntityDoi_Persist");
+ public static final EventId EntityDoi_Delete = new EventId(2003, "EntityDoi_Delete");
+
+ public static final EventId DmpBlueprint_Query = new EventId(3000, "DmpBlueprint_Query");
+ public static final EventId DmpBlueprint_Lookup = new EventId(3001, "DmpBlueprint_Lookup");
+ 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_Clone = new EventId(3004, "DmpBlueprint_Clone");
+
+ 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_Lookup = new EventId(4001, "User_Settings_Lookup");
+ public static final EventId User_Settings_Persist = new EventId(4002, "User_Settings_Persist");
+ public static final EventId User_Settings_Delete = new EventId(4003, "User_Settings_Delete");
+
+ public static final EventId Dmp_Query = new EventId(5000, "Dmp_Query");
+ public static final EventId Dmp_Lookup = new EventId(5001, "Dmp_Lookup");
+ public static final EventId Dmp_Persist = new EventId(5002, "Dmp_Persist");
+ public static final EventId Dmp_Delete = new EventId(5003, "Dmp_Delete");
+ public static final EventId Dmp_Clone = new EventId(5004, "Dmp_Clone");
+ public static final EventId Dmp_PersistNewVersion = new EventId(5005, "Dmp_PersistNewVersion");
+ public static final EventId Dmp_Assign_Users = new EventId(5006, "Dmp_Assign_Users");
+ public static final EventId Dmp_RemoveUser = new EventId(5007, "Dmp_RemoveUser");
+ public static final EventId Dmp_Invite_Users = new EventId(5008, "Dmp_Invite_Users");
+ public static final EventId Dmp_Invite_Accept = new EventId(5009, "Dmp_Invite_Accept");
+ public static final EventId Dmp_PublicQuery = new EventId(5010, "Dmp_PublicQuery");
+ public static final EventId Dmp_Export = new EventId(5011, "Dmp_Export");
+ public static final EventId Dmp_PublicLookup = new EventId(5012, "Dmp_PublicLookup");
+ public static final EventId Dmp_Finalize = new EventId(5013, "Dmp_Finalize");
+ public static final EventId Dmp_Undo_Finalize = new EventId(5014, "Dmp_Undo_Finalize");
+ public static final EventId Dmp_Validate = new EventId(5015, "Dmp_Validate");
+
+
+ public static final EventId Description_Query = new EventId(6000, "Description_Query");
+ public static final EventId Description_Lookup = new EventId(6001, "Description_Lookup");
+ public static final EventId Description_Persist = new EventId(6002, "Description_Persist");
+ public static final EventId Description_Delete = new EventId(6003, "Description_Delete");
+ public static final EventId Description_PublicQuery = new EventId(6004, "Description_PublicQuery");
+ public static final EventId Description_PublicLookup = new EventId(6005, "Description_PublicLookup");
+ public static final EventId Description_PersistStatus = new EventId(6006, "Description_PersistStatus");
+ public static final EventId Description_UploadFieldFiles = new EventId(6007, "Description_UploadFieldFiles");
+ public static final EventId Description_GetFieldFile = new EventId(6008, "Description_GetFieldFile");
+ public static final EventId Description_Validate = new EventId(6009, "Description_Validate");
+ public static final EventId Description_GetDescriptionSectionPermissions = new EventId(6010, "Description_GetDescriptionSectionPermissions");
+ public static final EventId Description_UpdateDescriptionTemplate = new EventId(6011, "Description_UpdateDescriptionTemplate");
+
+
+ public static final EventId Reference_Query = new EventId(7000, "Reference_Query");
+ public static final EventId Reference_Lookup = new EventId(7001, "Reference_Lookup");
+ public static final EventId Reference_Persist = new EventId(7002, "Reference_Persist");
+ public static final EventId Reference_Delete = new EventId(7003, "Reference_Delete");
+ public static final EventId Reference_Search = new EventId(7004, "Reference_Search");
+
+ public static final EventId DescriptionTemplate_Query = new EventId(8000, "DescriptionTemplate_Query");
+ public static final EventId DescriptionTemplate_Lookup = new EventId(8001, "DescriptionTemplate_Lookup");
+ public static final EventId DescriptionTemplate_Persist = new EventId(8002, "DescriptionTemplate_Persist");
+ public static final EventId DescriptionTemplate_Delete = new EventId(8003, "DescriptionTemplate_Delete");
+ public static final EventId DescriptionTemplate_Clone = new EventId(8004, "DescriptionTemplate_Clone");
+ public static final EventId DescriptionTemplate_PersistNewVersion = new EventId(8005, "DescriptionTemplate_PersistNewVersion");
+ public static final EventId DescriptionTemplate_GetXml = new EventId(8006, "DescriptionTemplate_GetXml");
+ public static final EventId DescriptionTemplate_Import = new EventId(8007, "DescriptionTemplate_Import");
+
+ public static final EventId SupportiveMaterial_Query = new EventId(9000, "SupportiveMaterial_Query");
+ public static final EventId SupportiveMaterial_Lookup = new EventId(9001, "SupportiveMaterial_Lookup");
+ public static final EventId SupportiveMaterial_Persist = new EventId(9002, "SupportiveMaterial_Persist");
+ public static final EventId SupportiveMaterial_Delete = new EventId(9003, "SupportiveMaterial_Delete");
+
+ public static final EventId ReferenceType_Query = new EventId(10000, "ReferenceType_Query");
+ public static final EventId ReferenceType_Lookup = new EventId(10001, "ReferenceType_Lookup");
+ public static final EventId ReferenceType_Persist = new EventId(10002, "ReferenceType_Persist");
+ public static final EventId ReferenceType_Delete = new EventId(10003, "ReferenceType_Delete");
+
+ public static final EventId User_Query = new EventId(11000, "User_Query");
+ public static final EventId User_Lookup = new EventId(11001, "User_Lookup");
+ public static final EventId User_Persist = new EventId(11002, "User_Persist");
+ public static final EventId User_Delete = new EventId(11003, "User_Delete");
+ public static final EventId User_LookupByEmail = new EventId(11004, "User_LookupByEmail");
+ public static final EventId User_ExportCsv = new EventId(11005, "User_ExportCsv");
+ public static final EventId User_PersistRoles = new EventId(11006, "User_PersistRoles");
+ public static final EventId User_LanguageMine = new EventId(11007, "User_LanguageMine");
+ public static final EventId User_TimezoneMine = new EventId(11008, "User_TimezoneMine");
+ public static final EventId User_CultureMine = new EventId(11009, "User_CultureMine");
+ public static final EventId User_MergeRequest = new EventId(11010, "User_MergeRequest");
+ public static final EventId User_MergeConfirm = new EventId(11011, "User_MergeConfirm");
+ public static final EventId User_RemoveCredentialRequest = new EventId(11012, "User_RemoveCredentialRequest");
+ public static final EventId User_RemoveCredentialConfirm = new EventId(11013, "User_RemoveCredentialConfirm");
+ public static final EventId User_DmpAssociatedQuery = new EventId(11014, "User_DmpAssociatedQuery");
+
+ public static final EventId Tenant_Query = new EventId(12000, "Tenant_Query");
+ public static final EventId Tenant_Lookup = new EventId(12001, "Tenant_Lookup");
+ public static final EventId Tenant_Persist = new EventId(12002, "Tenant_Persist");
+ public static final EventId Tenant_Delete = new EventId(12003, "Tenant_Delete");
+
+ public static final EventId Language_Query = new EventId(13000, "Language_Query");
+ public static final EventId Language_Lookup = new EventId(13001, "Language_Lookup");
+ public static final EventId Language_Persist = new EventId(13002, "Language_Persist");
+ public static final EventId Language_Delete = new EventId(13003, "Language_Delete");
+
+ public static final EventId StorageFile_Download = new EventId(14000, "StorageFile_Download");
+ public static final EventId StorageFile_Upload = new EventId(14001, "StorageFile_Upload");
+ public static final EventId StorageFile_Query = new EventId(14002, "StorageFile_Query");
+
+ public static final EventId Dashboard_MyRecentActivityItems = new EventId(15000, "Dashboard_MyRecentActivityItems");
+ public static final EventId Dashboard_MyDashboardStatistics = new EventId(15001, "Dashboard_MyDashboardStatistics");
+ public static final EventId Dashboard_PublicDashboardStatistics = new EventId(15002, "Dashboard_PublicDashboardStatistics");
+
+ public static final EventId Notification_Persist = new EventId(16000, "Notification_Persist");
+
+ public static final EventId Lock_Query = new EventId(17000, "Lock_Query");
+ public static final EventId Lock_Lookup = new EventId(17001, "Lock_Lookup");
+ public static final EventId Lock_Persist = new EventId(17002, "Lock_Persist");
+ public static final EventId Lock_Delete = new EventId(17003, "Lock_Delete");
+ public static final EventId Lock_IsLocked = new EventId(17004, "Lock_IsLocked");
+ public static final EventId Lock_UnLocked = new EventId(17005, "Lock_UnLocked");
+ public static final EventId Lock_Touched = new EventId(17006, "Lock_Touched");
+ public static final EventId Lock_Locked = new EventId(17007, "Lock_Locked");
+
+ public static final EventId Deposit_GetAvailableRepositories = new EventId(18000, "Deposit_GetAvailableRepositories");
+ public static final EventId Deposit_GetAccessToken = new EventId(18001, "Deposit_GetAccessToken");
+ public static final EventId Deposit_Deposit = new EventId(18002, "Deposit_Deposit");
+ public static final EventId Deposit_GetLogo = new EventId(18003, "Deposit_GetLogo");
+
+ public static final EventId Tag_Query = new EventId(19000, "Tag_Query");
+ public static final EventId Tag_Lookup = new EventId(19001, "Tag_Lookup");
+ public static final EventId Tag_Persist = new EventId(19002, "Tag_Persist");
+ public static final EventId Tag_Delete = new EventId(19003, "Tag_Delete");
+
+ public static final EventId FileTransformer_GetAvailableConfigurations = new EventId(20000, "FileTransformer_GetAvailableConfigurations");
+
+ public static final EventId ContactSupport_Sent = new EventId(210000, "ContactSupport_Sent");
+ public static final EventId ContactSupport_PublicSent = new EventId(210001, "ContactSupport_PublicSent");
+
+ public static final EventId Maintenance_GenerateElastic = new EventId(220000, "Maintenance_GenerateElastic");
+ public static final EventId Maintenance_ClearElastic = new EventId(230000, "Maintenance_ClearElastic");
+ public static final EventId Maintenance_SendUserTouchEvents = new EventId(230001, "Maintenance_SendUserTouchEvents");
+ public static final EventId Maintenance_SendTenantTouchEvents = new EventId(230002, "Maintenance_SendTenantTouchEvents");
+
+ public static final EventId Principal_Lookup = new EventId(240000, "Principal_Lookup");
+ public static final EventId Principal_MyTenants = new EventId(240001, "Principal_MyTenants");
+
+ public static final EventId GetSemantics = new EventId(250000, "GetSemantics");
+
+ public static final EventId PrefillingSource_Query = new EventId(260000, "PrefillingSource_Query");
+ public static final EventId PrefillingSource_Lookup = new EventId(260001, "PrefillingSource_Lookup");
+ public static final EventId PrefillingSource_Persist = new EventId(260002, "PrefillingSource_Persist");
+ public static final EventId PrefillingSource_Delete = new EventId(260003, "PrefillingSource_Delete");
+ public static final EventId PrefillingSource_Generate = new EventId(260004, "PrefillingSource_Generate");
+
+ public static final EventId TenantConfiguration_Query = new EventId(270000, "TenantConfiguration_Query");
+ public static final EventId TenantConfiguration_Lookup = new EventId(270001, "TenantConfiguration_Lookup");
+ public static final EventId TenantConfiguration_Persist = new EventId(270002, "TenantConfiguration_Persist");
+ public static final EventId TenantConfiguration_Delete = new EventId(270003, "TenantConfiguration_Delete");
+ public static final EventId TenantConfiguration_LookupByType = new EventId(270004, "TenantConfiguration_LookupByType");
+
+
+
+}
diff --git a/backend/core/src/main/java/org/opencdmp/authorization/AffiliatedAuthorizationRequirement.java b/backend/core/src/main/java/org/opencdmp/authorization/AffiliatedAuthorizationRequirement.java
new file mode 100644
index 000000000..c5450f0f4
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/authorization/AffiliatedAuthorizationRequirement.java
@@ -0,0 +1,40 @@
+package org.opencdmp.authorization;
+
+import gr.cite.commons.web.authz.policy.AuthorizationRequirement;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+public class AffiliatedAuthorizationRequirement implements AuthorizationRequirement {
+ private final Set requiredPermissions;
+ private final boolean matchAll;
+
+ public AffiliatedAuthorizationRequirement(Set requiredPermissions) {
+ this(false, requiredPermissions);
+ }
+
+ public AffiliatedAuthorizationRequirement(String... requiredPermissions) {
+ this(false, requiredPermissions);
+
+ }
+
+ public AffiliatedAuthorizationRequirement(boolean matchAll, Set requiredPermissions) {
+ this.matchAll = matchAll;
+ this.requiredPermissions = requiredPermissions;
+ }
+
+ public AffiliatedAuthorizationRequirement(boolean matchAll, String... requiredPermissions) {
+ this.requiredPermissions = new HashSet<>();
+ this.matchAll = matchAll;
+ this.requiredPermissions.addAll(Arrays.stream(requiredPermissions).distinct().toList());
+ }
+
+ public Set getRequiredPermissions() {
+ return requiredPermissions;
+ }
+
+ public boolean getMatchAll() {
+ return matchAll;
+ }
+}
diff --git a/backend/core/src/main/java/org/opencdmp/authorization/AffiliatedResource.java b/backend/core/src/main/java/org/opencdmp/authorization/AffiliatedResource.java
new file mode 100644
index 000000000..f6c469e92
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/authorization/AffiliatedResource.java
@@ -0,0 +1,31 @@
+package org.opencdmp.authorization;
+
+import org.opencdmp.commons.enums.DmpUserRole;
+import gr.cite.commons.web.authz.policy.AuthorizationResource;
+
+import java.util.HashSet;
+import java.util.List;
+
+public class AffiliatedResource extends AuthorizationResource {
+ private HashSet dmpUserRoles;
+
+ public AffiliatedResource() {
+ dmpUserRoles = new HashSet<>();
+ }
+
+ public AffiliatedResource(DmpUserRole dmpUserRole) {
+ this(List.of(dmpUserRole));
+ }
+
+ public AffiliatedResource(List dmpUserRoles) {
+ this.dmpUserRoles = new HashSet<>(dmpUserRoles);
+ }
+
+ public HashSet getDmpUserRoles() {
+ return dmpUserRoles;
+ }
+
+ public void setDmpUserRoles(HashSet dmpUserRoles) {
+ this.dmpUserRoles = dmpUserRoles;
+ }
+}
diff --git a/backend/core/src/main/java/org/opencdmp/authorization/AuthorizationConfiguration.java b/backend/core/src/main/java/org/opencdmp/authorization/AuthorizationConfiguration.java
new file mode 100644
index 000000000..9cf23acee
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/authorization/AuthorizationConfiguration.java
@@ -0,0 +1,9 @@
+package org.opencdmp.authorization;
+
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration("AppAuthorizationConfiguration")
+@EnableConfigurationProperties(AuthorizationProperties.class)
+public class AuthorizationConfiguration {
+}
diff --git a/backend/core/src/main/java/org/opencdmp/authorization/AuthorizationFlags.java b/backend/core/src/main/java/org/opencdmp/authorization/AuthorizationFlags.java
new file mode 100644
index 000000000..516749ca3
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/authorization/AuthorizationFlags.java
@@ -0,0 +1,8 @@
+package org.opencdmp.authorization;
+
+import java.util.EnumSet;
+
+public enum AuthorizationFlags {
+ None, Permission, DmpAssociated, Public, Owner;
+ public static final EnumSet OwnerOrDmpAssociatedOrPermission = EnumSet.of(DmpAssociated, Permission, Owner);
+}
diff --git a/backend/core/src/main/java/org/opencdmp/authorization/AuthorizationProperties.java b/backend/core/src/main/java/org/opencdmp/authorization/AuthorizationProperties.java
new file mode 100644
index 000000000..ef9670d7e
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/authorization/AuthorizationProperties.java
@@ -0,0 +1,50 @@
+package org.opencdmp.authorization;
+
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+import java.util.HashSet;
+import java.util.List;
+
+@ConfigurationProperties(prefix = "authorization")
+public class AuthorizationProperties {
+
+ private String globalAdminRole;
+
+ public String getGlobalAdminRole() {
+ return globalAdminRole;
+ }
+
+ public void setGlobalAdminRole(String globalAdminRole) {
+ this.globalAdminRole = globalAdminRole;
+ }
+ private Boolean autoAssignGlobalAdminToNewTenants;
+
+ public Boolean getAutoAssignGlobalAdminToNewTenants() {
+ return autoAssignGlobalAdminToNewTenants;
+ }
+
+ public void setAutoAssignGlobalAdminToNewTenants(Boolean autoAssignGlobalAdminToNewTenants) {
+ this.autoAssignGlobalAdminToNewTenants = autoAssignGlobalAdminToNewTenants;
+ }
+
+ private List allowedTenantRoles;
+
+ public List getAllowedTenantRoles() {
+ return allowedTenantRoles;
+ }
+
+ public void setAllowedTenantRoles(List allowedTenantRoles) {
+ this.allowedTenantRoles = allowedTenantRoles;
+ }
+
+ private List allowedGlobalRoles;
+
+ public List getAllowedGlobalRoles() {
+ return allowedGlobalRoles;
+ }
+
+ public void setAllowedGlobalRoles(List allowedGlobalRoles) {
+ this.allowedGlobalRoles = allowedGlobalRoles;
+ }
+}
diff --git a/backend/core/src/main/java/org/opencdmp/authorization/ClaimNames.java b/backend/core/src/main/java/org/opencdmp/authorization/ClaimNames.java
new file mode 100644
index 000000000..c893b6ac8
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/authorization/ClaimNames.java
@@ -0,0 +1,9 @@
+package org.opencdmp.authorization;
+
+public class ClaimNames {
+ public static final String ExternalProviderName = "ExternalProviderName";
+ public static final String TenantCodesClaimName = "TenantCodes";
+ public static final String TenantClaimName = "x-tenant";
+ public static final String GlobalRolesClaimName = "GlobalRoles";
+ public static final String TenantRolesClaimName = "TenantRoles";
+}
diff --git a/backend/core/src/main/java/org/opencdmp/authorization/OwnedAuthorizationRequirement.java b/backend/core/src/main/java/org/opencdmp/authorization/OwnedAuthorizationRequirement.java
new file mode 100644
index 000000000..19ccdafcf
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/authorization/OwnedAuthorizationRequirement.java
@@ -0,0 +1,6 @@
+package org.opencdmp.authorization;
+
+import gr.cite.commons.web.authz.policy.AuthorizationRequirement;
+
+public class OwnedAuthorizationRequirement implements AuthorizationRequirement {
+}
diff --git a/backend/core/src/main/java/org/opencdmp/authorization/OwnedResource.java b/backend/core/src/main/java/org/opencdmp/authorization/OwnedResource.java
new file mode 100644
index 000000000..f0b7cc6f4
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/authorization/OwnedResource.java
@@ -0,0 +1,26 @@
+package org.opencdmp.authorization;
+
+import gr.cite.commons.web.authz.policy.AuthorizationResource;
+
+import java.util.List;
+import java.util.UUID;
+
+public class OwnedResource extends AuthorizationResource {
+ private List userIds;
+
+ public OwnedResource(UUID userId) {
+ this(List.of(userId));
+ }
+
+ public OwnedResource(List userIds) {
+ this.userIds = userIds;
+ }
+
+ public List getUserIds() {
+ return userIds;
+ }
+
+ public void setUserIds(List userIds) {
+ this.userIds = userIds;
+ }
+}
diff --git a/backend/core/src/main/java/org/opencdmp/authorization/Permission.java b/backend/core/src/main/java/org/opencdmp/authorization/Permission.java
new file mode 100644
index 000000000..23498eccf
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/authorization/Permission.java
@@ -0,0 +1,222 @@
+package org.opencdmp.authorization;
+
+public final class Permission {
+ /////
+ public static String DeferredAffiliation = "DeferredAffiliation";
+
+ //Public
+ public static String PublicBrowseDescription = "PublicBrowseDescription";
+ public static String PublicBrowseDescriptionTemplate = "PublicBrowseDescriptionTemplate";
+ public static String PublicBrowseDmp = "PublicBrowseDmp";
+ public static String PublicBrowseDmpReference = "PublicBrowseDmpReference";
+ public static String PublicBrowseDmpUser = "PublicBrowseDmpUser";
+ public static String PublicBrowseReference = "PublicBrowseReference";
+ public static String PublicBrowseUser = "PublicBrowseUser";
+ public static String PublicBrowseDashboardStatistics = "PublicBrowseDashboardStatistics";
+ public static String PublicSendContactSupport = "PublicSendContactSupport";
+ public static String PublicBrowseReferenceType = "PublicBrowseReferenceType";
+ //Elastic
+ public static String ManageElastic = "ManageElastic";
+ //Queue Events
+ public static String ManageQueueEvents = "ManageQueueEvents";
+
+
+ //Deposit
+ public static String BrowseDeposit = "BrowseDeposit";
+ public static String EditDeposit = "BrowseDeposit";
+
+
+ //Language
+ public static String BrowseLanguage = "BrowseLanguage";
+ public static String EditLanguage = "EditLanguage";
+ public static String DeleteLanguage = "DeleteLanguage";
+
+
+ //NotificationTemplate
+ public static String BrowseNotificationTemplate = "BrowseNotificationTemplate";
+ public static String EditNotificationTemplate = "EditNotificationTemplate";
+ public static String DeleteNotificationTemplate = "DeleteNotificationTemplate";
+
+ //Language
+ public static String BrowseStatistics = "BrowseStatistics";
+ public static String BrowsePublicStatistics = "BrowsePublicStatistics";
+
+ //DescriptionTemplate
+ public static String BrowseDescriptionTemplate = "BrowseDescriptionTemplate";
+ public static String EditDescriptionTemplate = "EditDescriptionTemplate";
+ public static String DeleteDescriptionTemplate = "DeleteDescriptionTemplate";
+ public static String CloneDescriptionTemplate = "CloneDescriptionTemplate";
+ public static String CreateNewVersionDescriptionTemplate = "CreateNewVersionDescriptionTemplate";
+ public static String ImportDescriptionTemplate = "ImportDescriptionTemplate";
+ public static String ExportDescriptionTemplate = "ExportDescriptionTemplate";
+
+
+
+ //User
+ public static String BrowseUser = "BrowseUser";
+ public static String EditUser = "EditUser";
+ public static String DeleteUser = "DeleteUser";
+ public static String ExportUsers = "ExportUsers";
+ public static String BrowseDmpAssociatedUser = "BrowseDmpAssociatedUser";
+
+
+ //StorageFile
+ public static String BrowseStorageFile = "BrowseStorageFile";
+ public static String EditStorageFile = "EditStorageFile";
+ public static String DeleteStorageFile = "DeleteStorageFile";
+
+ //DescriptionTemplateType
+ public static String BrowseDescriptionTemplateType = "BrowseDescriptionTemplateType";
+ public static String EditDescriptionTemplateType = "EditDescriptionTemplateType";
+ public static String DeleteDescriptionTemplateType = "DeleteDescriptionTemplateType";
+
+ //Dmp
+ public static String BrowseDmp = "BrowseDmp";
+ public static String EditDmp = "EditDmp";
+ public static String NewDmp = "NewDmp";
+ public static String DepositDmp = "DepositDmp";
+ public static String DeleteDmp = "DeleteDmp";
+ public static String CloneDmp = "CloneDmp";
+ public static String ExportDmp = "ExportDmp";
+ public static String CreateNewVersionDmp = "CreateNewVersionDmp";
+ public static String FinalizeDmp = "FinalizeDmp";
+ public static String UndoFinalizeDmp = "UndoFinalizeDmp";
+ public static String AssignDmpUsers = "AssignDmpUsers";
+ public static String InviteDmpUsers = "InviteDmpUsers";
+
+ //DmpBlueprint
+ public static String BrowseDmpBlueprint = "BrowseDmpBlueprint";
+ public static String EditDmpBlueprint = "EditDmpBlueprint";
+ public static String DeleteDmpBlueprint = "DeleteDmpBlueprint";
+ public static String CloneDmpBlueprint = "CloneDmpBlueprint";
+ public static String CreateNewVersionDmpBlueprint = "CreateNewVersionDmpBlueprint";
+ public static String ExportDmpBlueprint = "ExportDmpBlueprint";
+ public static String ImportDmpBlueprint = "ImportDmpBlueprint";
+
+ //DmpDescriptionTemplate
+ public static String BrowseDmpDescriptionTemplate = "BrowseDmpDescriptionTemplate";
+ public static String EditDmpDescriptionTemplate = "EditDmpDescriptionTemplate";
+ public static String DeleteDmpDescriptionTemplate = "DeleteDmpDescriptionTemplate";
+
+ //DmpUser
+ public static String BrowseDmpUser = "BrowseDmpUser";
+ public static String EditDmpUser = "EditDmpUser";
+ public static String DeleteDmpUser = "DeleteDmpUser";
+
+ //Description
+ public static String BrowseDescription = "BrowseDescription";
+ public static String EditDescription = "EditDescription";
+ public static String FinalizeDescription = "FinalizeDescription";
+ public static String DeleteDescription = "DeleteDescription";
+ public static String CloneDescription = "CloneDescription";
+
+ //DescriptionTag
+ public static String BrowseDescriptionTag = "BrowseDescriptionTag";
+ public static String EditDescriptionTag = "EditDescriptionTag";
+ public static String DeleteDescriptionTag = "DeleteDescriptionTag";
+
+ //DescriptionTemplateType
+ public static String BrowseEntityDoi = "BrowseEntityDoi";
+ public static String EditEntityDoi = "EditEntityDoi";
+ public static String DeleteEntityDoi = "DeleteEntityDoi";
+
+ //UserSettings
+ public static String BrowseUserSettings = "BrowseUserSettings";
+ public static String EditUserSettings = "EditUserSettings";
+ public static String DeleteUserSettings = "DeleteUserSettings";
+
+
+
+ //Reference
+ public static String BrowseReference = "BrowseReference";
+ public static String EditReference = "EditReference";
+ public static String DeleteReference = "DeleteReference";
+
+ //Tag
+ public static String BrowseTag = "BrowseTag";
+ public static String EditTag = "EditTag";
+ public static String DeleteTag = "DeleteTag";
+
+ //DmpReference
+ public static String BrowseDmpReference = "BrowseDmpReference";
+ public static String EditDmpReference = "EditDmpReference";
+ public static String DeleteDmpReference = "DeleteDmpReference";
+
+ //DescriptionReference
+ public static String BrowseDescriptionReference = "BrowseDescriptionReference";
+ public static String EditDescriptionReference = "EditDescriptionReference";
+ public static String DeleteDescriptionReference = "DeleteDescriptionReference";
+
+ //SupportiveMaterial
+ public static String BrowseSupportiveMaterial = "BrowseSupportiveMaterial";
+ public static String EditSupportiveMaterial= "EditSupportiveMaterial";
+ public static String DeleteSupportiveMaterial = "DeleteSupportiveMaterial";
+
+ //ReferenceType
+ public static String BrowseReferenceType = "BrowseReferenceType";
+ public static String EditReferenceType= "EditReferenceType";
+ public static String DeleteReferenceType = "DeleteReferenceType";
+
+ //Tenant
+ public static String BrowseTenant = "BrowseTenant";
+ public static String EditTenant= "EditTenant";
+ public static String DeleteTenant = "DeleteTenant";
+ public static String AllowNoTenant = "AllowNoTenant";
+
+ //TenantConfiguration
+ public static String BrowseTenantConfiguration = "BrowseTenantConfiguration";
+ public static String EditTenantConfiguration = "EditTenantConfiguration";
+ public static String DeleteTenantConfiguration = "DeleteTenantConfiguration";
+
+ //TenantUser
+ public static String BrowseTenantUser = "BrowseTenantUser";
+ public static String EditTenantUser = "EditTenantUser";
+ public static String DeleteTenantUser = "DeleteTenantUser";
+
+ //Prefilling
+ public static String BrowsePrefilling = "BrowsePrefilling";
+
+
+ //Lock
+ public static String BrowseLock = "BrowseLock";
+ public static String EditLock = "EditLock";
+ public static String DeleteLock = "DeleteLock";
+
+ //ContactSupport
+ public static String SendContactSupport = "SendContactSupport";
+
+ //ActionConfirmation
+ public static String BrowseActionConfirmation = "BrowseActionConfirmation";
+ public static String EditActionConfirmation = "EditActionConfirmation";
+ public static String DeleteActionConfirmation = "DeleteActionConfirmation";
+
+ //PrefillingSource
+ public static String BrowsePrefillingSource = "BrowsePrefillingSource";
+ public static String EditPrefillingSource= "EditPrefillingSource";
+ public static String DeletePrefillingSource = "DeletePrefillingSource";
+
+
+ // UI Pages
+ public static String ViewDescriptionTemplateTypePage = "ViewDescriptionTemplateTypePage";
+ public static String ViewMaintenancePage = "ViewMaintenancePage";
+ public static String ViewNotificationPage = "ViewNotificationPage";
+ public static String ViewNotificationTemplatePage = "ViewNotificationTemplatePage";
+ public static String ViewSupportiveMaterialPage = "ViewSupportiveMaterialPage";
+ public static String ViewLanguagePage = "ViewLanguagePage";
+ public static String ViewUserPage = "ViewUserPage";
+ public static String ViewTenantPage = "ViewTenantPage";
+ public static String ViewPrefillingSourcePage = "ViewPrefillingSourcePage";
+ public static String ViewReferenceTypePage = "ViewReferenceTypePage";
+ public static String ViewReferencePage = "ViewReferencePage";
+ public static String ViewEntityLockPage = "ViewEntityLockPage";
+ public static String ViewDescriptionTemplatePage = "ViewDescriptionTemplatePage";
+ public static String ViewDmpBlueprintPage = "ViewDmpBlueprintPage";
+ public static String ViewPublicDescriptionPage = "ViewPublicDescriptionPage";
+ public static String ViewPublicDmpPage = "ViewPublicDmpPage";
+ public static String ViewMyDescriptionPage = "ViewMyDescriptionPage";
+ public static String ViewMyDmpPage = "ViewMyDmpPage";
+ public static String ViewHomePage = "ViewHomePage";
+ public static String ViewMineInAppNotificationPage = "ViewMineInAppNotificationPage";
+ public static String ViewTenantConfigurationPage = "ViewTenantConfigurationPage";
+
+}
diff --git a/backend/core/src/main/java/org/opencdmp/authorization/PermissionNameProvider.java b/backend/core/src/main/java/org/opencdmp/authorization/PermissionNameProvider.java
new file mode 100644
index 000000000..0e84f5234
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/authorization/PermissionNameProvider.java
@@ -0,0 +1,40 @@
+package org.opencdmp.authorization;
+
+import org.opencdmp.convention.ConventionService;
+import org.opencdmp.service.deposit.DepositServiceImpl;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.config.ConfigurableBeanFactory;
+import org.springframework.context.annotation.Scope;
+import org.springframework.stereotype.Service;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.List;
+
+@Service
+@Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON)
+public class PermissionNameProvider {
+ private static final Logger logger = LoggerFactory.getLogger(PermissionNameProvider.class);
+ private final List permissions;
+
+ public PermissionNameProvider(ConventionService conventionService) {
+ this.permissions = new ArrayList<>();
+ Class clazz = Permission.class;
+ for (Field f : clazz.getDeclaredFields()) {
+ if (Modifier.isStatic(f.getModifiers())) {
+ try {
+ Object value = f.get(null);
+ if (value != null && !conventionService.isNullOrEmpty((String)value)) this.permissions.add((String)value);
+ } catch (Exception e) {
+ logger.error("Can not load permission " + f.getName() + " " + e.getMessage());
+ }
+ }
+ }
+ }
+
+ public List getPermissions() {
+ return permissions;
+ }
+}
diff --git a/backend/core/src/main/java/org/opencdmp/authorization/authorizationcontentresolver/AffiliationCacheOptions.java b/backend/core/src/main/java/org/opencdmp/authorization/authorizationcontentresolver/AffiliationCacheOptions.java
new file mode 100644
index 000000000..9bde2a0e2
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/authorization/authorizationcontentresolver/AffiliationCacheOptions.java
@@ -0,0 +1,10 @@
+package org.opencdmp.authorization.authorizationcontentresolver;
+
+import gr.cite.tools.cache.CacheOptions;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@ConfigurationProperties(prefix = "cache.affiliation")
+public class AffiliationCacheOptions extends CacheOptions {
+}
diff --git a/backend/core/src/main/java/org/opencdmp/authorization/authorizationcontentresolver/AffiliationCacheService.java b/backend/core/src/main/java/org/opencdmp/authorization/authorizationcontentresolver/AffiliationCacheService.java
new file mode 100644
index 000000000..5870f1e87
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/authorization/authorizationcontentresolver/AffiliationCacheService.java
@@ -0,0 +1,108 @@
+package org.opencdmp.authorization.authorizationcontentresolver;
+
+import org.opencdmp.authorization.AffiliatedResource;
+import org.opencdmp.convention.ConventionService;
+import gr.cite.tools.cache.CacheService;
+import gr.cite.tools.exception.MyApplicationException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.UUID;
+
+@Service
+public class AffiliationCacheService extends CacheService {
+
+ public static class AffiliationCacheValue {
+
+ public AffiliationCacheValue() {
+ }
+
+ public AffiliationCacheValue(UUID tenantId, UUID userId, UUID entityId, String entityType, AffiliatedResource affiliatedResource) {
+ this.userId = userId;
+ this.tenantId = tenantId;
+ this.entityId = entityId;
+ this.entityType = entityType;
+ this.affiliatedResource = affiliatedResource;
+ }
+
+ private UUID userId;
+ private UUID tenantId;
+ private UUID entityId;
+ private String entityType;
+ private AffiliatedResource affiliatedResource;
+
+ public UUID getUserId() {
+ return userId;
+ }
+
+ public void setUserId(UUID userId) {
+ this.userId = userId;
+ }
+
+ public UUID getTenantId() {
+ return tenantId;
+ }
+
+ public void setTenantId(UUID tenantId) {
+ this.tenantId = tenantId;
+ }
+
+ public UUID getEntityId() {
+ return entityId;
+ }
+
+ public void setEntityId(UUID entityId) {
+ this.entityId = entityId;
+ }
+
+ public String getEntityType() {
+ return entityType;
+ }
+
+ public void setEntityType(String entityType) {
+ this.entityType = entityType;
+ }
+
+ public AffiliatedResource getAffiliatedResource() {
+ return affiliatedResource;
+ }
+
+ public void setAffiliatedResource(AffiliatedResource affiliatedResource) {
+ this.affiliatedResource = affiliatedResource;
+ }
+ }
+
+ private final ConventionService conventionService;
+ @Autowired
+ public AffiliationCacheService(AffiliationCacheOptions options, ConventionService conventionService) {
+ super(options);
+ this.conventionService = conventionService;
+ }
+
+ @Override
+ protected Class valueClass() {
+ return AffiliationCacheValue.class;
+ }
+
+ @Override
+ public String keyOf(AffiliationCacheValue value) {
+ return this.buildKey(value.getTenantId(), value.getUserId(), value.getEntityId(), value.getEntityType());
+ }
+
+
+ public String buildKey(UUID tenantId, UUID userId, UUID entityId, String entityType) {
+ if (userId == null) throw new IllegalArgumentException("userId id is required");
+ if (entityId == null) throw new IllegalArgumentException("entityId id is required");
+ if (this.conventionService.isNullOrEmpty(entityType)) throw new IllegalArgumentException("entityType id is required");
+
+ HashMap keyParts = new HashMap<>();
+ keyParts.put("$user$", userId.toString().replace("-", "").toLowerCase(Locale.ROOT));
+ keyParts.put("$tenant$", tenantId == null ? "" : userId.toString().replace("-", "").toLowerCase(Locale.ROOT));
+ keyParts.put("$entity$", entityId.toString().replace("-", "").toLowerCase(Locale.ROOT));
+ keyParts.put("$type$", entityType);
+ return this.generateKey(keyParts);
+ }
+}
diff --git a/backend/core/src/main/java/org/opencdmp/authorization/authorizationcontentresolver/AuthorizationContentResolver.java b/backend/core/src/main/java/org/opencdmp/authorization/authorizationcontentresolver/AuthorizationContentResolver.java
new file mode 100644
index 000000000..a8793f40a
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/authorization/authorizationcontentresolver/AuthorizationContentResolver.java
@@ -0,0 +1,23 @@
+package org.opencdmp.authorization.authorizationcontentresolver;
+
+import org.opencdmp.authorization.AffiliatedResource;
+
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+public interface AuthorizationContentResolver {
+ List getPermissionNames();
+
+ AffiliatedResource dmpAffiliation(UUID id);
+
+ Map dmpsAffiliation(List ids);
+
+ AffiliatedResource descriptionAffiliation(UUID id);
+
+ Map descriptionsAffiliation(List ids);
+
+ AffiliatedResource descriptionsAffiliationBySection(UUID dmpId, UUID sectionId);
+
+ Map descriptionsAffiliationBySections(UUID dmpId, List sectionIds);
+}
diff --git a/backend/core/src/main/java/org/opencdmp/authorization/authorizationcontentresolver/AuthorizationContentResolverImpl.java b/backend/core/src/main/java/org/opencdmp/authorization/authorizationcontentresolver/AuthorizationContentResolverImpl.java
new file mode 100644
index 000000000..7f28686f9
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/authorization/authorizationcontentresolver/AuthorizationContentResolverImpl.java
@@ -0,0 +1,174 @@
+package org.opencdmp.authorization.authorizationcontentresolver;
+
+import org.opencdmp.authorization.AffiliatedResource;
+import org.opencdmp.authorization.PermissionNameProvider;
+import org.opencdmp.commons.enums.IsActive;
+import org.opencdmp.commons.scope.tenant.TenantScope;
+import org.opencdmp.commons.scope.user.UserScope;
+import org.opencdmp.data.DescriptionEntity;
+import org.opencdmp.data.DmpDescriptionTemplateEntity;
+import org.opencdmp.data.DmpEntity;
+import org.opencdmp.data.DmpUserEntity;
+import org.opencdmp.model.Description;
+import org.opencdmp.model.DmpDescriptionTemplate;
+import org.opencdmp.model.DmpUser;
+import org.opencdmp.query.DescriptionQuery;
+import org.opencdmp.query.DmpDescriptionTemplateQuery;
+import org.opencdmp.query.DmpUserQuery;
+import gr.cite.tools.data.query.QueryFactory;
+import gr.cite.tools.fieldset.BaseFieldSet;
+import org.springframework.stereotype.Service;
+import org.springframework.web.context.annotation.RequestScope;
+
+import javax.management.InvalidApplicationException;
+import java.util.*;
+import java.util.stream.Collectors;
+
+@Service
+@RequestScope
+public class AuthorizationContentResolverImpl implements AuthorizationContentResolver {
+ private final QueryFactory queryFactory;
+ private final UserScope userScope;
+ private final TenantScope tenantScope;
+ private final AffiliationCacheService affiliationCacheService;
+ private final PermissionNameProvider permissionNameProvider;
+ public AuthorizationContentResolverImpl(QueryFactory queryFactory, UserScope userScope, TenantScope tenantScope, AffiliationCacheService affiliationCacheService, PermissionNameProvider permissionNameProvider) {
+ this.queryFactory = queryFactory;
+ this.userScope = userScope;
+ this.tenantScope = tenantScope;
+ this.affiliationCacheService = affiliationCacheService;
+ this.permissionNameProvider = permissionNameProvider;
+ }
+
+ @Override
+ public List getPermissionNames() {
+ return permissionNameProvider.getPermissions();
+ }
+
+ @Override
+ public AffiliatedResource dmpAffiliation(UUID id) {
+ return this.dmpsAffiliation(List.of(id)).getOrDefault(id, new AffiliatedResource());
+ }
+ @Override
+ public Map dmpsAffiliation(List ids){
+ UUID userId = this.userScope.getUserIdSafe();
+ Map affiliatedResources = new HashMap<>();
+ for (UUID id : ids){
+ affiliatedResources.put(id, new AffiliatedResource());
+ }
+ if (userId == null || !userScope.isSet()) return affiliatedResources;
+
+ List idsToResolve = this.getAffiliatedFromCache(ids, userId, affiliatedResources, DmpEntity.class.getSimpleName());
+ if (idsToResolve.isEmpty()) return affiliatedResources;
+
+ List dmpUsers = this.queryFactory.query(DmpUserQuery.class).dmpIds(ids).sectionIsEmpty(true).userIds(userId).isActives(IsActive.Active).collectAs(new BaseFieldSet().ensure(DmpUser._role).ensure(DmpUser._dmp));
+
+ for (DmpUserEntity dmpUser : dmpUsers){
+ affiliatedResources.get(dmpUser.getDmpId()).getDmpUserRoles().add(dmpUser.getRole());
+ }
+
+ this.ensureAffiliatedInCache(idsToResolve, userId, affiliatedResources, DmpEntity.class.getSimpleName());
+ return affiliatedResources;
+ }
+
+ @Override
+ public AffiliatedResource descriptionAffiliation(UUID id) {
+ return this.descriptionsAffiliation(List.of(id)).getOrDefault(id, new AffiliatedResource());
+ }
+ @Override
+ public Map descriptionsAffiliation(List ids){
+ UUID userId = this.userScope.getUserIdSafe();
+ Map affiliatedResources = new HashMap<>();
+ for (UUID id : ids){
+ affiliatedResources.put(id, new AffiliatedResource());
+ }
+ if (userId == null || !userScope.isSet()) return affiliatedResources;
+
+ List idsToResolve = this.getAffiliatedFromCache(ids, userId, affiliatedResources, DescriptionEntity.class.getSimpleName());
+ if (idsToResolve.isEmpty()) return affiliatedResources;
+
+ List descriptionEntities = this.queryFactory.query(DescriptionQuery.class).ids(ids).collectAs(new BaseFieldSet().ensure(Description._id).ensure(Description._dmpDescriptionTemplate).ensure(Description._dmp));
+ List dmpDescriptionTemplateEntities = this.queryFactory.query(DmpDescriptionTemplateQuery.class).ids(descriptionEntities.stream().map(DescriptionEntity::getDmpDescriptionTemplateId).distinct().toList()).collectAs(new BaseFieldSet().ensure(DmpDescriptionTemplate._id).ensure(DmpDescriptionTemplate._sectionId));
+ Map dmpDescriptionTemplateEntityMap = dmpDescriptionTemplateEntities == null ? new HashMap<>() : dmpDescriptionTemplateEntities.stream().collect(Collectors.toMap(DmpDescriptionTemplateEntity::getId, x-> x));
+
+ List dmpUsers = this.queryFactory.query(DmpUserQuery.class).descriptionIds(ids).userIds(userId).isActives(IsActive.Active).collectAs(new BaseFieldSet().ensure(DmpUser._role).ensure(DmpUser._sectionId).ensure(DmpUser._dmp));
+ Map> dmpUsersMap = dmpUsers.stream().collect(Collectors.groupingBy(DmpUserEntity::getDmpId));
+
+ for (DescriptionEntity description : descriptionEntities){
+ List dmpDescriptionUsers = dmpUsersMap.getOrDefault(description.getDmpId(), new ArrayList<>());
+ for (DmpUserEntity dmpUser : dmpDescriptionUsers) {
+ if (dmpUser.getSectionId() == null) affiliatedResources.get(description.getId()).getDmpUserRoles().add(dmpUser.getRole());
+ else {
+ DmpDescriptionTemplateEntity dmpDescriptionTemplateEntity = dmpDescriptionTemplateEntityMap.getOrDefault(description.getDmpDescriptionTemplateId(), null);
+ if (dmpDescriptionTemplateEntity != null && dmpUser.getSectionId().equals(dmpDescriptionTemplateEntity.getSectionId())){
+ affiliatedResources.get(description.getId()).getDmpUserRoles().add(dmpUser.getRole());
+ }
+ }
+ }
+ }
+
+ this.ensureAffiliatedInCache(idsToResolve, userId, affiliatedResources, DescriptionEntity.class.getSimpleName());
+ return affiliatedResources;
+ }
+
+ @Override
+ public AffiliatedResource descriptionsAffiliationBySection(UUID dmpId, UUID sectionId){
+ return this.descriptionsAffiliationBySections(dmpId, List.of(sectionId)).getOrDefault(sectionId, new AffiliatedResource());
+ }
+
+ @Override
+ public Map descriptionsAffiliationBySections(UUID dmpId, List sectionIds){
+ UUID userId = this.userScope.getUserIdSafe();
+ Map affiliatedResources = new HashMap<>();
+ for (UUID id : sectionIds){
+ affiliatedResources.put(id, new AffiliatedResource());
+ }
+ if (userId == null || !userScope.isSet()) return affiliatedResources;
+
+ List dmpUsers = this.queryFactory.query(DmpUserQuery.class).dmpIds(dmpId).userIds(userId).isActives(IsActive.Active).collectAs(new BaseFieldSet().ensure(DmpUser._role).ensure(DmpUser._sectionId).ensure(DmpUser._dmp));
+
+ for (UUID sectionId : sectionIds.stream().distinct().toList()){
+ List dmpSectionUsers = dmpUsers.stream().filter(x-> x.getSectionId() == null || x.getSectionId().equals(sectionId)).toList();
+ for (DmpUserEntity dmpUser : dmpSectionUsers) {
+ if (dmpUser.getSectionId() == null) affiliatedResources.get(sectionId).getDmpUserRoles().add(dmpUser.getRole());
+ else {
+ if (dmpUser.getSectionId().equals(sectionId)){
+ affiliatedResources.get(sectionId).getDmpUserRoles().add(dmpUser.getRole());
+ }
+ }
+ }
+ }
+
+ return affiliatedResources;
+ }
+
+ private List getAffiliatedFromCache(List ids, UUID userId, Map affiliatedResources, String entityType) {
+ List idsToResolve = new ArrayList<>();
+ for (UUID id : ids){
+ AffiliationCacheService.AffiliationCacheValue cacheValue = null;
+ try {
+ cacheValue = this.affiliationCacheService.lookup(this.affiliationCacheService.buildKey(this.tenantScope.isSet() ? this.tenantScope.getTenant(): null, userId, id, entityType));
+ } catch (InvalidApplicationException e) {
+ throw new RuntimeException(e);
+ }
+ if (cacheValue != null) affiliatedResources.put(id, cacheValue.getAffiliatedResource());
+ else idsToResolve.add(id);
+ }
+ return idsToResolve;
+ }
+
+ private void ensureAffiliatedInCache(List idsToResolve, UUID userId, Map affiliatedResources, String entityType) {
+ for (UUID id : idsToResolve){
+ AffiliatedResource affiliatedResource = affiliatedResources.getOrDefault(id, null);
+ if (affiliatedResource != null) {
+ AffiliationCacheService.AffiliationCacheValue cacheValue = null;
+ try {
+ cacheValue = new AffiliationCacheService.AffiliationCacheValue(this.tenantScope.isSet() ? this.tenantScope.getTenant(): null, userId, id, entityType, affiliatedResource);
+ } catch (InvalidApplicationException e) {
+ throw new RuntimeException(e);
+ }
+ this.affiliationCacheService.put(cacheValue);
+ }
+ }
+ }
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/JsonHandlingService.java b/backend/core/src/main/java/org/opencdmp/commons/JsonHandlingService.java
new file mode 100644
index 000000000..38c92f799
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/JsonHandlingService.java
@@ -0,0 +1,56 @@
+package org.opencdmp.commons;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.ObjectReader;
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
+import org.springframework.beans.factory.config.ConfigurableBeanFactory;
+import org.springframework.context.annotation.Scope;
+import org.springframework.stereotype.Component;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@Component
+@Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON)
+public class JsonHandlingService {
+ private final ObjectMapper objectMapper;
+
+ public JsonHandlingService() {
+ this.objectMapper = new ObjectMapper();
+ objectMapper.registerModule(new JavaTimeModule());
+ }
+
+ public String toJson(Object item) throws JsonProcessingException {
+ if (item == null) return null;
+ return objectMapper.writeValueAsString(item);
+ }
+
+ public String toJsonSafe(Object item) {
+ if (item == null) return null;
+ try {
+ return objectMapper.writeValueAsString(item);
+ } catch (Exception ex) {
+ return null;
+ }
+ }
+
+ public T fromJson(Class type, String json) throws JsonProcessingException {
+ if (json == null) return null;
+ return objectMapper.readValue(json, type);
+ }
+
+ public HashMap mapFromJson(String json) throws JsonProcessingException {
+ ObjectReader reader = objectMapper.readerFor(Map.class);
+ return reader.readValue(json);
+ }
+
+ public T fromJsonSafe(Class type, String json) {
+ if (json == null) return null;
+ try {
+ return objectMapper.readValue(json, type);
+ } catch (Exception ex) {
+ return null;
+ }
+ }
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/XmlHandlingService.java b/backend/core/src/main/java/org/opencdmp/commons/XmlHandlingService.java
new file mode 100644
index 000000000..d5c00a32b
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/XmlHandlingService.java
@@ -0,0 +1,103 @@
+package org.opencdmp.commons;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import jakarta.xml.bind.JAXBContext;
+import jakarta.xml.bind.JAXBException;
+import jakarta.xml.bind.Marshaller;
+import jakarta.xml.bind.Unmarshaller;
+import org.springframework.beans.factory.config.ConfigurableBeanFactory;
+import org.springframework.context.annotation.Scope;
+import org.springframework.stereotype.Component;
+import org.w3c.dom.Document;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+import javax.management.InvalidApplicationException;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.*;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import java.io.IOException;
+import java.io.StringReader;
+import java.io.StringWriter;
+
+@Component
+@Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON)
+public class XmlHandlingService {
+
+ public String generateXml(Document doc) throws TransformerException {
+ TransformerFactory tFact = TransformerFactory.newInstance();
+ Transformer trans = tFact.newTransformer();
+ StringWriter writer = new StringWriter();
+ StreamResult result = new StreamResult(writer);
+ DOMSource source = new DOMSource(doc);
+ trans.setOutputProperty(OutputKeys.INDENT, "yes");
+ trans.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
+ trans.transform(source, result);
+ return writer.toString();
+ }
+
+ public String toXml(Object item) throws JAXBException {
+
+
+ JAXBContext context = JAXBContext.newInstance(item.getClass());
+ Marshaller marshaller = context.createMarshaller();
+ StringWriter out = new StringWriter();
+ marshaller.marshal(item, out);
+ return out.toString();
+ }
+
+ public String toXmlSafe(Object item) {
+ if (item == null) return null;
+ try {
+ return this.toXml(item);
+ } catch (Exception ex) {
+ return null;
+ }
+ }
+
+ public T fromXml(Class type, String xmlString) throws JAXBException, InstantiationException, IllegalAccessException, ParserConfigurationException, IOException, SAXException {
+ JAXBContext jaxbContext = JAXBContext.newInstance(type);
+ Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
+
+ return (T) jaxbUnmarshaller.unmarshal(new StringReader(xmlString));
+ }
+
+ public T fromXmlSafe(Class type, String xmlString) {
+ if (xmlString == null) return null;
+ try {
+ return this.fromXml(type, xmlString);
+ } catch (Exception ex) {
+ return null;
+ }
+ }
+
+// public > T xmlSerializableFromXml(Class type, String xmlString) throws JAXBException, InstantiationException, IllegalAccessException, ParserConfigurationException, IOException, SAXException {
+// T object = type.newInstance();
+// return (T) object.fromXml(this.getDocument(xmlString).getDocumentElement());
+// }
+//
+// public > T xmlSerializableFromXmlSafe(Class type, String xmlString) {
+// if (xmlString == null) return null;
+// try {
+// return this.xmlSerializableFromXml(type, xmlString);
+// } catch (Exception ex) {
+// return null;
+// }
+// }
+
+ public Document getDocument(String xml) throws ParserConfigurationException, IOException, SAXException {
+ DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
+ DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
+ InputSource inputStream = new InputSource(new StringReader(xml));
+ return docBuilder.parse(inputStream);
+ }
+
+ public Document getDocument() throws ParserConfigurationException {
+ DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
+ DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
+ return docBuilder.newDocument();
+ }
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/enums/ActionConfirmationStatus.java b/backend/core/src/main/java/org/opencdmp/commons/enums/ActionConfirmationStatus.java
new file mode 100644
index 000000000..3268aba00
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/enums/ActionConfirmationStatus.java
@@ -0,0 +1,32 @@
+package org.opencdmp.commons.enums;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.opencdmp.data.converters.enums.DatabaseEnum;
+
+import java.util.Map;
+
+public enum ActionConfirmationStatus implements DatabaseEnum {
+
+ Requested((short) 0),
+ Accepted((short) 1);
+
+ private final Short value;
+
+ ActionConfirmationStatus(Short value) {
+ this.value = value;
+ }
+
+ @Override
+ @JsonValue
+ public Short getValue() {
+ return value;
+ }
+
+ private static final Map map = EnumUtils.getEnumValueMap(ActionConfirmationStatus.class);
+
+ public static ActionConfirmationStatus of(Short i) {
+ return map.get(i);
+ }
+
+
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/enums/ActionConfirmationType.java b/backend/core/src/main/java/org/opencdmp/commons/enums/ActionConfirmationType.java
new file mode 100644
index 000000000..15eed455e
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/enums/ActionConfirmationType.java
@@ -0,0 +1,33 @@
+package org.opencdmp.commons.enums;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.opencdmp.data.converters.enums.DatabaseEnum;
+
+import java.util.Map;
+
+public enum ActionConfirmationType implements DatabaseEnum {
+
+ MergeAccount((short) 0),
+ RemoveCredential((short) 1),
+ DmpInvitation((short) 2);
+
+ private final Short value;
+
+ ActionConfirmationType(Short value) {
+ this.value = value;
+ }
+
+ @Override
+ @JsonValue
+ public Short getValue() {
+ return value;
+ }
+
+ private static final Map map = EnumUtils.getEnumValueMap(ActionConfirmationType.class);
+
+ public static ActionConfirmationType of(Short i) {
+ return map.get(i);
+ }
+
+
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/enums/ContactInfoType.java b/backend/core/src/main/java/org/opencdmp/commons/enums/ContactInfoType.java
new file mode 100644
index 000000000..93e4685a0
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/enums/ContactInfoType.java
@@ -0,0 +1,30 @@
+package org.opencdmp.commons.enums;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.opencdmp.data.converters.enums.DatabaseEnum;
+
+import java.util.Map;
+
+public enum ContactInfoType implements DatabaseEnum {
+
+ Email((short) 0);
+
+ private final Short value;
+
+ ContactInfoType(Short value) {
+ this.value = value;
+ }
+
+ @Override
+ @JsonValue
+ public Short getValue() {
+ return value;
+ }
+
+ private static final Map map = EnumUtils.getEnumValueMap(ContactInfoType.class);
+
+ public static ContactInfoType of(Short i) {
+ return map.get(i);
+ }
+
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/enums/DescriptionStatus.java b/backend/core/src/main/java/org/opencdmp/commons/enums/DescriptionStatus.java
new file mode 100644
index 000000000..fa07e7708
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/enums/DescriptionStatus.java
@@ -0,0 +1,31 @@
+package org.opencdmp.commons.enums;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.opencdmp.data.converters.enums.DatabaseEnum;
+
+import java.util.Map;
+
+public enum DescriptionStatus implements DatabaseEnum {
+
+ Draft((short) 0),
+ Finalized((short) 1),
+ Canceled((short) 2);
+
+ private final Short value;
+
+ DescriptionStatus(Short value) {
+ this.value = value;
+ }
+
+ @JsonValue
+ public Short getValue() {
+ return value;
+ }
+
+ private static final Map map = EnumUtils.getEnumValueMap(DescriptionStatus.class);
+
+ public static DescriptionStatus of(Short i) {
+ return map.get(i);
+ }
+
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/enums/DescriptionTemplateStatus.java b/backend/core/src/main/java/org/opencdmp/commons/enums/DescriptionTemplateStatus.java
new file mode 100644
index 000000000..c7dc5b8d8
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/enums/DescriptionTemplateStatus.java
@@ -0,0 +1,30 @@
+package org.opencdmp.commons.enums;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.opencdmp.data.converters.enums.DatabaseEnum;
+
+import java.util.Map;
+
+public enum DescriptionTemplateStatus implements DatabaseEnum {
+
+ Draft((short) 0),
+ Finalized((short) 1);
+
+ private final Short value;
+
+ DescriptionTemplateStatus(Short value) {
+ this.value = value;
+ }
+
+ @JsonValue
+ public Short getValue() {
+ return value;
+ }
+
+ private static final Map map = EnumUtils.getEnumValueMap(DescriptionTemplateStatus.class);
+
+ public static DescriptionTemplateStatus of(Short i) {
+ return map.get(i);
+ }
+
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/enums/DescriptionTemplateTypeStatus.java b/backend/core/src/main/java/org/opencdmp/commons/enums/DescriptionTemplateTypeStatus.java
new file mode 100644
index 000000000..ceade7c51
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/enums/DescriptionTemplateTypeStatus.java
@@ -0,0 +1,30 @@
+package org.opencdmp.commons.enums;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.opencdmp.data.converters.enums.DatabaseEnum;
+
+import java.util.Map;
+
+public enum DescriptionTemplateTypeStatus implements DatabaseEnum {
+
+ Draft((short) 0),
+ Finalized((short) 1);
+
+ private final Short value;
+
+ DescriptionTemplateTypeStatus(Short value) {
+ this.value = value;
+ }
+
+ @JsonValue
+ public Short getValue() {
+ return value;
+ }
+
+ private static final Map map = EnumUtils.getEnumValueMap(DescriptionTemplateTypeStatus.class);
+
+ public static DescriptionTemplateTypeStatus of(Short i) {
+ return map.get(i);
+ }
+
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/enums/DescriptionTemplateVersionStatus.java b/backend/core/src/main/java/org/opencdmp/commons/enums/DescriptionTemplateVersionStatus.java
new file mode 100644
index 000000000..ca779106d
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/enums/DescriptionTemplateVersionStatus.java
@@ -0,0 +1,32 @@
+package org.opencdmp.commons.enums;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.opencdmp.data.converters.enums.DatabaseEnum;
+
+import java.util.Map;
+
+public enum DescriptionTemplateVersionStatus implements DatabaseEnum {
+
+ Current((short) 0),
+ Previous((short) 1),
+ NotFinalized((short) 2);
+
+ private final Short value;
+
+ DescriptionTemplateVersionStatus(Short value) {
+ this.value = value;
+ }
+
+ @Override
+ @JsonValue
+ public Short getValue() {
+ return value;
+ }
+
+ private static final Map map = EnumUtils.getEnumValueMap(DescriptionTemplateVersionStatus.class);
+
+ public static DescriptionTemplateVersionStatus of(Short i) {
+ return map.get(i);
+ }
+
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/enums/DescriptionValidationOutput.java b/backend/core/src/main/java/org/opencdmp/commons/enums/DescriptionValidationOutput.java
new file mode 100644
index 000000000..509b4dfcd
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/enums/DescriptionValidationOutput.java
@@ -0,0 +1,30 @@
+package org.opencdmp.commons.enums;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.opencdmp.data.converters.enums.DatabaseEnum;
+
+import java.util.Map;
+
+public enum DescriptionValidationOutput implements DatabaseEnum {
+
+ Valid((short) 1),
+ Invalid((short) 2);
+
+ private final Short value;
+
+ DescriptionValidationOutput(Short value) {
+ this.value = value;
+ }
+
+ @JsonValue
+ public Short getValue() {
+ return value;
+ }
+
+ private static final Map map = EnumUtils.getEnumValueMap(DescriptionValidationOutput.class);
+
+ public static DescriptionValidationOutput of(Short i) {
+ return map.get(i);
+ }
+
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/enums/DmpAccessType.java b/backend/core/src/main/java/org/opencdmp/commons/enums/DmpAccessType.java
new file mode 100644
index 000000000..9418774db
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/enums/DmpAccessType.java
@@ -0,0 +1,30 @@
+package org.opencdmp.commons.enums;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.opencdmp.data.converters.enums.DatabaseEnum;
+
+import java.util.Map;
+
+public enum DmpAccessType implements DatabaseEnum {
+
+ Public((short) 0), Restricted((short) 1);
+
+ private final Short value;
+
+ DmpAccessType(Short value) {
+ this.value = value;
+ }
+
+ @Override
+ @JsonValue
+ public Short getValue() {
+ return value;
+ }
+
+ private static final Map map = EnumUtils.getEnumValueMap(DmpAccessType.class);
+
+ public static DmpAccessType of(Short i) {
+ return map.get(i);
+ }
+
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/enums/DmpBlueprintExtraFieldDataType.java b/backend/core/src/main/java/org/opencdmp/commons/enums/DmpBlueprintExtraFieldDataType.java
new file mode 100644
index 000000000..a22be8ee5
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/enums/DmpBlueprintExtraFieldDataType.java
@@ -0,0 +1,33 @@
+package org.opencdmp.commons.enums;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.opencdmp.data.converters.enums.DatabaseEnum;
+
+import java.util.Map;
+
+public enum DmpBlueprintExtraFieldDataType implements DatabaseEnum {
+
+ Text((short) 0),
+ RichTex((short) 1),
+ Date((short) 2),
+ Number((short) 3),
+ ;
+
+ private final Short value;
+
+ DmpBlueprintExtraFieldDataType(Short value) {
+ this.value = value;
+ }
+
+ @JsonValue
+ public Short getValue() {
+ return value;
+ }
+
+ private static final Map map = EnumUtils.getEnumValueMap(DmpBlueprintExtraFieldDataType.class);
+
+ public static DmpBlueprintExtraFieldDataType of(Short i) {
+ return map.get(i);
+ }
+
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/enums/DmpBlueprintFieldCategory.java b/backend/core/src/main/java/org/opencdmp/commons/enums/DmpBlueprintFieldCategory.java
new file mode 100644
index 000000000..2db7c80b2
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/enums/DmpBlueprintFieldCategory.java
@@ -0,0 +1,35 @@
+package org.opencdmp.commons.enums;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.opencdmp.data.converters.enums.DatabaseEnum;
+
+import java.util.Map;
+
+public enum DmpBlueprintFieldCategory implements DatabaseEnum {
+ System((short) 0),
+ Extra((short) 1),
+ ReferenceType((short) 2);
+
+ public static class Names {
+ public static final String System = "system";
+ public static final String Extra = "extra";
+ public static final String ReferenceType = "referenceType";
+ }
+
+ private final Short value;
+
+ DmpBlueprintFieldCategory(Short value) {
+ this.value = value;
+ }
+
+ @JsonValue
+ public Short getValue() {
+ return value;
+ }
+
+ private static final Map map = EnumUtils.getEnumValueMap(DmpBlueprintFieldCategory.class);
+
+ public static DmpBlueprintFieldCategory of(Short i) {
+ return map.get(i);
+ }
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/enums/DmpBlueprintStatus.java b/backend/core/src/main/java/org/opencdmp/commons/enums/DmpBlueprintStatus.java
new file mode 100644
index 000000000..d82f48001
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/enums/DmpBlueprintStatus.java
@@ -0,0 +1,30 @@
+package org.opencdmp.commons.enums;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.opencdmp.data.converters.enums.DatabaseEnum;
+
+import java.util.Map;
+
+public enum DmpBlueprintStatus implements DatabaseEnum {
+
+ Draft((short) 0),
+ Finalized((short) 1);
+
+ private final Short value;
+
+ DmpBlueprintStatus(Short value) {
+ this.value = value;
+ }
+
+ @JsonValue
+ public Short getValue() {
+ return value;
+ }
+
+ private static final Map map = EnumUtils.getEnumValueMap(DmpBlueprintStatus.class);
+
+ public static DmpBlueprintStatus of(Short i) {
+ return map.get(i);
+ }
+
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/enums/DmpBlueprintSystemFieldType.java b/backend/core/src/main/java/org/opencdmp/commons/enums/DmpBlueprintSystemFieldType.java
new file mode 100644
index 000000000..a04509453
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/enums/DmpBlueprintSystemFieldType.java
@@ -0,0 +1,32 @@
+package org.opencdmp.commons.enums;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.opencdmp.data.converters.enums.DatabaseEnum;
+
+import java.util.Map;
+
+public enum DmpBlueprintSystemFieldType implements DatabaseEnum {
+
+ Title((short)0),
+ Description((short)1),
+ Language((short)2),
+ Contact((short)3),
+ AccessRights((short)4),
+ User((short)5);
+ private final Short value;
+
+ DmpBlueprintSystemFieldType(Short value) {
+ this.value = value;
+ }
+
+ @JsonValue
+ public Short getValue() {
+ return value;
+ }
+
+ private static final Map map = EnumUtils.getEnumValueMap(DmpBlueprintSystemFieldType.class);
+
+ public static DmpBlueprintSystemFieldType of(Short i) {
+ return map.get(i);
+ }
+}
\ No newline at end of file
diff --git a/backend/core/src/main/java/org/opencdmp/commons/enums/DmpBlueprintVersionStatus.java b/backend/core/src/main/java/org/opencdmp/commons/enums/DmpBlueprintVersionStatus.java
new file mode 100644
index 000000000..80fa6c976
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/enums/DmpBlueprintVersionStatus.java
@@ -0,0 +1,32 @@
+package org.opencdmp.commons.enums;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.opencdmp.data.converters.enums.DatabaseEnum;
+
+import java.util.Map;
+
+public enum DmpBlueprintVersionStatus implements DatabaseEnum {
+
+ 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 map = EnumUtils.getEnumValueMap(DmpBlueprintVersionStatus.class);
+
+ public static DmpBlueprintVersionStatus of(Short i) {
+ return map.get(i);
+ }
+
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/enums/DmpStatus.java b/backend/core/src/main/java/org/opencdmp/commons/enums/DmpStatus.java
new file mode 100644
index 000000000..0cb33f250
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/enums/DmpStatus.java
@@ -0,0 +1,31 @@
+package org.opencdmp.commons.enums;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.opencdmp.data.converters.enums.DatabaseEnum;
+
+import java.util.Map;
+
+public enum DmpStatus implements DatabaseEnum {
+
+ Draft((short) 0), Finalized((short) 1);
+
+ private final Short value;
+
+ DmpStatus(Short value) {
+ this.value = value;
+ }
+
+ @Override
+ @JsonValue
+ public Short getValue() {
+ return value;
+ }
+
+ private static final Map map = EnumUtils.getEnumValueMap(DmpStatus.class);
+
+ public static DmpStatus of(Short i) {
+ return map.get(i);
+ }
+
+
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/enums/DmpUserRole.java b/backend/core/src/main/java/org/opencdmp/commons/enums/DmpUserRole.java
new file mode 100644
index 000000000..b641e64d5
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/enums/DmpUserRole.java
@@ -0,0 +1,33 @@
+package org.opencdmp.commons.enums;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.opencdmp.data.converters.enums.DatabaseEnum;
+
+import java.util.Map;
+
+public enum DmpUserRole implements DatabaseEnum {
+
+ Owner((short) 0),
+ User((short) 1),
+ DescriptionContributor((short) 2),
+ Reviewer((short) 3);
+
+ private final Short value;
+
+ DmpUserRole(Short value) {
+ this.value = value;
+ }
+
+ @Override
+ @JsonValue
+ public Short getValue() {
+ return value;
+ }
+
+ private static final Map map = EnumUtils.getEnumValueMap(DmpUserRole.class);
+
+ public static DmpUserRole of(Short i) {
+ return map.get(i);
+ }
+
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/enums/DmpValidationOutput.java b/backend/core/src/main/java/org/opencdmp/commons/enums/DmpValidationOutput.java
new file mode 100644
index 000000000..2245df5b6
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/enums/DmpValidationOutput.java
@@ -0,0 +1,30 @@
+package org.opencdmp.commons.enums;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.opencdmp.data.converters.enums.DatabaseEnum;
+
+import java.util.Map;
+
+public enum DmpValidationOutput implements DatabaseEnum {
+
+ Valid((short) 1),
+ Invalid((short) 2);
+
+ private final Short value;
+
+ DmpValidationOutput(Short value) {
+ this.value = value;
+ }
+
+ @JsonValue
+ public Short getValue() {
+ return value;
+ }
+
+ private static final Map map = EnumUtils.getEnumValueMap(DmpValidationOutput.class);
+
+ public static DmpValidationOutput of(Short i) {
+ return map.get(i);
+ }
+
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/enums/DmpVersionStatus.java b/backend/core/src/main/java/org/opencdmp/commons/enums/DmpVersionStatus.java
new file mode 100644
index 000000000..af6601322
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/enums/DmpVersionStatus.java
@@ -0,0 +1,32 @@
+package org.opencdmp.commons.enums;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.opencdmp.data.converters.enums.DatabaseEnum;
+
+import java.util.Map;
+
+public enum DmpVersionStatus implements DatabaseEnum {
+
+ Current((short) 0),
+ Previous((short) 1),
+ NotFinalized((short) 2);
+
+ private final Short value;
+
+ DmpVersionStatus(Short value) {
+ this.value = value;
+ }
+
+ @Override
+ @JsonValue
+ public Short getValue() {
+ return value;
+ }
+
+ private static final Map map = EnumUtils.getEnumValueMap(DmpVersionStatus.class);
+
+ public static DmpVersionStatus of(Short i) {
+ return map.get(i);
+ }
+
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/enums/EntityType.java b/backend/core/src/main/java/org/opencdmp/commons/enums/EntityType.java
new file mode 100644
index 000000000..15ae70af4
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/enums/EntityType.java
@@ -0,0 +1,30 @@
+package org.opencdmp.commons.enums;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.opencdmp.data.converters.enums.DatabaseEnum;
+
+import java.util.Map;
+
+public enum EntityType implements DatabaseEnum {
+
+ DMP((short) 0);
+
+ private final Short value;
+
+ EntityType(Short value) {
+ this.value = value;
+ }
+
+ @Override
+ @JsonValue
+ public Short getValue() {
+ return value;
+ }
+
+ private static final Map map = EnumUtils.getEnumValueMap(EntityType.class);
+
+ public static EntityType of(Short i) {
+ return map.get(i);
+ }
+
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/enums/EnumUtils.java b/backend/core/src/main/java/org/opencdmp/commons/enums/EnumUtils.java
new file mode 100644
index 000000000..074e11c6c
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/enums/EnumUtils.java
@@ -0,0 +1,16 @@
+package org.opencdmp.commons.enums;
+
+import org.opencdmp.data.converters.enums.DatabaseEnum;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class EnumUtils {
+ public static & DatabaseEnum, EnumValue> Map getEnumValueMap(Class enumType){
+ HashMap map = new HashMap<>();
+ for (EnumType v : enumType.getEnumConstants()) {
+ map.put(v.getValue(), v);
+ }
+ return map;
+ }
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/enums/ExternalFetcherApiHTTPMethodType.java b/backend/core/src/main/java/org/opencdmp/commons/enums/ExternalFetcherApiHTTPMethodType.java
new file mode 100644
index 000000000..40741ed29
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/enums/ExternalFetcherApiHTTPMethodType.java
@@ -0,0 +1,30 @@
+package org.opencdmp.commons.enums;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.opencdmp.data.converters.enums.DatabaseEnum;
+import jakarta.xml.bind.annotation.XmlEnumValue;
+
+import java.util.Map;
+
+public enum ExternalFetcherApiHTTPMethodType implements DatabaseEnum {
+ @XmlEnumValue(value = "0")
+ GET((short) 0),
+ @XmlEnumValue(value = "1")
+ POST((short) 1);
+ private final Short value;
+
+ ExternalFetcherApiHTTPMethodType(Short value) {
+ this.value = value;
+ }
+
+ @JsonValue
+ public Short getValue() {
+ return value;
+ }
+
+ private static final Map map = EnumUtils.getEnumValueMap(ExternalFetcherApiHTTPMethodType.class);
+
+ public static ExternalFetcherApiHTTPMethodType of(Short i) {
+ return map.get(i);
+ }
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/enums/ExternalFetcherSourceType.java b/backend/core/src/main/java/org/opencdmp/commons/enums/ExternalFetcherSourceType.java
new file mode 100644
index 000000000..d2b27aceb
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/enums/ExternalFetcherSourceType.java
@@ -0,0 +1,35 @@
+package org.opencdmp.commons.enums;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.opencdmp.data.converters.enums.DatabaseEnum;
+import jakarta.xml.bind.annotation.XmlEnumValue;
+
+import java.util.Map;
+
+public enum ExternalFetcherSourceType implements DatabaseEnum {
+ @XmlEnumValue(value = "0")
+ API((short) 0),
+ @XmlEnumValue(value = "1")
+ STATIC((short) 1);
+ private final Short value;
+
+ public static class Names {
+ public static final String API = "api";
+ public static final String STATIC = "static";
+ }
+
+ ExternalFetcherSourceType(Short value) {
+ this.value = value;
+ }
+
+ @JsonValue
+ public Short getValue() {
+ return value;
+ }
+
+ private static final Map map = EnumUtils.getEnumValueMap(ExternalFetcherSourceType.class);
+
+ public static ExternalFetcherSourceType of(Short i) {
+ return map.get(i);
+ }
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/enums/FieldType.java b/backend/core/src/main/java/org/opencdmp/commons/enums/FieldType.java
new file mode 100644
index 000000000..9046c5e3a
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/enums/FieldType.java
@@ -0,0 +1,82 @@
+package org.opencdmp.commons.enums;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.opencdmp.data.converters.enums.DatabaseEnum;
+
+import java.util.Map;
+
+public enum FieldType implements DatabaseEnum {
+ SELECT(Names.Select),
+ BOOLEAN_DECISION(Names.BooleanDecision),
+ RADIO_BOX(Names.RadioBox),
+ INTERNAL_ENTRIES_DMPS(Names.InternalEntitiesDmps),
+ INTERNAL_ENTRIES_DESCRIPTIONS(Names.InternalEntitiesDescriptions),
+ CHECK_BOX(Names.CheckBox),
+ FREE_TEXT(Names.FreeText),
+ TEXT_AREA(Names.TextArea),
+ RICH_TEXT_AREA(Names.RichTextarea),
+ UPLOAD(Names.Upload),
+ DATE_PICKER(Names.DatePicker),
+ TAGS(Names.Tags),
+ REFERENCE_TYPES(Names.ReferenceTypes),
+ DATASET_IDENTIFIER(Names.DatasetIdentifier),
+ VALIDATION(Names.Validation);
+ private final String value;
+
+ public static class Names {
+ public static final String Select = "select";
+ public static final String BooleanDecision = "booleanDecision";
+ public static final String RadioBox = "radiobox";
+ public static final String InternalEntitiesDmps = "internalEntitiesDmps";
+ public static final String InternalEntitiesDescriptions = "internalEntitiesDescriptions";
+ public static final String CheckBox = "checkBox";
+ public static final String FreeText = "freetext";
+ public static final String TextArea = "textarea";
+ public static final String RichTextarea = "richTextarea";
+ public static final String Upload = "upload";
+ public static final String DatePicker = "datePicker";
+ public static final String Tags = "tags";
+ public static final String DatasetIdentifier = "datasetIdentifier";
+ public static final String Validation = "validation";
+ public static final String ReferenceTypes = "referenceTypes";
+ }
+
+ FieldType(String value) {
+ this.value = value;
+ }
+
+ @JsonValue
+ public String getValue() {
+ return value;
+ }
+
+ private static final Map map = EnumUtils.getEnumValueMap(FieldType.class);
+
+ public static FieldType of(String i) {
+ return map.get(i);
+ }
+
+
+ public static boolean isReferenceType(FieldType fieldType){
+ return fieldType.equals(FieldType.REFERENCE_TYPES);
+ }
+
+ public static boolean isTextType(FieldType fieldType){
+ return fieldType.equals(FieldType.FREE_TEXT) || fieldType.equals(FieldType.CHECK_BOX) || fieldType.equals(FieldType.TEXT_AREA) ||
+ fieldType.equals(FieldType.RICH_TEXT_AREA) || fieldType.equals(FieldType.UPLOAD) || fieldType.equals(FieldType.BOOLEAN_DECISION) ||
+ fieldType.equals(FieldType.RADIO_BOX);
+ }
+
+ public static boolean isTextListType(FieldType fieldType){
+ return fieldType.equals(FieldType.SELECT) || fieldType.equals(FieldType.TAGS) || fieldType.equals(FieldType.INTERNAL_ENTRIES_DMPS) ||
+ fieldType.equals(FieldType.INTERNAL_ENTRIES_DESCRIPTIONS);
+ }
+
+ public static boolean isDateType(FieldType fieldType){
+ return fieldType.equals(FieldType.DATE_PICKER);
+ }
+
+ public static boolean isExternalIdentifierType(FieldType fieldType){
+ return fieldType.equals(FieldType.VALIDATION) || fieldType.equals(FieldType.DATASET_IDENTIFIER) ;
+ }
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/enums/FieldValidationType.java b/backend/core/src/main/java/org/opencdmp/commons/enums/FieldValidationType.java
new file mode 100644
index 000000000..abc2f5302
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/enums/FieldValidationType.java
@@ -0,0 +1,33 @@
+package org.opencdmp.commons.enums;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.opencdmp.data.converters.enums.DatabaseEnum;
+
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+public enum FieldValidationType implements DatabaseEnum {
+
+ None((short) 0),
+ Required((short) 1),
+ Url((short) 2);
+
+ private final Short value;
+
+ FieldValidationType(Short value) {
+ this.value = value;
+ }
+
+ @JsonValue
+ public Short getValue() {
+ return value;
+ }
+
+ private static final Map map = EnumUtils.getEnumValueMap(FieldValidationType.class);
+
+ public static FieldValidationType of(Short i) {
+ return map.get(i);
+ }
+
+}
\ No newline at end of file
diff --git a/backend/core/src/main/java/org/opencdmp/commons/enums/IsActive.java b/backend/core/src/main/java/org/opencdmp/commons/enums/IsActive.java
new file mode 100644
index 000000000..c329cc87c
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/enums/IsActive.java
@@ -0,0 +1,30 @@
+package org.opencdmp.commons.enums;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.opencdmp.data.converters.enums.DatabaseEnum;
+
+import java.util.Map;
+
+public enum IsActive implements DatabaseEnum {
+
+ Inactive((short) 0),
+ Active((short) 1);
+
+ private final Short value;
+
+ IsActive(Short value) {
+ this.value = value;
+ }
+
+ @JsonValue
+ public Short getValue() {
+ return value;
+ }
+
+ private static final Map map = EnumUtils.getEnumValueMap(IsActive.class);
+
+ public static IsActive of(Short i) {
+ return map.get(i);
+ }
+
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/enums/LockTargetType.java b/backend/core/src/main/java/org/opencdmp/commons/enums/LockTargetType.java
new file mode 100644
index 000000000..56b27b270
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/enums/LockTargetType.java
@@ -0,0 +1,29 @@
+package org.opencdmp.commons.enums;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.opencdmp.data.converters.enums.DatabaseEnum;
+
+import java.util.Map;
+
+public enum LockTargetType implements DatabaseEnum {
+ Dmp((short) 0),
+ Description((short) 1),
+ DmpBlueprint((short) 2),
+ DescriptionTemplate((short) 3);
+ private final Short value;
+
+ LockTargetType(Short value) {
+ this.value = value;
+ }
+
+ @JsonValue
+ public Short getValue() {
+ return value;
+ }
+
+ private static final Map map = EnumUtils.getEnumValueMap(LockTargetType.class);
+
+ public static LockTargetType of(Short i) {
+ return map.get(i);
+ }
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/enums/ProviderType.java b/backend/core/src/main/java/org/opencdmp/commons/enums/ProviderType.java
new file mode 100644
index 000000000..bc6c36d32
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/enums/ProviderType.java
@@ -0,0 +1,36 @@
+package org.opencdmp.commons.enums;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.opencdmp.data.converters.enums.DatabaseEnum;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public enum ProviderType implements DatabaseEnum {
+
+ Google (1),
+ Facebook ( 2),
+ Twitter ( 3),
+ LinkedIn (4),
+ NativeLogin ( 5),
+ B2Access ( 6),
+ ORCID (7),
+ OpenAire ( 8),
+ Configurable ( 9),
+ Zenodo (10),
+ Keycloack ( 128);
+
+ private final Integer value;
+
+ ProviderType(Integer value) {
+ this.value = value;
+ }
+
+ @JsonValue
+ public Integer getValue() { return this.value; }
+
+ private static final Map map = EnumUtils.getEnumValueMap(ProviderType.class);
+ public static ProviderType of(Integer i) {
+ return map.get(i);
+ }
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/enums/RecentActivityItemType.java b/backend/core/src/main/java/org/opencdmp/commons/enums/RecentActivityItemType.java
new file mode 100644
index 000000000..e752e2c85
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/enums/RecentActivityItemType.java
@@ -0,0 +1,31 @@
+package org.opencdmp.commons.enums;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.opencdmp.data.converters.enums.DatabaseEnum;
+
+import java.util.Map;
+
+public enum RecentActivityItemType implements DatabaseEnum {
+
+ Dmp((short) 0),
+ Description((short) 1);
+
+ private final Short value;
+
+ RecentActivityItemType(Short value) {
+ this.value = value;
+ }
+
+ @Override
+ @JsonValue
+ public Short getValue() {
+ return value;
+ }
+
+ private static final Map map = EnumUtils.getEnumValueMap(RecentActivityItemType.class);
+
+ public static RecentActivityItemType of(Short i) {
+ return map.get(i);
+ }
+
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/enums/RecentActivityOrder.java b/backend/core/src/main/java/org/opencdmp/commons/enums/RecentActivityOrder.java
new file mode 100644
index 000000000..f115e9efe
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/enums/RecentActivityOrder.java
@@ -0,0 +1,31 @@
+package org.opencdmp.commons.enums;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.opencdmp.data.converters.enums.DatabaseEnum;
+
+import java.util.Map;
+
+public enum RecentActivityOrder implements DatabaseEnum {
+ UpdatedAt((short) 0),
+ Label((short) 1),
+ Status((short) 2);
+
+ private final Short value;
+
+ RecentActivityOrder(Short value) {
+ this.value = value;
+ }
+
+ @Override
+ @JsonValue
+ public Short getValue() {
+ return value;
+ }
+
+ private static final Map map = EnumUtils.getEnumValueMap(RecentActivityOrder.class);
+
+ public static RecentActivityOrder of(Short i) {
+ return map.get(i);
+ }
+
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/enums/ReferenceFieldDataType.java b/backend/core/src/main/java/org/opencdmp/commons/enums/ReferenceFieldDataType.java
new file mode 100644
index 000000000..93dd9b555
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/enums/ReferenceFieldDataType.java
@@ -0,0 +1,27 @@
+package org.opencdmp.commons.enums;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.opencdmp.data.converters.enums.DatabaseEnum;
+
+import java.util.Map;
+
+public enum ReferenceFieldDataType implements DatabaseEnum {
+ Text((short) 0),
+ Date((short) 1);
+ private final Short value;
+
+ ReferenceFieldDataType(Short value) {
+ this.value = value;
+ }
+
+ @JsonValue
+ public Short getValue() {
+ return value;
+ }
+
+ private static final Map map = EnumUtils.getEnumValueMap(ReferenceFieldDataType.class);
+
+ public static ReferenceFieldDataType of(Short i) {
+ return map.get(i);
+ }
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/enums/ReferenceSourceType.java b/backend/core/src/main/java/org/opencdmp/commons/enums/ReferenceSourceType.java
new file mode 100644
index 000000000..08a34b1ec
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/enums/ReferenceSourceType.java
@@ -0,0 +1,28 @@
+package org.opencdmp.commons.enums;
+
+import org.opencdmp.data.converters.enums.DatabaseEnum;
+
+import java.util.Map;
+
+public enum ReferenceSourceType implements DatabaseEnum {
+
+ Internal((short) 0),
+ External((short) 1);
+
+ private final Short value;
+
+ ReferenceSourceType(Short value) {
+ this.value = value;
+ }
+
+ @Override
+ public Short getValue() {
+ return value;
+ }
+
+ private static final Map map = EnumUtils.getEnumValueMap(ReferenceSourceType.class);
+
+ public static ReferenceSourceType of(Short i) {
+ return map.get(i);
+ }
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/enums/StorageFilePermission.java b/backend/core/src/main/java/org/opencdmp/commons/enums/StorageFilePermission.java
new file mode 100644
index 000000000..04095a214
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/enums/StorageFilePermission.java
@@ -0,0 +1,30 @@
+package org.opencdmp.commons.enums;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.opencdmp.data.converters.enums.DatabaseEnum;
+
+import java.util.Map;
+
+public enum StorageFilePermission implements DatabaseEnum {
+
+ Read((short) 0),
+ Write((short) 1);
+
+ private final Short value;
+
+ StorageFilePermission(Short value) {
+ this.value = value;
+ }
+
+ @JsonValue
+ public Short getValue() {
+ return value;
+ }
+
+ private static final Map map = EnumUtils.getEnumValueMap(StorageFilePermission.class);
+
+ public static StorageFilePermission of(Short i) {
+ return map.get(i);
+ }
+
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/enums/StorageType.java b/backend/core/src/main/java/org/opencdmp/commons/enums/StorageType.java
new file mode 100644
index 000000000..b0644f0ea
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/enums/StorageType.java
@@ -0,0 +1,32 @@
+package org.opencdmp.commons.enums;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.opencdmp.data.converters.enums.DatabaseEnum;
+
+import java.util.Map;
+
+public enum StorageType implements DatabaseEnum {
+
+ Temp((short) 0),
+ Main((short) 1),
+ Transformer((short)2),
+ Deposit((short)3);
+
+ private final Short value;
+
+ StorageType(Short value) {
+ this.value = value;
+ }
+
+ @JsonValue
+ public Short getValue() {
+ return value;
+ }
+
+ private static final Map map = EnumUtils.getEnumValueMap(StorageType.class);
+
+ public static StorageType of(Short i) {
+ return map.get(i);
+ }
+
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/enums/SupportiveMaterialFieldType.java b/backend/core/src/main/java/org/opencdmp/commons/enums/SupportiveMaterialFieldType.java
new file mode 100644
index 000000000..0a34bc2c6
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/enums/SupportiveMaterialFieldType.java
@@ -0,0 +1,31 @@
+package org.opencdmp.commons.enums;
+
+import org.opencdmp.data.converters.enums.DatabaseEnum;
+
+import java.util.Map;
+
+public enum SupportiveMaterialFieldType implements DatabaseEnum {
+
+ Faq((short) 0),
+ About((short) 1),
+ Glossary((short) 2),
+ TermsOfService((short) 3),
+ UserGuide((short) 4);
+
+ private final Short value;
+
+ SupportiveMaterialFieldType(Short value) {
+ this.value = value;
+ }
+
+ @Override
+ public Short getValue() {
+ return value;
+ }
+
+ private static final Map map = EnumUtils.getEnumValueMap(SupportiveMaterialFieldType.class);
+
+ public static SupportiveMaterialFieldType of(Short i) {
+ return map.get(i);
+ }
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/enums/TenantConfigurationType.java b/backend/core/src/main/java/org/opencdmp/commons/enums/TenantConfigurationType.java
new file mode 100644
index 000000000..1bfa0dfff
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/enums/TenantConfigurationType.java
@@ -0,0 +1,33 @@
+package org.opencdmp.commons.enums;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.opencdmp.data.converters.enums.DatabaseEnum;
+
+import java.util.Map;
+
+public enum TenantConfigurationType implements DatabaseEnum {
+
+ DepositPlugins((short) 0),
+ FileTransformerPlugins((short) 1),
+ DefaultUserLocale((short) 2),
+ Logo((short) 3),
+ CssColors((short) 4);
+
+ private final Short value;
+
+ TenantConfigurationType(Short value) {
+ this.value = value;
+ }
+
+ @JsonValue
+ public Short getValue() {
+ return value;
+ }
+
+ private static final Map map = EnumUtils.getEnumValueMap(TenantConfigurationType.class);
+
+ public static TenantConfigurationType of(Short i) {
+ return map.get(i);
+ }
+
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/enums/UserDescriptionTemplateRole.java b/backend/core/src/main/java/org/opencdmp/commons/enums/UserDescriptionTemplateRole.java
new file mode 100644
index 000000000..fc75dca7d
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/enums/UserDescriptionTemplateRole.java
@@ -0,0 +1,30 @@
+package org.opencdmp.commons.enums;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.opencdmp.data.converters.enums.DatabaseEnum;
+
+import java.util.Map;
+
+public enum UserDescriptionTemplateRole implements DatabaseEnum {
+
+ Owner((short) 0),
+ Member((short) 1);
+
+ private final Short value;
+
+ UserDescriptionTemplateRole(Short value) {
+ this.value = value;
+ }
+
+ @JsonValue
+ public Short getValue() {
+ return value;
+ }
+
+ private static final Map map = EnumUtils.getEnumValueMap(UserDescriptionTemplateRole.class);
+
+ public static UserDescriptionTemplateRole of(Short i) {
+ return map.get(i);
+ }
+
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/enums/UserSettingsType.java b/backend/core/src/main/java/org/opencdmp/commons/enums/UserSettingsType.java
new file mode 100644
index 000000000..0a60f575f
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/enums/UserSettingsType.java
@@ -0,0 +1,30 @@
+package org.opencdmp.commons.enums;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.opencdmp.data.converters.enums.DatabaseEnum;
+
+import java.util.Map;
+
+public enum UserSettingsType implements DatabaseEnum {
+
+ Settings((short) 0),
+ Config((short) 1);
+
+ private final Short value;
+
+ UserSettingsType(Short value) {
+ this.value = value;
+ }
+
+ @JsonValue
+ public Short getValue() {
+ return value;
+ }
+
+ private static final Map map = EnumUtils.getEnumValueMap(UserSettingsType.class);
+
+ public static UserSettingsType of(Short i) {
+ return map.get(i);
+ }
+}
+
diff --git a/backend/core/src/main/java/org/opencdmp/commons/enums/notification/NotificationContactType.java b/backend/core/src/main/java/org/opencdmp/commons/enums/notification/NotificationContactType.java
new file mode 100644
index 000000000..af180f8be
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/enums/notification/NotificationContactType.java
@@ -0,0 +1,33 @@
+package org.opencdmp.commons.enums.notification;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.opencdmp.commons.enums.EnumUtils;
+import org.opencdmp.data.converters.enums.DatabaseEnum;
+
+import java.util.Map;
+
+public enum NotificationContactType implements DatabaseEnum {
+
+ EMAIL((short) 0),
+ SLACK_BROADCAST((short) 1),
+ SMS((short) 2),
+ IN_APP((short) 3);
+
+ private final Short value;
+
+ NotificationContactType(Short value) {
+ this.value = value;
+ }
+
+ @JsonValue
+ public Short getValue() {
+ return value;
+ }
+
+ private static final Map map = EnumUtils.getEnumValueMap(NotificationContactType.class);
+
+ public static NotificationContactType of(Short i) {
+ return map.get(i);
+ }
+
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/fake/FakeRequestAttributes.java b/backend/core/src/main/java/org/opencdmp/commons/fake/FakeRequestAttributes.java
new file mode 100644
index 000000000..a258f23de
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/fake/FakeRequestAttributes.java
@@ -0,0 +1,126 @@
+package org.opencdmp.commons.fake;
+
+import org.jetbrains.annotations.NotNull;
+import org.springframework.util.Assert;
+import org.springframework.web.context.request.RequestAttributes;
+
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+public class FakeRequestAttributes implements RequestAttributes {
+ private final Map requestAttributeMap = new HashMap<>();
+ private final Map requestDestructionCallbacks = new LinkedHashMap<>(8);
+ private volatile boolean requestActive = true;
+
+ @Override
+ public Object getAttribute(@NotNull String name, int scope) {
+ if (scope == RequestAttributes.SCOPE_REQUEST) {
+ if (!isRequestActive()) {
+ throw new IllegalStateException("Cannot ask for request attribute - request is not active anymore!");
+ }
+ return this.requestAttributeMap.get(name);
+ } else {
+ throw new IllegalStateException("Only " + RequestAttributes.SCOPE_REQUEST + " allowed for " + FakeRequestAttributes.class.getSimpleName());
+ }
+ }
+
+ @Override
+ public void setAttribute(@NotNull String name, @NotNull Object value, int scope) {
+ if (scope == RequestAttributes.SCOPE_REQUEST) {
+ if (!isRequestActive()) {
+ throw new IllegalStateException("Cannot set request attribute - request is not active anymore!");
+ }
+ this.requestAttributeMap.put(name, value);
+ } else {
+ throw new IllegalStateException("Only " + RequestAttributes.SCOPE_REQUEST + " allowed for " + FakeRequestAttributes.class.getSimpleName());
+ }
+ }
+
+ @Override
+ public void removeAttribute(@NotNull String name, int scope) {
+ if (scope == RequestAttributes.SCOPE_REQUEST) {
+ if (isRequestActive()) {
+ removeRequestDestructionCallback(name);
+ this.requestAttributeMap.remove(name);
+ }
+ } else {
+ throw new IllegalStateException("Only " + RequestAttributes.SCOPE_REQUEST + " allowed for " + FakeRequestAttributes.class.getSimpleName());
+ }
+ }
+
+ @Override
+ public String @NotNull [] getAttributeNames(int scope) {
+ if (scope == RequestAttributes.SCOPE_REQUEST) {
+ if (!isRequestActive()) {
+ throw new IllegalStateException("Cannot ask for request attributes - request is not active anymore!");
+ }
+ return this.requestAttributeMap.keySet().toArray(new String[0]);
+ } else {
+ throw new IllegalStateException("Only " + RequestAttributes.SCOPE_REQUEST + " allowed for " + FakeRequestAttributes.class.getSimpleName());
+ }
+ //return new String[0];
+ }
+
+ @Override
+ public void registerDestructionCallback(@NotNull String name, @NotNull Runnable callback, int scope) {
+ if (scope == SCOPE_REQUEST) {
+ registerRequestDestructionCallback(name, callback);
+ } else {
+ throw new IllegalStateException("Only " + RequestAttributes.SCOPE_REQUEST + " allowed for " + FakeRequestAttributes.class.getSimpleName());
+ }
+ }
+
+ protected final void registerRequestDestructionCallback(String name, Runnable callback) {
+ Assert.notNull(name, "Name must not be null");
+ Assert.notNull(callback, "Callback must not be null");
+ synchronized (this.requestDestructionCallbacks) {
+ this.requestDestructionCallbacks.put(name, callback);
+ }
+ }
+
+ @Override
+ public Object resolveReference(@NotNull String key) {
+ // Not supported
+ return null;
+ }
+
+ @Override
+ public @NotNull String getSessionId() {
+ return "";
+ }
+
+ @Override
+ public @NotNull Object getSessionMutex() {
+ return new Object();
+ }
+
+ public void requestCompleted() {
+ executeRequestDestructionCallbacks();
+ for (String name : getAttributeNames(RequestAttributes.SCOPE_REQUEST)) {
+ this.removeAttribute(name, RequestAttributes.SCOPE_REQUEST);
+ }
+ this.requestActive = false;
+ }
+
+ private boolean isRequestActive() {
+ return this.requestActive;
+ }
+
+
+ private void removeRequestDestructionCallback(String name) {
+ Assert.notNull(name, "Name must not be null");
+ synchronized (this.requestDestructionCallbacks) {
+ this.requestDestructionCallbacks.remove(name);
+ }
+ }
+
+ private void executeRequestDestructionCallbacks() {
+ synchronized (this.requestDestructionCallbacks) {
+ for (Runnable runnable : this.requestDestructionCallbacks.values()) {
+ runnable.run();
+ }
+ this.requestDestructionCallbacks.clear();
+ }
+ }
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/fake/FakeRequestScope.java b/backend/core/src/main/java/org/opencdmp/commons/fake/FakeRequestScope.java
new file mode 100644
index 000000000..7cfc9ae9c
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/fake/FakeRequestScope.java
@@ -0,0 +1,44 @@
+package org.opencdmp.commons.fake;
+
+import org.springframework.web.context.request.RequestAttributes;
+import org.springframework.web.context.request.RequestContextHolder;
+
+import java.io.Closeable;
+
+public class FakeRequestScope implements Closeable {
+ private RequestAttributes initialRequestAttributes = null;
+ private FakeRequestAttributes currentRequestAttributes = null;
+ boolean isInUse = false;
+
+ public FakeRequestScope() {
+ this.reset();
+ }
+
+ public final void reset() {
+ this.close();
+ this.isInUse = true;
+
+ this.initialRequestAttributes = RequestContextHolder.getRequestAttributes();
+ this.currentRequestAttributes = new FakeRequestAttributes();
+ RequestContextHolder.setRequestAttributes(this.currentRequestAttributes);
+ }
+
+ @Override
+ public void close() {
+ if (!this.isInUse)
+ return;
+ this.isInUse = false;
+
+ if (initialRequestAttributes != null)
+ RequestContextHolder.setRequestAttributes(initialRequestAttributes);
+ else
+ RequestContextHolder.resetRequestAttributes();
+
+ if (currentRequestAttributes != null)
+ currentRequestAttributes.requestCompleted();
+
+ this.initialRequestAttributes = null;
+ this.currentRequestAttributes = null;
+ }
+
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/locale/LocaleConfiguration.java b/backend/core/src/main/java/org/opencdmp/commons/locale/LocaleConfiguration.java
new file mode 100644
index 000000000..197a63ea8
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/locale/LocaleConfiguration.java
@@ -0,0 +1,20 @@
+package org.opencdmp.commons.locale;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@EnableConfigurationProperties(LocaleProperties.class)
+public class LocaleConfiguration {
+ private final LocaleProperties properties;
+
+ @Autowired
+ public LocaleConfiguration(LocaleProperties properties) {
+ this.properties = properties;
+ }
+
+ public LocaleProperties getProperties() {
+ return properties;
+ }
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/locale/LocaleProperties.java b/backend/core/src/main/java/org/opencdmp/commons/locale/LocaleProperties.java
new file mode 100644
index 000000000..7ddf7ae04
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/locale/LocaleProperties.java
@@ -0,0 +1,34 @@
+package org.opencdmp.commons.locale;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+@ConfigurationProperties(prefix = "locale")
+public class LocaleProperties {
+ private String timezone;
+ private String language;
+ private String culture;
+
+ public String getTimezone() {
+ return timezone;
+ }
+
+ public void setTimezone(String timezone) {
+ this.timezone = timezone;
+ }
+
+ public String getLanguage() {
+ return language;
+ }
+
+ public void setLanguage(String language) {
+ this.language = language;
+ }
+
+ public String getCulture() {
+ return culture;
+ }
+
+ public void setCulture(String culture) {
+ this.culture = culture;
+ }
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/lock/LockByKeyManager.java b/backend/core/src/main/java/org/opencdmp/commons/lock/LockByKeyManager.java
new file mode 100644
index 000000000..c65faec63
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/lock/LockByKeyManager.java
@@ -0,0 +1,58 @@
+package org.opencdmp.commons.lock;
+
+import org.springframework.stereotype.Service;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.locks.ReentrantLock;
+
+@Service
+public class LockByKeyManager {
+
+ private static class LockWrapper {
+ private final ReentrantLock lock = new ReentrantLock();
+ private final AtomicInteger numberOfThreadsInQueue = new AtomicInteger(1);
+
+ private LockWrapper addThreadInQueue() {
+ numberOfThreadsInQueue.incrementAndGet();
+ return this;
+ }
+
+ private int removeThreadFromQueue() {
+ return numberOfThreadsInQueue.decrementAndGet();
+ }
+
+ }
+
+ private static ConcurrentHashMap locks = new ConcurrentHashMap();
+
+ public void lock(String key) {
+ LockWrapper lockWrapper = locks.compute(key, (k, v) -> v == null ? new LockWrapper() : v.addThreadInQueue());
+ lockWrapper.lock.lock();
+ }
+
+ public boolean tryLock(String key, long timeout, TimeUnit unit) throws InterruptedException {
+ LockWrapper lockWrapper = null;
+ try {
+ lockWrapper = locks.compute(key, (k, v) -> v == null ? new LockWrapper() : v.addThreadInQueue());
+ return lockWrapper.lock.tryLock(timeout, unit);
+ } catch (Exception ex){
+ if (lockWrapper != null && lockWrapper.removeThreadFromQueue() == 0) {
+ // NB : We pass in the specific value to remove to handle the case where another thread would queue right before the removal
+ locks.remove(key, lockWrapper);
+ }
+ throw ex;
+ }
+ }
+
+ public void unlock(String key) {
+ LockWrapper lockWrapper = locks.get(key);
+ lockWrapper.lock.unlock();
+ if (lockWrapper.removeThreadFromQueue() == 0) {
+ // NB : We pass in the specific value to remove to handle the case where another thread would queue right before the removal
+ locks.remove(key, lockWrapper);
+ }
+ }
+
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/metrics/MetricLabels.java b/backend/core/src/main/java/org/opencdmp/commons/metrics/MetricLabels.java
new file mode 100644
index 000000000..a09721df1
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/metrics/MetricLabels.java
@@ -0,0 +1,21 @@
+package org.opencdmp.commons.metrics;
+
+public class MetricLabels {
+
+ public static final String DRAFT = "draft";
+
+ public static final String FINALIZED = "finalized";
+
+ public static final String PUBLISHED = "published";
+
+ public static final String DOIED = "doied";
+
+ public static final String ACTIVE = "active";
+
+ public static final String USED = "used";
+
+ public static final String LOGGEDIN = "loggedin";
+
+ public static final String TOTAL = "total";
+
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/metrics/MetricNames.java b/backend/core/src/main/java/org/opencdmp/commons/metrics/MetricNames.java
new file mode 100644
index 000000000..aa263e1d9
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/metrics/MetricNames.java
@@ -0,0 +1,28 @@
+package org.opencdmp.commons.metrics;
+
+public class MetricNames {
+
+ public static final String DATASET_TEMPLATE = "argos_dmp_templates";
+
+ public static final String INSTALLATIONS = "installations";
+
+ public static final String USERS = "argos_users";
+
+ public static final String DMP = "argos_managed_dmps";
+
+ public static final String DATASET = "argos_managed_dataset_descriptions";
+
+ public static final String RESEARCHERS = "argos_researchers";
+
+ public static final String PROJECTS = "argos_projects";
+
+ public static final String FUNDERS = "argos_funders";
+
+ public static final String GRANTS = "argos_grants";
+
+ public static final String LANGUAGES = "argos_languages";
+
+ public static final String DMP_WITH_GRANT = "argos_managed_dmps_with_grantid";
+
+ public static final String NEXUS_PREFIX = "nexus_";
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/notification/NotificationConfiguration.java b/backend/core/src/main/java/org/opencdmp/commons/notification/NotificationConfiguration.java
new file mode 100644
index 000000000..990f602f5
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/notification/NotificationConfiguration.java
@@ -0,0 +1,20 @@
+package org.opencdmp.commons.notification;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@EnableConfigurationProperties(NotificationProperties.class)
+public class NotificationConfiguration {
+ private final NotificationProperties properties;
+
+ @Autowired
+ public NotificationConfiguration(NotificationProperties properties) {
+ this.properties = properties;
+ }
+
+ public NotificationProperties getProperties() {
+ return properties;
+ }
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/notification/NotificationProperties.java b/backend/core/src/main/java/org/opencdmp/commons/notification/NotificationProperties.java
new file mode 100644
index 000000000..4da201dcf
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/notification/NotificationProperties.java
@@ -0,0 +1,136 @@
+package org.opencdmp.commons.notification;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+import java.util.UUID;
+
+@ConfigurationProperties(prefix = "notification")
+public class NotificationProperties {
+
+ private UUID dmpInvitationExternalUserType;
+ private UUID dmpInvitationExistingUserType;
+ private UUID dmpModifiedType;
+ private UUID dmpFinalisedType;
+ private UUID descriptionModifiedType;
+ private UUID descriptionFinalisedType;
+ private UUID mergeAccountConfirmationType;
+ private UUID removeCredentialConfirmationType;
+ private UUID dmpDepositType;
+ private UUID descriptionTemplateInvitationType;
+ private UUID contactSupportType;
+ private UUID publicContactSupportType;
+ private int emailExpirationTimeSeconds;
+ private String contactSupportEmail;
+
+ public UUID getDmpInvitationExternalUserType() {
+ return dmpInvitationExternalUserType;
+ }
+
+ public void setDmpInvitationExternalUserType(UUID dmpInvitationExternalUserType) {
+ this.dmpInvitationExternalUserType = dmpInvitationExternalUserType;
+ }
+
+ public UUID getDmpInvitationExistingUserType() {
+ return dmpInvitationExistingUserType;
+ }
+
+ public void setDmpInvitationExistingUserType(UUID dmpInvitationExistingUserType) {
+ this.dmpInvitationExistingUserType = dmpInvitationExistingUserType;
+ }
+
+ public UUID getDmpModifiedType() {
+ return dmpModifiedType;
+ }
+
+ public void setDmpModifiedType(UUID dmpModifiedType) {
+ this.dmpModifiedType = dmpModifiedType;
+ }
+
+ public UUID getDmpFinalisedType() {
+ return dmpFinalisedType;
+ }
+
+ public void setDmpFinalisedType(UUID dmpFinalisedType) {
+ this.dmpFinalisedType = dmpFinalisedType;
+ }
+
+ public UUID getDescriptionModifiedType() {
+ return descriptionModifiedType;
+ }
+
+ public void setDescriptionModifiedType(UUID descriptionModifiedType) {
+ this.descriptionModifiedType = descriptionModifiedType;
+ }
+
+ public UUID getDescriptionFinalisedType() {
+ return descriptionFinalisedType;
+ }
+
+ public void setDescriptionFinalisedType(UUID descriptionFinalisedType) {
+ this.descriptionFinalisedType = descriptionFinalisedType;
+ }
+
+ public UUID getMergeAccountConfirmationType() {
+ return mergeAccountConfirmationType;
+ }
+
+ public void setMergeAccountConfirmationType(UUID mergeAccountConfirmationType) {
+ this.mergeAccountConfirmationType = mergeAccountConfirmationType;
+ }
+
+ public UUID getRemoveCredentialConfirmationType() {
+ return removeCredentialConfirmationType;
+ }
+
+ public void setRemoveCredentialConfirmationType(UUID removeCredentialConfirmationType) {
+ this.removeCredentialConfirmationType = removeCredentialConfirmationType;
+ }
+
+ public UUID getDmpDepositType() {
+ return dmpDepositType;
+ }
+
+ public void setDmpDepositType(UUID dmpDepositType) {
+ this.dmpDepositType = dmpDepositType;
+ }
+
+ public UUID getDescriptionTemplateInvitationType() {
+ return descriptionTemplateInvitationType;
+ }
+
+ public void setDescriptionTemplateInvitationType(UUID descriptionTemplateInvitationType) {
+ this.descriptionTemplateInvitationType = descriptionTemplateInvitationType;
+ }
+
+ public int getEmailExpirationTimeSeconds() {
+ return emailExpirationTimeSeconds;
+ }
+
+ public void setEmailExpirationTimeSeconds(int emailExpirationTimeSeconds) {
+ this.emailExpirationTimeSeconds = emailExpirationTimeSeconds;
+ }
+
+ public UUID getContactSupportType() {
+ return contactSupportType;
+ }
+
+ public void setContactSupportType(UUID contactSupportType) {
+ this.contactSupportType = contactSupportType;
+ }
+
+ public UUID getPublicContactSupportType() {
+ return publicContactSupportType;
+ }
+
+ public void setPublicContactSupportType(UUID publicContactSupportType) {
+ this.publicContactSupportType = publicContactSupportType;
+ }
+
+ public String getContactSupportEmail() {
+ return contactSupportEmail;
+ }
+
+ public void setContactSupportEmail(String contactSupportEmail) {
+ this.contactSupportEmail = contactSupportEmail;
+ }
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/scope/tenant/MultitenancyConfiguration.java b/backend/core/src/main/java/org/opencdmp/commons/scope/tenant/MultitenancyConfiguration.java
new file mode 100644
index 000000000..dd7c17666
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/scope/tenant/MultitenancyConfiguration.java
@@ -0,0 +1,9 @@
+package org.opencdmp.commons.scope.tenant;
+
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@EnableConfigurationProperties(MultitenancyProperties.class)
+public class MultitenancyConfiguration {
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/scope/tenant/MultitenancyProperties.java b/backend/core/src/main/java/org/opencdmp/commons/scope/tenant/MultitenancyProperties.java
new file mode 100644
index 000000000..ce18b6c6c
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/scope/tenant/MultitenancyProperties.java
@@ -0,0 +1,25 @@
+package org.opencdmp.commons.scope.tenant;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+@ConfigurationProperties(prefix = "tenant.multitenancy")
+public class MultitenancyProperties {
+ private boolean isMultitenant;
+ private String defaultTenantCode;
+
+ public boolean isMultitenant() {
+ return isMultitenant;
+ }
+
+ public void setIsMultitenant(boolean multitenant) {
+ isMultitenant = multitenant;
+ }
+
+ public String getDefaultTenantCode() {
+ return defaultTenantCode;
+ }
+
+ public void setDefaultTenantCode(String defaultTenantCode) {
+ this.defaultTenantCode = defaultTenantCode;
+ }
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/scope/tenant/TenantScope.java b/backend/core/src/main/java/org/opencdmp/commons/scope/tenant/TenantScope.java
new file mode 100644
index 000000000..a70cb1470
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/scope/tenant/TenantScope.java
@@ -0,0 +1,126 @@
+package org.opencdmp.commons.scope.tenant;
+
+import org.opencdmp.data.tenant.TenantScopedBaseEntity;
+import jakarta.persistence.EntityManager;
+import org.hibernate.Session;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.annotation.RequestScope;
+
+import javax.management.InvalidApplicationException;
+
+import java.util.UUID;
+import java.util.concurrent.atomic.AtomicReference;
+
+@Component
+@RequestScope
+public class TenantScope {
+ public static final String TenantReplaceParameter = "::TenantCode::";
+ private final MultitenancyProperties multitenancy;
+ private final AtomicReference tenant = new AtomicReference<>();
+ private final AtomicReference tenantCode = new AtomicReference<>();
+ private final AtomicReference initialTenant = new AtomicReference<>();
+ private final AtomicReference initialTenantCode = new AtomicReference<>();
+
+ @Autowired
+ public TenantScope(MultitenancyProperties multitenancy) {
+ this.multitenancy = multitenancy;
+ }
+
+ public Boolean isMultitenant() {
+ return multitenancy.isMultitenant();
+ }
+
+ public String getDefaultTenantCode() {
+ return multitenancy.getDefaultTenantCode();
+ }
+
+ public Boolean isSet() {
+ if (!this.isMultitenant())
+ return Boolean.TRUE;
+ return this.tenant.get() != null || this.isDefaultTenant();
+ }
+
+ public Boolean isDefaultTenant() {
+ if (!this.isMultitenant())
+ return Boolean.TRUE;
+ return this.multitenancy.getDefaultTenantCode().equalsIgnoreCase(this.tenantCode.get());
+ }
+
+ public UUID getTenant() throws InvalidApplicationException {
+ if (!this.isMultitenant())
+ return null;
+ if (this.tenant.get() == null && !this.isDefaultTenant())
+ throw new InvalidApplicationException("tenant not set");
+ return this.isDefaultTenant() ? null : this.tenant.get();
+ }
+
+ public String getTenantCode() throws InvalidApplicationException {
+ if (!this.isMultitenant())
+ return null;
+ if (this.tenantCode.get() == null)
+ throw new InvalidApplicationException("tenant not set");
+ return this.tenantCode.get();
+ }
+
+ public void setTempTenant(EntityManager entityManager, UUID tenant, String tenantCode) {
+ this.tenant.set(tenant);
+ this.tenantCode.set(tenantCode);
+
+ entityManager
+ .unwrap(Session.class)
+ .disableFilter(TenantScopedBaseEntity.TENANT_FILTER);
+
+ entityManager
+ .unwrap(Session.class)
+ .disableFilter(TenantScopedBaseEntity.DEFAULT_TENANT_FILTER);
+ if (this.tenant.get() != null || this.isDefaultTenant()) {
+ if(!this.isDefaultTenant()) {
+ entityManager
+ .unwrap(Session.class)
+ .enableFilter(TenantScopedBaseEntity.TENANT_FILTER)
+ .setParameter(TenantScopedBaseEntity.TENANT_FILTER_TENANT_PARAM, this.tenant.get().toString());
+ } else {
+ entityManager
+ .unwrap(Session.class)
+ .enableFilter(TenantScopedBaseEntity.DEFAULT_TENANT_FILTER);
+ }
+ }
+ }
+
+ public void removeTempTenant(EntityManager entityManager) {
+ this.tenant.set(this.initialTenant.get());
+ this.tenantCode.set(this.initialTenantCode.get());
+
+
+ entityManager
+ .unwrap(Session.class)
+ .disableFilter(TenantScopedBaseEntity.TENANT_FILTER);
+
+ entityManager
+ .unwrap(Session.class)
+ .disableFilter(TenantScopedBaseEntity.DEFAULT_TENANT_FILTER);
+ if (this.initialTenant.get() != null || this.isDefaultTenant()) {
+ if(!this.isDefaultTenant()) {
+ entityManager
+ .unwrap(Session.class)
+ .enableFilter(TenantScopedBaseEntity.TENANT_FILTER)
+ .setParameter(TenantScopedBaseEntity.TENANT_FILTER_TENANT_PARAM, this.tenant.get().toString());
+ } else {
+ entityManager
+ .unwrap(Session.class)
+ .enableFilter(TenantScopedBaseEntity.DEFAULT_TENANT_FILTER);
+ }
+ }
+ }
+
+ public void setTenant(UUID tenant, String tenantCode) {
+ if (this.isMultitenant()) {
+ this.tenant.set(tenant);
+ this.initialTenant.set(tenant);
+ this.tenantCode.set(tenantCode);
+ this.initialTenantCode.set(tenantCode);
+ }
+ }
+}
+
diff --git a/backend/core/src/main/java/org/opencdmp/commons/scope/tenant/TenantScoped.java b/backend/core/src/main/java/org/opencdmp/commons/scope/tenant/TenantScoped.java
new file mode 100644
index 000000000..7735776b6
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/scope/tenant/TenantScoped.java
@@ -0,0 +1,9 @@
+package org.opencdmp.commons.scope.tenant;
+
+import java.beans.Transient;
+import java.util.UUID;
+
+public interface TenantScoped {
+ void setTenantId(UUID tenantId);
+ UUID getTenantId();
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/scope/user/UserScope.java b/backend/core/src/main/java/org/opencdmp/commons/scope/user/UserScope.java
new file mode 100644
index 000000000..5de65380f
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/scope/user/UserScope.java
@@ -0,0 +1,35 @@
+package org.opencdmp.commons.scope.user;
+
+import gr.cite.tools.logging.LoggerService;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.annotation.RequestScope;
+
+import javax.management.InvalidApplicationException;
+import java.util.UUID;
+import java.util.concurrent.atomic.AtomicReference;
+
+@Component
+@RequestScope
+public class UserScope {
+ private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(UserScope.class));
+ private final AtomicReference userId = new AtomicReference<>();
+
+ public Boolean isSet() {
+ return this.userId.get() != null;
+ }
+
+ public UUID getUserId() throws InvalidApplicationException {
+ if (this.userId.get() == null) throw new InvalidApplicationException("user not set");
+ return this.userId.get();
+ }
+
+ public UUID getUserIdSafe() {
+ return this.userId.get();
+ }
+
+ public void setUserId(UUID userId) {
+ this.userId.set(userId);
+ }
+}
+
diff --git a/backend/core/src/main/java/org/opencdmp/commons/types/actionconfirmation/DmpInvitationEntity.java b/backend/core/src/main/java/org/opencdmp/commons/types/actionconfirmation/DmpInvitationEntity.java
new file mode 100644
index 000000000..e01d2ccc6
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/types/actionconfirmation/DmpInvitationEntity.java
@@ -0,0 +1,44 @@
+package org.opencdmp.commons.types.actionconfirmation;
+
+import org.opencdmp.commons.enums.DmpUserRole;
+import jakarta.xml.bind.annotation.*;
+
+import java.util.UUID;
+
+@XmlRootElement(name = "dmp-invitation")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class DmpInvitationEntity {
+
+ @XmlAttribute(name = "email")
+ private String email;
+
+ @XmlAttribute(name = "dmp")
+ private UUID dmpId;
+
+ @XmlAttribute(name = "dmp-role")
+ private DmpUserRole role;
+
+ public String getEmail() {
+ return email;
+ }
+
+ public void setEmail(String email) {
+ this.email = email;
+ }
+
+ public UUID getDmpId() {
+ return dmpId;
+ }
+
+ public void setDmpId(UUID dmpId) {
+ this.dmpId = dmpId;
+ }
+
+ public DmpUserRole getRole() {
+ return role;
+ }
+
+ public void setRole(DmpUserRole role) {
+ this.role = role;
+ }
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/types/actionconfirmation/MergeAccountConfirmationEntity.java b/backend/core/src/main/java/org/opencdmp/commons/types/actionconfirmation/MergeAccountConfirmationEntity.java
new file mode 100644
index 000000000..4af63df6e
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/types/actionconfirmation/MergeAccountConfirmationEntity.java
@@ -0,0 +1,22 @@
+package org.opencdmp.commons.types.actionconfirmation;
+
+import jakarta.xml.bind.annotation.XmlAccessType;
+import jakarta.xml.bind.annotation.XmlAccessorType;
+import jakarta.xml.bind.annotation.XmlAttribute;
+import jakarta.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement(name = "merge-account-confirmation")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class MergeAccountConfirmationEntity {
+
+ @XmlAttribute(name = "email")
+ private String email;
+
+ public String getEmail() {
+ return email;
+ }
+
+ public void setEmail(String email) {
+ this.email = email;
+ }
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/types/actionconfirmation/RemoveCredentialRequestEntity.java b/backend/core/src/main/java/org/opencdmp/commons/types/actionconfirmation/RemoveCredentialRequestEntity.java
new file mode 100644
index 000000000..48d8d39a8
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/types/actionconfirmation/RemoveCredentialRequestEntity.java
@@ -0,0 +1,24 @@
+package org.opencdmp.commons.types.actionconfirmation;
+
+import jakarta.xml.bind.annotation.XmlAccessType;
+import jakarta.xml.bind.annotation.XmlAccessorType;
+import jakarta.xml.bind.annotation.XmlAttribute;
+import jakarta.xml.bind.annotation.XmlRootElement;
+
+import java.util.UUID;
+
+@XmlRootElement(name = "remove-credential-confirmation")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class RemoveCredentialRequestEntity {
+
+ @XmlAttribute(name = "credential-id")
+ private UUID credentialId;
+
+ public UUID getCredentialId() {
+ return credentialId;
+ }
+
+ public void setCredentialId(UUID credentialId) {
+ this.credentialId = credentialId;
+ }
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/types/dashborad/RecentActivityItemEntity.java b/backend/core/src/main/java/org/opencdmp/commons/types/dashborad/RecentActivityItemEntity.java
new file mode 100644
index 000000000..8e7b23592
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/types/dashborad/RecentActivityItemEntity.java
@@ -0,0 +1,62 @@
+package org.opencdmp.commons.types.dashborad;
+
+import org.opencdmp.commons.enums.RecentActivityItemType;
+
+import java.time.Instant;
+import java.util.UUID;
+
+public class RecentActivityItemEntity {
+ private RecentActivityItemType type;
+ private UUID id;
+ private Instant updatedAt;
+ private String label;
+ private Short statusValue;
+
+ public RecentActivityItemEntity(RecentActivityItemType type, UUID id, Instant updatedAt, String label, Short statusValue) {
+ this.type = type;
+ this.id = id;
+ this.updatedAt = updatedAt;
+ this.label = label;
+ this.statusValue = statusValue;
+ }
+
+ public RecentActivityItemType getType() {
+ return type;
+ }
+
+ public void setType(RecentActivityItemType type) {
+ this.type = type;
+ }
+
+ public UUID getId() {
+ return id;
+ }
+
+ public void setId(UUID id) {
+ this.id = id;
+ }
+
+ public Instant getUpdatedAt() {
+ return updatedAt;
+ }
+
+ public void setUpdatedAt(Instant updatedAt) {
+ this.updatedAt = updatedAt;
+ }
+
+ public String getLabel() {
+ return label;
+ }
+
+ public void setLabel(String label) {
+ this.label = label;
+ }
+
+ public Short getStatusValue() {
+ return statusValue;
+ }
+
+ public void setStatusValue(Short statusValue) {
+ this.statusValue = statusValue;
+ }
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/types/deposit/DepositSourceEntity.java b/backend/core/src/main/java/org/opencdmp/commons/types/deposit/DepositSourceEntity.java
new file mode 100644
index 000000000..0aef2fe0e
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/types/deposit/DepositSourceEntity.java
@@ -0,0 +1,77 @@
+package org.opencdmp.commons.types.deposit;
+
+public class DepositSourceEntity {
+
+ private String repositoryId;
+ private String url;
+ private String issuerUrl;
+ private String clientId;
+ private String clientSecret;
+ private String scope;
+ private String pdfTransformerId;
+ private String rdaTransformerId;
+
+ public String getRepositoryId() {
+ return repositoryId;
+ }
+
+ public void setRepositoryId(String repositoryId) {
+ this.repositoryId = repositoryId;
+ }
+
+ public String getUrl() {
+ return url;
+ }
+
+ public void setUrl(String url) {
+ this.url = url;
+ }
+
+ public String getIssuerUrl() {
+ return issuerUrl;
+ }
+
+ public void setIssuerUrl(String issuerUrl) {
+ this.issuerUrl = issuerUrl;
+ }
+
+ public String getClientId() {
+ return clientId;
+ }
+
+ public void setClientId(String clientId) {
+ this.clientId = clientId;
+ }
+
+ public String getClientSecret() {
+ return clientSecret;
+ }
+
+ public void setClientSecret(String clientSecret) {
+ this.clientSecret = clientSecret;
+ }
+
+ public String getScope() {
+ return scope;
+ }
+
+ public void setScope(String scope) {
+ this.scope = scope;
+ }
+
+ public String getPdfTransformerId() {
+ return pdfTransformerId;
+ }
+
+ public void setPdfTransformerId(String pdfTransformerId) {
+ this.pdfTransformerId = pdfTransformerId;
+ }
+
+ public String getRdaTransformerId() {
+ return rdaTransformerId;
+ }
+
+ public void setRdaTransformerId(String rdaTransformerId) {
+ this.rdaTransformerId = rdaTransformerId;
+ }
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/types/description/ExternalIdentifierEntity.java b/backend/core/src/main/java/org/opencdmp/commons/types/description/ExternalIdentifierEntity.java
new file mode 100644
index 000000000..2e6d07639
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/types/description/ExternalIdentifierEntity.java
@@ -0,0 +1,25 @@
+package org.opencdmp.commons.types.description;
+
+public class ExternalIdentifierEntity {
+
+ private String identifier;
+
+ private String type;
+
+ public String getIdentifier() {
+ return identifier;
+ }
+
+ public void setIdentifier(String identifier) {
+ this.identifier = identifier;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/types/description/FieldEntity.java b/backend/core/src/main/java/org/opencdmp/commons/types/description/FieldEntity.java
new file mode 100644
index 000000000..969056255
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/types/description/FieldEntity.java
@@ -0,0 +1,44 @@
+package org.opencdmp.commons.types.description;
+
+
+import java.time.Instant;
+import java.util.List;
+
+public class FieldEntity {
+ private String textValue;
+ private List textListValue;
+ private Instant dateValue;
+ private ExternalIdentifierEntity externalIdentifier;
+
+ public String getTextValue() {
+ return textValue;
+ }
+
+ public void setTextValue(String textValue) {
+ this.textValue = textValue;
+ }
+
+ public List getTextListValue() {
+ return textListValue;
+ }
+
+ public void setTextListValue(List textListValue) {
+ this.textListValue = textListValue;
+ }
+
+ public Instant getDateValue() {
+ return dateValue;
+ }
+
+ public void setDateValue(Instant dateValue) {
+ this.dateValue = dateValue;
+ }
+
+ public ExternalIdentifierEntity getExternalIdentifier() {
+ return externalIdentifier;
+ }
+
+ public void setExternalIdentifier(ExternalIdentifierEntity externalIdentifier) {
+ this.externalIdentifier = externalIdentifier;
+ }
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/types/description/PropertyDefinitionEntity.java b/backend/core/src/main/java/org/opencdmp/commons/types/description/PropertyDefinitionEntity.java
new file mode 100644
index 000000000..561e3df3c
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/types/description/PropertyDefinitionEntity.java
@@ -0,0 +1,18 @@
+package org.opencdmp.commons.types.description;
+
+import java.util.Map;
+
+public class PropertyDefinitionEntity {
+ private Map fieldSets;
+
+ public Map getFieldSets() {
+ return fieldSets;
+ }
+
+ public void setFieldSets(Map fieldSets) {
+ this.fieldSets = fieldSets;
+ }
+}
+
+
+
diff --git a/backend/core/src/main/java/org/opencdmp/commons/types/description/PropertyDefinitionFieldSetEntity.java b/backend/core/src/main/java/org/opencdmp/commons/types/description/PropertyDefinitionFieldSetEntity.java
new file mode 100644
index 000000000..b0207e859
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/types/description/PropertyDefinitionFieldSetEntity.java
@@ -0,0 +1,15 @@
+package org.opencdmp.commons.types.description;
+
+import java.util.List;
+
+public class PropertyDefinitionFieldSetEntity {
+ private List items;
+
+ public List getItems() {
+ return items;
+ }
+
+ public void setItems(List items) {
+ this.items = items;
+ }
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/types/description/PropertyDefinitionFieldSetItemEntity.java b/backend/core/src/main/java/org/opencdmp/commons/types/description/PropertyDefinitionFieldSetItemEntity.java
new file mode 100644
index 000000000..c17232466
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/types/description/PropertyDefinitionFieldSetItemEntity.java
@@ -0,0 +1,33 @@
+package org.opencdmp.commons.types.description;
+
+import java.util.Map;
+
+public class PropertyDefinitionFieldSetItemEntity {
+ private Map fields;
+ private String comment;
+ private int ordinal;
+
+ public Map getFields() {
+ return fields;
+ }
+
+ public void setFields(Map fields) {
+ this.fields = fields;
+ }
+
+ public String getComment() {
+ return comment;
+ }
+
+ public void setComment(String comment) {
+ this.comment = comment;
+ }
+
+ public int getOrdinal() {
+ return ordinal;
+ }
+
+ public void setOrdinal(int ordinal) {
+ this.ordinal = ordinal;
+ }
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/types/descriptionreference/DescriptionReferenceDataEntity.java b/backend/core/src/main/java/org/opencdmp/commons/types/descriptionreference/DescriptionReferenceDataEntity.java
new file mode 100644
index 000000000..f897f6785
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/types/descriptionreference/DescriptionReferenceDataEntity.java
@@ -0,0 +1,15 @@
+package org.opencdmp.commons.types.descriptionreference;
+
+import java.util.UUID;
+
+public class DescriptionReferenceDataEntity {
+ private String fieldId;
+
+ public String getFieldId() {
+ return fieldId;
+ }
+
+ public void setFieldId(String fieldId) {
+ this.fieldId = fieldId;
+ }
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/DefinitionEntity.java b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/DefinitionEntity.java
new file mode 100644
index 000000000..334864987
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/DefinitionEntity.java
@@ -0,0 +1,50 @@
+package org.opencdmp.commons.types.descriptiontemplate;
+
+import jakarta.xml.bind.annotation.*;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@XmlRootElement(name = "root")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class DefinitionEntity {
+ @XmlElementWrapper(name = "pages")
+ @XmlElement(name = "page")
+ private List pages;
+
+ public List getPages() {
+ return pages;
+ }
+
+ public void setPages(List pageEntities) {
+ this.pages = pageEntities;
+ }
+
+ public List getAllField(){
+ List fieldEntities = new ArrayList<>();
+ if (this.getPages() != null){
+ for (PageEntity sectionEntity: this.getPages()) {
+ fieldEntities.addAll(sectionEntity.getAllField());
+ }
+ }
+ return fieldEntities;
+ }
+
+ public List getAllFieldSets(){
+ List fieldSetsEntities = new ArrayList<>();
+ if (this.getPages() != null){
+ for (PageEntity sectionEntity: this.getPages()) {
+ fieldSetsEntities.addAll(sectionEntity.getAllFieldSets());
+ }
+ }
+ return fieldSetsEntities;
+ }
+
+ public List getFieldSetById(String id) {
+ return this.getAllFieldSets().stream().filter(x-> id.equals(x.getId())).toList();
+ }
+
+ public List getFieldById(String id) {
+ return this.getAllField().stream().filter(x-> id.equals(x.getId())).toList();
+ }
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/ExternalIdentifierEntity.java b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/ExternalIdentifierEntity.java
new file mode 100644
index 000000000..96c1c5a1a
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/ExternalIdentifierEntity.java
@@ -0,0 +1,32 @@
+package org.opencdmp.commons.types.descriptiontemplate;
+
+import jakarta.xml.bind.annotation.XmlAccessType;
+import jakarta.xml.bind.annotation.XmlAccessorType;
+import jakarta.xml.bind.annotation.XmlAttribute;
+
+@XmlAccessorType(XmlAccessType.FIELD)
+public class ExternalIdentifierEntity {
+
+ @XmlAttribute(name="identifier")
+ private String identifier;
+
+ @XmlAttribute(name="type")
+ private String type;
+
+ public String getIdentifier() {
+ return identifier;
+ }
+
+ public void setIdentifier(String identifier) {
+ this.identifier = identifier;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/FieldEntity.java b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/FieldEntity.java
new file mode 100644
index 000000000..58b260e87
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/FieldEntity.java
@@ -0,0 +1,106 @@
+package org.opencdmp.commons.types.descriptiontemplate;
+
+import org.opencdmp.commons.enums.FieldValidationType;
+import org.opencdmp.commons.types.descriptiontemplate.fielddata.*;
+import jakarta.xml.bind.annotation.*;
+
+import java.util.List;
+
+@XmlAccessorType(XmlAccessType.FIELD)
+public class FieldEntity {
+ @XmlAttribute(name="id")
+ private String id;
+ @XmlAttribute(name="ordinal")
+ private int ordinal;
+ @XmlElementWrapper(name = "schematics")
+ @XmlElement(name = "schematic")
+ private List schematics;
+ @XmlAttribute(name="numbering")
+ private String numbering;
+ @XmlAttribute(name="defaultValue")
+ private String defaultValue;
+ @XmlElementWrapper(name = "visibilityRules")
+ @XmlElement(name = "rule")
+ private List visibilityRules;
+
+ @XmlElements({
+ @XmlElement(name = LabelDataEntity.XmlElementName, type = LabelDataEntity.class),
+ @XmlElement(name = LabelAndMultiplicityDataEntity.XmlElementName, type = LabelAndMultiplicityDataEntity.class),
+ @XmlElement(name = UploadDataEntity.XmlElementName, type = UploadDataEntity.class),
+ @XmlElement(name = RadioBoxDataEntity.XmlElementName, type = RadioBoxDataEntity.class),
+ @XmlElement(name = SelectDataEntity.XmlElementName, type = SelectDataEntity.class),
+ @XmlElement(name = ReferenceTypeDataEntity.XmlElementName, type = ReferenceTypeDataEntity.class)
+ })
+ private BaseFieldDataEntity data;
+ @XmlElementWrapper(name = "validations")
+ @XmlElement(name = "validation")
+ private List validations;
+ @XmlAttribute(name="includeInExport")
+ private Boolean includeInExport;
+
+ public String getId() {
+ return id;
+ }
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public int getOrdinal() {
+ return ordinal;
+ }
+ public void setOrdinal(int ordinal) {
+ this.ordinal = ordinal;
+ }
+
+ public List getSchematics() {
+ return schematics;
+ }
+ public void setSchematics(List schematics) {
+ this.schematics = schematics;
+ }
+
+ public BaseFieldDataEntity getData() {
+ return data;
+ }
+ public void setData(BaseFieldDataEntity data) {
+ this.data = data;
+ }
+
+ public String getDefaultValue() {
+ return defaultValue;
+ }
+ public void setDefaultValue(String defaultValue) {
+ this.defaultValue = defaultValue;
+ }
+
+
+ public List getValidations() {
+ return validations;
+ }
+ public void setValidations(List validations) {
+ this.validations = validations;
+ }
+
+ public String getNumbering() {
+ return numbering;
+ }
+ public void setNumbering(String numbering) {
+ this.numbering = numbering;
+ }
+
+ public Boolean getIncludeInExport() {
+ return includeInExport;
+ }
+
+ public void setIncludeInExport(Boolean includeInExport) {
+ this.includeInExport = includeInExport;
+ }
+
+ public List getVisibilityRules() {
+ return visibilityRules;
+ }
+
+ public void setVisibilityRules(List visibilityRules) {
+ this.visibilityRules = visibilityRules;
+ }
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/FieldSetEntity.java b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/FieldSetEntity.java
new file mode 100644
index 000000000..5ab80101d
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/FieldSetEntity.java
@@ -0,0 +1,121 @@
+package org.opencdmp.commons.types.descriptiontemplate;
+
+import jakarta.xml.bind.annotation.*;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@XmlAccessorType(XmlAccessType.FIELD)
+public class FieldSetEntity {
+ @XmlAttribute(name="id")
+ private String id;
+ @XmlAttribute(name="ordinal")
+ private int ordinal;
+
+ @XmlElementWrapper(name = "fields")
+ @XmlElement(name = "field")
+ private List fields;
+ @XmlAttribute(name="numbering")
+ private String numbering;
+ @XmlAttribute(name="title")
+ private String title;
+ @XmlAttribute(name="description")
+ private String description;
+ @XmlAttribute(name="extendedDescription")
+ private String extendedDescription;
+ @XmlAttribute(name="additionalInformation")
+ private String additionalInformation;
+ @XmlElement(name="multiplicity")
+ private MultiplicityEntity multiplicity;
+ @XmlAttribute(name="hasMultiplicity")
+ private boolean hasMultiplicity;
+ @XmlAttribute(name="hasCommentField")
+ private boolean hasCommentField;
+
+ public List getFields() {
+ return fields;
+ }
+ public void setFields(List fieldEntities) {
+ this.fields = fieldEntities;
+ }
+
+ public String getId() {
+ return id;
+ }
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public int getOrdinal() {
+ return ordinal;
+ }
+ public void setOrdinal(int ordinal) {
+ this.ordinal = ordinal;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public String getExtendedDescription() {
+ return extendedDescription;
+ }
+ public void setExtendedDescription(String extendedDescription) {
+ this.extendedDescription = extendedDescription;
+ }
+
+ public MultiplicityEntity getMultiplicity() {
+ return multiplicity;
+ }
+ public void setMultiplicity(MultiplicityEntity multiplicity) {
+ this.multiplicity = multiplicity;
+ }
+
+ public boolean getHasCommentField() {
+ return hasCommentField;
+ }
+ public void setHasCommentField(boolean hasCommentField) {
+ this.hasCommentField = hasCommentField;
+ }
+
+ public String getNumbering() {
+ return numbering;
+ }
+ public void setNumbering(String numbering) {
+ this.numbering = numbering;
+ }
+
+ public String getAdditionalInformation() {
+ return additionalInformation;
+ }
+ public void setAdditionalInformation(String additionalInformation) {
+ this.additionalInformation = additionalInformation;
+ }
+
+
+ public List getAllField() {
+ return this.getFields() == null ? new ArrayList<>() : this.getFields();
+ }
+
+ public List getFieldById(String id) {
+ return this.getAllField().stream().filter(x-> id.equals(x.getId())).toList();
+ }
+
+ public boolean getHasMultiplicity() {
+ return hasMultiplicity;
+ }
+
+ public void setHasMultiplicity(boolean hasMultiplicity) {
+ this.hasMultiplicity = hasMultiplicity;
+ }
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/MultiplicityEntity.java b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/MultiplicityEntity.java
new file mode 100644
index 000000000..728d817a9
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/MultiplicityEntity.java
@@ -0,0 +1,50 @@
+package org.opencdmp.commons.types.descriptiontemplate;
+
+import jakarta.xml.bind.annotation.XmlAccessType;
+import jakarta.xml.bind.annotation.XmlAccessorType;
+import jakarta.xml.bind.annotation.XmlAttribute;
+
+@XmlAccessorType(XmlAccessType.FIELD)
+public class MultiplicityEntity {
+
+ @XmlAttribute(name="min")
+ private int min;
+ @XmlAttribute(name="max")
+ private int max;
+ @XmlAttribute(name="placeholder")
+ private String placeholder;
+ @XmlAttribute(name="tableView")
+ private boolean tableView;
+
+ public int getMin() {
+ return min;
+ }
+
+ public void setMin(int min) {
+ this.min = min;
+ }
+
+ public int getMax() {
+ return max;
+ }
+
+ public void setMax(int max) {
+ this.max = max;
+ }
+
+ public String getPlaceholder() {
+ return placeholder;
+ }
+
+ public void setPlaceholder(String placeholder) {
+ this.placeholder = placeholder;
+ }
+
+ public boolean getTableView() {
+ return tableView;
+ }
+
+ public void setTableView(boolean tableView) {
+ this.tableView = tableView;
+ }
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/PageEntity.java b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/PageEntity.java
new file mode 100644
index 000000000..0313f713a
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/PageEntity.java
@@ -0,0 +1,74 @@
+package org.opencdmp.commons.types.descriptiontemplate;
+
+import jakarta.xml.bind.annotation.*;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+@XmlAccessorType(XmlAccessType.FIELD)
+public class PageEntity {
+ @XmlAttribute(name="id")
+ private String id;
+ @XmlAttribute(name="ordinal")
+ private int ordinal;
+ @XmlAttribute(name="title")
+ private String title;
+
+ @XmlElementWrapper(name = "sections")
+ @XmlElement(name = "section")
+ private List sections;
+
+ public List getSections() {
+ return sections;
+ }
+
+ public void setSections(List sections) {
+ this.sections = sections;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public int getOrdinal() {
+ return ordinal;
+ }
+
+ public void setOrdinal(int ordinal) {
+ this.ordinal = ordinal;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+
+ public List getAllField(){
+ List fieldEntities = new ArrayList<>();
+ if (this.getSections() != null){
+ for (SectionEntity sectionEntity: this.getSections()) {
+ fieldEntities.addAll(sectionEntity.getAllField());
+ }
+ }
+ return fieldEntities;
+ }
+
+ public List getAllFieldSets(){
+ List fieldSetsEntities = new ArrayList<>();
+ if (this.getSections() != null){
+ for (SectionEntity sectionEntity: this.getSections()) {
+ fieldSetsEntities.addAll(sectionEntity.getAllFieldSets());
+ }
+ }
+ return fieldSetsEntities;
+ }
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/RuleEntity.java b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/RuleEntity.java
new file mode 100644
index 000000000..cbf0c7ddb
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/RuleEntity.java
@@ -0,0 +1,64 @@
+package org.opencdmp.commons.types.descriptiontemplate;
+
+import jakarta.xml.bind.annotation.*;
+
+import java.time.Instant;
+import java.util.List;
+
+@XmlAccessorType(XmlAccessType.FIELD)
+public class RuleEntity {
+ @XmlAttribute(name="target")
+ private String target;
+ @XmlAttribute(name="value")
+ private String textValue;
+
+ @XmlElementWrapper(name = "textListValues")
+ @XmlElement(name = "textListValue")
+ private List textListValue;
+
+ @XmlElement(name = "dateValue")
+ private Instant dateValue;
+ @XmlElement(name="externalIdentifier")
+ private ExternalIdentifierEntity externalIdentifier;
+
+ public String getTarget() {
+ return target;
+ }
+
+ public void setTarget(String target) {
+ this.target = target;
+ }
+
+ public String getTextValue() {
+ return textValue;
+ }
+
+ public void setTextValue(String textValue) {
+ this.textValue = textValue;
+ }
+
+ public List getTextListValue() {
+ return textListValue;
+ }
+
+ public void setTextListValue(List textListValue) {
+ this.textListValue = textListValue;
+ }
+
+ public Instant getDateValue() {
+ return dateValue;
+ }
+
+ public void setDateValue(Instant dateValue) {
+ this.dateValue = dateValue;
+ }
+
+ public ExternalIdentifierEntity getExternalIdentifier() {
+ return externalIdentifier;
+ }
+
+ public void setExternalIdentifier(ExternalIdentifierEntity externalIdentifier) {
+ this.externalIdentifier = externalIdentifier;
+ }
+}
+
diff --git a/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/SectionEntity.java b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/SectionEntity.java
new file mode 100644
index 000000000..87832ad6e
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/SectionEntity.java
@@ -0,0 +1,131 @@
+package org.opencdmp.commons.types.descriptiontemplate;
+
+import jakarta.xml.bind.annotation.*;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@XmlAccessorType(XmlAccessType.FIELD)
+public class SectionEntity{
+ @XmlAttribute(name="id")
+ private String id;
+ @XmlAttribute(name="ordinal")
+ private int ordinal;
+ @XmlAttribute(name="defaultVisibility")
+ private boolean defaultVisibility;
+ @XmlAttribute(name="numbering")
+ private String numbering;
+ @XmlAttribute(name="title")
+ private String title;
+ @XmlAttribute(name="description")
+ private String description;
+ @XmlAttribute(name="extendedDescription")
+ private String extendedDescription;
+
+ @XmlElementWrapper(name = "sections")
+ @XmlElement(name = "section")
+ private List sections;
+ @XmlElementWrapper(name = "fieldSets")
+ @XmlElement(name = "fieldSet")
+ private List fieldSets;
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public int getOrdinal() {
+ return ordinal;
+ }
+
+ public void setOrdinal(int ordinal) {
+ this.ordinal = ordinal;
+ }
+
+ public boolean isDefaultVisibility() {
+ return defaultVisibility;
+ }
+
+ public void setDefaultVisibility(boolean defaultVisibility) {
+ this.defaultVisibility = defaultVisibility;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public List getSections() {
+ return sections;
+ }
+
+ public void setSections(List sections) {
+ this.sections = sections;
+ }
+
+ public List getFieldSets() {
+ return fieldSets;
+ }
+
+ public void setFieldSets(List fieldSetEntities) {
+ this.fieldSets = fieldSetEntities;
+ }
+
+ public String getExtendedDescription() {
+ return extendedDescription;
+ }
+
+ public void setExtendedDescription(String extendedDescription) {
+ this.extendedDescription = extendedDescription;
+ }
+
+ public String getNumbering() {
+ return numbering;
+ }
+
+ public void setNumbering(String numbering) {
+ this.numbering = numbering;
+ }
+
+ public List getAllField(){
+ List fieldEntities = new ArrayList<>();
+ if (this.getFieldSets() != null){
+ for (FieldSetEntity fieldSetEntity: this.getFieldSets()) {
+ fieldEntities.addAll(fieldSetEntity.getAllField());
+ }
+ }
+ if (this.getSections() != null){
+ for (SectionEntity sectionEntity: this.getSections()) {
+ fieldEntities.addAll(sectionEntity.getAllField());
+ }
+ }
+ return fieldEntities;
+ }
+
+ public List getAllFieldSets(){
+ List fieldSetEntities = new ArrayList<>();
+ if (this.getFieldSets() != null){
+ fieldSetEntities.addAll(this.getFieldSets());
+ }
+ if (this.getSections() != null){
+ for (SectionEntity sectionEntity: this.getSections()) {
+ fieldSetEntities.addAll(sectionEntity.getAllFieldSets());
+ }
+ }
+ return fieldSetEntities;
+ }
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/fielddata/BaseFieldDataEntity.java b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/fielddata/BaseFieldDataEntity.java
new file mode 100644
index 000000000..73b41e33f
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/fielddata/BaseFieldDataEntity.java
@@ -0,0 +1,32 @@
+package org.opencdmp.commons.types.descriptiontemplate.fielddata;
+
+import org.opencdmp.commons.enums.FieldType;
+import jakarta.xml.bind.annotation.XmlAccessType;
+import jakarta.xml.bind.annotation.XmlAccessorType;
+import jakarta.xml.bind.annotation.XmlAttribute;
+
+
+@XmlAccessorType(XmlAccessType.FIELD)
+public abstract class BaseFieldDataEntity {
+
+ @XmlAttribute(name = "label")
+ private String label;
+ @XmlAttribute(name = "fieldType")
+ private FieldType fieldType;
+
+ public String getLabel() {
+ return label;
+ }
+
+ public void setLabel(String label) {
+ this.label = label;
+ }
+
+ public FieldType getFieldType() {
+ return fieldType;
+ }
+
+ public void setFieldType(FieldType fieldType) {
+ this.fieldType = fieldType;
+ }
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/fielddata/LabelAndMultiplicityDataEntity.java b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/fielddata/LabelAndMultiplicityDataEntity.java
new file mode 100644
index 000000000..c419e11af
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/fielddata/LabelAndMultiplicityDataEntity.java
@@ -0,0 +1,21 @@
+package org.opencdmp.commons.types.descriptiontemplate.fielddata;
+
+import jakarta.xml.bind.annotation.XmlAccessType;
+import jakarta.xml.bind.annotation.XmlAccessorType;
+import jakarta.xml.bind.annotation.XmlAttribute;
+
+@XmlAccessorType(XmlAccessType.FIELD)
+public class LabelAndMultiplicityDataEntity extends BaseFieldDataEntity {
+ public static final String XmlElementName = "labelAndMultiplicityData";
+
+ @XmlAttribute(name = "multipleSelect")
+ private Boolean multipleSelect;
+
+ public Boolean getMultipleSelect() {
+ return multipleSelect;
+ }
+
+ public void setMultipleSelect(Boolean multipleSelect) {
+ this.multipleSelect = multipleSelect;
+ }
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/fielddata/LabelDataEntity.java b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/fielddata/LabelDataEntity.java
new file mode 100644
index 000000000..4b3fa23f2
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/fielddata/LabelDataEntity.java
@@ -0,0 +1,10 @@
+package org.opencdmp.commons.types.descriptiontemplate.fielddata;
+
+import jakarta.xml.bind.annotation.XmlAccessType;
+import jakarta.xml.bind.annotation.XmlAccessorType;
+
+
+@XmlAccessorType(XmlAccessType.FIELD)
+public class LabelDataEntity extends BaseFieldDataEntity {
+ public static final String XmlElementName = "labelData";
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/fielddata/RadioBoxDataEntity.java b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/fielddata/RadioBoxDataEntity.java
new file mode 100644
index 000000000..4cbffa500
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/fielddata/RadioBoxDataEntity.java
@@ -0,0 +1,45 @@
+package org.opencdmp.commons.types.descriptiontemplate.fielddata;
+
+import jakarta.xml.bind.annotation.*;
+
+import java.util.List;
+
+@XmlAccessorType(XmlAccessType.FIELD)
+public class RadioBoxDataEntity extends BaseFieldDataEntity {
+ public static final String XmlElementName = "radioBoxData";
+ @XmlAccessorType(XmlAccessType.FIELD)
+ public static class RadioBoxDataOptionEntity {
+ @XmlAttribute(name="label")
+ private String label;
+ @XmlAttribute(name="value")
+ private String value;
+
+ public String getLabel() {
+ return label;
+ }
+
+ public void setLabel(String label) {
+ this.label = label;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public void setValue(String value) {
+ this.value = value;
+ }
+ }
+
+ @XmlElementWrapper(name = "options")
+ @XmlElement(name = "option")
+ private List options;
+
+ public List getOptions() {
+ return options;
+ }
+
+ public void setOptions(List options) {
+ this.options = options;
+ }
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/fielddata/ReferenceTypeDataEntity.java b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/fielddata/ReferenceTypeDataEntity.java
new file mode 100644
index 000000000..b7dd20e5f
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/fielddata/ReferenceTypeDataEntity.java
@@ -0,0 +1,33 @@
+package org.opencdmp.commons.types.descriptiontemplate.fielddata;
+
+import jakarta.xml.bind.annotation.XmlAccessType;
+import jakarta.xml.bind.annotation.XmlAccessorType;
+import jakarta.xml.bind.annotation.XmlAttribute;
+
+import java.util.UUID;
+
+@XmlAccessorType(XmlAccessType.FIELD)
+public class ReferenceTypeDataEntity extends BaseFieldDataEntity {
+ public static final String XmlElementName = "referenceTypeData";
+
+ @XmlAttribute(name = "multipleSelect")
+ private Boolean multipleSelect;
+
+ @XmlAttribute(name = "referenceTypeId")
+ private UUID referenceTypeId;
+ public Boolean getMultipleSelect() {
+ return multipleSelect;
+ }
+
+ public void setMultipleSelect(Boolean multipleSelect) {
+ this.multipleSelect = multipleSelect;
+ }
+
+ public UUID getReferenceTypeId() {
+ return referenceTypeId;
+ }
+
+ public void setReferenceTypeId(UUID referenceTypeId) {
+ this.referenceTypeId = referenceTypeId;
+ }
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/fielddata/SelectDataEntity.java b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/fielddata/SelectDataEntity.java
new file mode 100644
index 000000000..39d0d0f84
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/fielddata/SelectDataEntity.java
@@ -0,0 +1,44 @@
+package org.opencdmp.commons.types.descriptiontemplate.fielddata;
+
+import jakarta.xml.bind.annotation.*;
+
+import java.util.List;
+
+@XmlAccessorType(XmlAccessType.FIELD)
+public class SelectDataEntity extends LabelAndMultiplicityDataEntity {
+ public static final String XmlElementName = "selectData";
+ @XmlElementWrapper(name = "options")
+ @XmlElement(name = "options")
+ private List options;
+
+ public List getOptions() {
+ return options;
+ }
+
+ public void setOptions(List optionEntities) {
+ this.options = optionEntities;
+ }
+
+ @XmlAccessorType(XmlAccessType.FIELD)
+ public static class OptionEntity {
+ @XmlAttribute(name="label")
+ private String label;
+ @XmlAttribute(name="value")
+ private String value;
+
+ public String getLabel() {
+ return label;
+ }
+ public void setLabel(String label) {
+ this.label = label;
+ }
+
+ public String getValue() {
+ return value;
+ }
+ public void setValue(String value) {
+ this.value = value;
+ }
+ }
+}
+
diff --git a/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/fielddata/UploadDataEntity.java b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/fielddata/UploadDataEntity.java
new file mode 100644
index 000000000..4498c3df7
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/fielddata/UploadDataEntity.java
@@ -0,0 +1,59 @@
+package org.opencdmp.commons.types.descriptiontemplate.fielddata;
+
+import jakarta.xml.bind.annotation.*;
+
+import java.util.List;
+
+
+@XmlAccessorType(XmlAccessType.FIELD)
+public class UploadDataEntity extends BaseFieldDataEntity {
+ public static final String XmlElementName = "uploadData";
+
+ @XmlAccessorType(XmlAccessType.FIELD)
+ public static class UploadDataOptionEntity {
+ @XmlAttribute(name="label")
+ private String label;
+ @XmlAttribute(name="value")
+ private String value;
+
+ public String getLabel() {
+ return label;
+ }
+
+ public void setLabel(String label) {
+ this.label = label;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public void setValue(String value) {
+ this.value = value;
+ }
+ }
+
+ @XmlElementWrapper(name = "types")
+ @XmlElement(name = "type")
+ private List types;
+
+ @XmlAttribute(name="maxFileSizeInMB")
+ private Integer maxFileSizeInMB;
+
+
+ public List getTypes() {
+ return types;
+ }
+
+ public void setTypes(List types) {
+ this.types = types;
+ }
+
+ public Integer getMaxFileSizeInMB() {
+ return maxFileSizeInMB;
+ }
+
+ public void setMaxFileSizeInMB(Integer maxFileSizeInMB) {
+ this.maxFileSizeInMB = maxFileSizeInMB;
+ }
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/importexport/DescriptionTemplateImportExport.java b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/importexport/DescriptionTemplateImportExport.java
new file mode 100644
index 000000000..f6ac730e1
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/importexport/DescriptionTemplateImportExport.java
@@ -0,0 +1,66 @@
+package org.opencdmp.commons.types.descriptiontemplate.importexport;
+
+
+import org.opencdmp.commons.enums.DescriptionTemplateStatus;
+
+import org.opencdmp.model.persist.DescriptionTemplatePersist;
+import org.opencdmp.model.persist.NewVersionDescriptionTemplatePersist;
+import org.opencdmp.model.persist.descriptiontemplatedefinition.DefinitionPersist;
+import org.opencdmp.model.persist.descriptiontemplatedefinition.PagePersist;
+import org.opencdmp.model.persist.descriptiontemplatedefinition.SectionPersist;
+import org.opencdmp.service.fielddatahelper.FieldDataHelperServiceProvider;
+import jakarta.xml.bind.annotation.*;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.UUID;
+
+@XmlRootElement(name = "root")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class DescriptionTemplateImportExport {
+ @XmlAttribute(name = "description")
+ private String description;
+ @XmlAttribute(name = "language")
+ private String language;
+ @XmlAttribute(name = "type")
+ private UUID type;
+ @XmlElementWrapper(name = "pages")
+ @XmlElement(name = "page")
+ private List pages;
+
+
+ public List getPages() {
+ return pages;
+ }
+
+ public void setPages(List pages) {
+ this.pages = pages;
+ }
+
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+
+ public String getLanguage() {
+ return language;
+ }
+
+ public void setLanguage(String language) {
+ this.language = language;
+ }
+
+
+ public UUID getType() {
+ return type;
+ }
+
+ public void setType(UUID type) {
+ this.type = type;
+ }
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/importexport/ExternalIdentifierImportExport.java b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/importexport/ExternalIdentifierImportExport.java
new file mode 100644
index 000000000..e78d8606b
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/importexport/ExternalIdentifierImportExport.java
@@ -0,0 +1,32 @@
+package org.opencdmp.commons.types.descriptiontemplate.importexport;
+
+import jakarta.xml.bind.annotation.XmlAccessType;
+import jakarta.xml.bind.annotation.XmlAccessorType;
+import jakarta.xml.bind.annotation.XmlAttribute;
+
+@XmlAccessorType(XmlAccessType.FIELD)
+public class ExternalIdentifierImportExport {
+
+ @XmlAttribute(name="identifier")
+ private String identifier;
+
+ @XmlAttribute(name="type")
+ private String type;
+
+ public String getIdentifier() {
+ return identifier;
+ }
+
+ public void setIdentifier(String identifier) {
+ this.identifier = identifier;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/importexport/FieldImportExport.java b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/importexport/FieldImportExport.java
new file mode 100644
index 000000000..483811a79
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/importexport/FieldImportExport.java
@@ -0,0 +1,122 @@
+package org.opencdmp.commons.types.descriptiontemplate.importexport;
+
+import org.opencdmp.commons.enums.FieldType;
+import org.opencdmp.commons.enums.FieldValidationType;
+import org.opencdmp.commons.types.descriptiontemplate.importexport.fielddata.*;
+import jakarta.xml.bind.annotation.*;
+
+import java.util.List;
+
+@XmlAccessorType(XmlAccessType.FIELD)
+public class FieldImportExport {
+
+ @XmlAttribute(name = "id")
+ private String id;
+
+ @XmlAttribute(name = "ordinal")
+ private int ordinal;
+
+ @XmlElement(name = "numbering")
+ private String numbering;
+
+ @XmlElementWrapper(name = "validations")
+ @XmlElement(name = "validation")
+ private List validations;
+
+ @XmlElement(name = "defaultValue")
+ private String defaultValue;
+
+ @XmlElementWrapper(name = "visibilityRules")
+ @XmlElement(name = "visibilityRule")
+ private List visibilityRules;
+
+ @XmlElement(name = "fieldType")
+ private FieldType fieldType;
+
+ @XmlElements({
+ @XmlElement(name = LabelDataImportExport.XmlElementName, type = LabelDataImportExport.class),
+ @XmlElement(name = LabelAndMultiplicityDataImportExport.XmlElementName, type = LabelAndMultiplicityDataImportExport.class),
+ @XmlElement(name = UploadDataImportExport.XmlElementName, type = UploadDataImportExport.class),
+ @XmlElement(name = RadioBoxDataImportExport.XmlElementName, type = RadioBoxDataImportExport.class),
+ @XmlElement(name = SelectDataImportExport.XmlElementName, type = SelectDataImportExport.class),
+ @XmlElement(name = ReferenceTypeDataImportExport.XmlElementName, type = ReferenceTypeDataImportExport.class),
+ })
+ private BaseFieldDataImportExport data;
+
+ @XmlElementWrapper(name = "schematics")
+ @XmlElement(name = "schematic")
+ private List schematics;
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public int getOrdinal() {
+ return ordinal;
+ }
+
+ public void setOrdinal(int ordinal) {
+ this.ordinal = ordinal;
+ }
+
+ public String getNumbering() {
+ return numbering;
+ }
+
+ public void setNumbering(String numbering) {
+ this.numbering = numbering;
+ }
+
+ public String getDefaultValue() {
+ return defaultValue;
+ }
+
+ public void setDefaultValue(String defaultValue) {
+ this.defaultValue = defaultValue;
+ }
+
+ public FieldType getFieldType() {
+ return fieldType;
+ }
+
+ public void setFieldType(FieldType fieldType) {
+ this.fieldType = fieldType;
+ }
+
+ public BaseFieldDataImportExport getData() {
+ return this.data;
+ }
+
+ public void setData(BaseFieldDataImportExport data) {
+ this.data = data;
+ }
+
+ public List getValidations() {
+ return validations;
+ }
+
+ public void setValidations(List validations) {
+ this.validations = validations;
+ }
+
+ public List getSchematics() {
+ return schematics;
+ }
+
+ public void setSchematics(List schematics) {
+ this.schematics = schematics;
+ }
+
+ public List getVisibilityRules() {
+ return visibilityRules;
+ }
+
+ public void setVisibilityRules(List visibilityRules) {
+ this.visibilityRules = visibilityRules;
+ }
+
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/importexport/FieldSetImportExport.java b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/importexport/FieldSetImportExport.java
new file mode 100644
index 000000000..da8914ed7
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/importexport/FieldSetImportExport.java
@@ -0,0 +1,122 @@
+package org.opencdmp.commons.types.descriptiontemplate.importexport;
+
+import jakarta.xml.bind.annotation.*;
+
+import java.util.List;
+
+@XmlAccessorType(XmlAccessType.FIELD)
+public class FieldSetImportExport {
+
+ @XmlAttribute(name="id")
+ private String id;
+ @XmlAttribute(name="ordinal")
+ private int ordinal;
+
+ @XmlElementWrapper(name = "fields")
+ @XmlElement(name = "field")
+ private List fields;
+ @XmlAttribute(name="numbering")
+ private String numbering;
+ @XmlAttribute(name="title")
+ private String title;
+ @XmlAttribute(name="description")
+ private String description;
+ @XmlAttribute(name="extendedDescription")
+ private String extendedDescription;
+ @XmlAttribute(name="additionalInformation")
+ private String additionalInformation;
+ @XmlElement(name="multiplicity")
+ private MultiplicityImportExport multiplicity;
+
+ @XmlAttribute(name="hasMultiplicity")
+ private boolean hasMultiplicity;
+ @XmlAttribute(name="hasCommentField")
+ private Boolean hasCommentField;
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public int getOrdinal() {
+ return ordinal;
+ }
+
+ public void setOrdinal(int ordinal) {
+ this.ordinal = ordinal;
+ }
+
+ public List getFields() {
+ return fields;
+ }
+
+ public void setFields(List fields) {
+ this.fields = fields;
+ }
+
+ public String getNumbering() {
+ return numbering;
+ }
+
+ public void setNumbering(String numbering) {
+ this.numbering = numbering;
+ }
+
+ public Boolean getHasCommentField() {
+ return hasCommentField;
+ }
+ public void setHasCommentField(Boolean hasCommentField) {
+ this.hasCommentField = hasCommentField;
+ }
+
+ public MultiplicityImportExport getMultiplicity() {
+ return multiplicity;
+ }
+
+ public void setMultiplicity(MultiplicityImportExport multiplicity) {
+ this.multiplicity = multiplicity;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public String getExtendedDescription() {
+ return extendedDescription;
+ }
+
+ public void setExtendedDescription(String extendedDescription) {
+ this.extendedDescription = extendedDescription;
+ }
+
+ public String getAdditionalInformation() {
+ return additionalInformation;
+ }
+
+ public void setAdditionalInformation(String additionalInformation) {
+ this.additionalInformation = additionalInformation;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public boolean getHasMultiplicity() {
+ return hasMultiplicity;
+ }
+
+ public void setHasMultiplicity(boolean hasMultiplicity) {
+ this.hasMultiplicity = hasMultiplicity;
+ }
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/importexport/MultiplicityImportExport.java b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/importexport/MultiplicityImportExport.java
new file mode 100644
index 000000000..a73e64fde
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/importexport/MultiplicityImportExport.java
@@ -0,0 +1,51 @@
+package org.opencdmp.commons.types.descriptiontemplate.importexport;
+
+import jakarta.xml.bind.annotation.XmlAccessType;
+import jakarta.xml.bind.annotation.XmlAccessorType;
+import jakarta.xml.bind.annotation.XmlAttribute;
+
+
+@XmlAccessorType(XmlAccessType.FIELD)
+public class MultiplicityImportExport {
+ @XmlAttribute(name="min")
+ private int min;
+ @XmlAttribute(name="max")
+ private int max;
+ @XmlAttribute(name="placeholder")
+ private String placeholder;
+ @XmlAttribute(name="tableView")
+ private boolean tableView;
+
+ public int getMin() {
+ return min;
+ }
+
+ public void setMin(int min) {
+ this.min = min;
+ }
+
+ public int getMax() {
+ return max;
+ }
+
+ public void setMax(int max) {
+ this.max = max;
+ }
+
+ public String getPlaceholder() {
+ return placeholder;
+ }
+
+ public void setPlaceholder(String placeholder) {
+ this.placeholder = placeholder;
+ }
+
+ public boolean getTableView() {
+ return tableView;
+ }
+
+ public void setTableView(boolean tableView) {
+ this.tableView = tableView;
+ }
+
+}
\ No newline at end of file
diff --git a/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/importexport/PageImportExport.java b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/importexport/PageImportExport.java
new file mode 100644
index 000000000..eecb3fa9c
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/importexport/PageImportExport.java
@@ -0,0 +1,55 @@
+package org.opencdmp.commons.types.descriptiontemplate.importexport;
+
+import org.opencdmp.model.persist.descriptiontemplatedefinition.PagePersist;
+import org.opencdmp.model.persist.descriptiontemplatedefinition.SectionPersist;
+import org.opencdmp.service.fielddatahelper.FieldDataHelperServiceProvider;
+import jakarta.xml.bind.annotation.*;
+
+import java.util.List;
+
+@XmlAccessorType(XmlAccessType.FIELD)
+public class PageImportExport {
+ @XmlAttribute(name = "id")
+ private String id;
+ @XmlAttribute(name = "ordinal")
+ private int ordinal;
+
+ @XmlAttribute(name = "title")
+ private String title;
+ @XmlElementWrapper(name = "sections")
+ @XmlElement(name = "section")
+ private List sections;
+
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public int getOrdinal() {
+ return ordinal;
+ }
+
+ public void setOrdinal(int ordinal) {
+ this.ordinal = ordinal;
+ }
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public List getSections() {
+ return sections;
+ }
+
+ public void setSections(List sections) {
+ this.sections = sections;
+ }
+
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/importexport/RuleImportExport.java b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/importexport/RuleImportExport.java
new file mode 100644
index 000000000..05125f3d2
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/importexport/RuleImportExport.java
@@ -0,0 +1,64 @@
+package org.opencdmp.commons.types.descriptiontemplate.importexport;
+
+import jakarta.xml.bind.annotation.*;
+
+import java.time.Instant;
+import java.util.List;
+
+@XmlAccessorType(XmlAccessType.FIELD)
+public class RuleImportExport {
+
+ @XmlAttribute(name="target")
+ private String target;
+ @XmlAttribute(name="value")
+ private String textValue;
+
+ @XmlElementWrapper(name = "textListValues")
+ @XmlElement(name = "textListValue")
+ private List textListValue;
+ @XmlElement(name = "dateValue")
+ private Instant dateValue;
+
+ @XmlElement(name="externalIdentifier")
+ private ExternalIdentifierImportExport externalIdentifier;
+
+ public String getTarget() {
+ return target;
+ }
+
+ public void setTarget(String target) {
+ this.target = target;
+ }
+
+ public String getTextValue() {
+ return textValue;
+ }
+
+ public void setTextValue(String textValue) {
+ this.textValue = textValue;
+ }
+
+ public List getTextListValue() {
+ return textListValue;
+ }
+
+ public void setTextListValue(List textListValue) {
+ this.textListValue = textListValue;
+ }
+
+ public Instant getDateValue() {
+ return dateValue;
+ }
+
+ public void setDateValue(Instant dateValue) {
+ this.dateValue = dateValue;
+ }
+
+ public ExternalIdentifierImportExport getExternalIdentifier() {
+ return externalIdentifier;
+ }
+
+ public void setExternalIdentifier(ExternalIdentifierImportExport externalIdentifier) {
+ this.externalIdentifier = externalIdentifier;
+ }
+}
\ No newline at end of file
diff --git a/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/importexport/SectionImportExport.java b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/importexport/SectionImportExport.java
new file mode 100644
index 000000000..afcb35924
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/importexport/SectionImportExport.java
@@ -0,0 +1,102 @@
+package org.opencdmp.commons.types.descriptiontemplate.importexport;
+
+import jakarta.xml.bind.annotation.*;
+
+import java.util.List;
+
+@XmlAccessorType(XmlAccessType.FIELD)
+public class SectionImportExport {
+ @XmlAttribute(name = "id")
+ private String id;
+ @XmlAttribute(name = "ordinal")
+ private int ordinal;
+ @XmlAttribute(name = "defaultVisibility")
+ private Boolean defaultVisibility;
+ @XmlElementWrapper(name = "fieldSets")
+ @XmlElement(name = "fieldSet")
+ private List fieldSets;
+ @XmlElement(name = "numbering")
+ private String numbering;
+ @XmlElement(name = "description")
+ private String description;
+ @XmlElement(name = "title")
+ private String title;
+ @XmlElementWrapper(name = "sections")
+ @XmlElement(name = "section")
+ private List sections;
+ @XmlAttribute(name = "multiplicity")
+ private Boolean multiplicity;
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public int getOrdinal() {
+ return ordinal;
+ }
+
+ public void setOrdinal(int ordinal) {
+ this.ordinal = ordinal;
+ }
+
+ public Boolean getDefaultVisibility() {
+ return defaultVisibility;
+ }
+
+ public void setDefaultVisibility(Boolean defaultVisibility) {
+ this.defaultVisibility = defaultVisibility;
+ }
+
+ public List getFieldSets() {
+ return fieldSets;
+ }
+
+ public void setFieldSets(List fieldSets) {
+ this.fieldSets = fieldSets;
+ }
+
+ public String getNumbering() {
+ return numbering;
+ }
+
+ public void setNumbering(String numbering) {
+ this.numbering = numbering;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public List getSections() {
+ return sections;
+ }
+
+ public void setSections(List sections) {
+ this.sections = sections;
+ }
+
+ public Boolean getMultiplicity() {
+ return multiplicity;
+ }
+
+ public void setMultiplicity(Boolean multiplicity) {
+ this.multiplicity = multiplicity;
+ }
+
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/importexport/fielddata/BaseFieldDataImportExport.java b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/importexport/fielddata/BaseFieldDataImportExport.java
new file mode 100644
index 000000000..281767a9b
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/importexport/fielddata/BaseFieldDataImportExport.java
@@ -0,0 +1,30 @@
+package org.opencdmp.commons.types.descriptiontemplate.importexport.fielddata;
+
+import org.opencdmp.commons.enums.FieldType;
+import jakarta.xml.bind.annotation.XmlAccessType;
+import jakarta.xml.bind.annotation.XmlAccessorType;
+import jakarta.xml.bind.annotation.XmlAttribute;
+
+@XmlAccessorType(XmlAccessType.FIELD)
+public abstract class BaseFieldDataImportExport {
+ @XmlAttribute(name = "label")
+ private String label;
+ @XmlAttribute(name = "fieldType")
+ private FieldType fieldType;
+
+ public String getLabel() {
+ return label;
+ }
+
+ public void setLabel(String label) {
+ this.label = label;
+ }
+
+ public FieldType getFieldType() {
+ return fieldType;
+ }
+
+ public void setFieldType(FieldType fieldType) {
+ this.fieldType = fieldType;
+ }
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/importexport/fielddata/LabelAndMultiplicityDataImportExport.java b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/importexport/fielddata/LabelAndMultiplicityDataImportExport.java
new file mode 100644
index 000000000..ad4a17fda
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/importexport/fielddata/LabelAndMultiplicityDataImportExport.java
@@ -0,0 +1,23 @@
+package org.opencdmp.commons.types.descriptiontemplate.importexport.fielddata;
+
+import jakarta.xml.bind.annotation.XmlAccessType;
+import jakarta.xml.bind.annotation.XmlAccessorType;
+import jakarta.xml.bind.annotation.XmlAttribute;
+
+@XmlAccessorType(XmlAccessType.FIELD)
+public class LabelAndMultiplicityDataImportExport extends BaseFieldDataImportExport {
+ public static final String XmlElementName = "labelAndMultiplicityData";
+
+ @XmlAttribute(name = "multipleSelect")
+ private Boolean multipleSelect;
+
+ public Boolean getMultipleSelect() {
+ return multipleSelect;
+ }
+
+ public void setMultipleSelect(Boolean multipleSelect) {
+ this.multipleSelect = multipleSelect;
+ }
+
+}
+
diff --git a/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/importexport/fielddata/LabelDataImportExport.java b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/importexport/fielddata/LabelDataImportExport.java
new file mode 100644
index 000000000..7bee61ddc
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/importexport/fielddata/LabelDataImportExport.java
@@ -0,0 +1,10 @@
+package org.opencdmp.commons.types.descriptiontemplate.importexport.fielddata;
+
+import jakarta.xml.bind.annotation.XmlAccessType;
+import jakarta.xml.bind.annotation.XmlAccessorType;
+
+@XmlAccessorType(XmlAccessType.FIELD)
+public class LabelDataImportExport extends BaseFieldDataImportExport {
+ public static final String XmlElementName = "labelData";
+
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/importexport/fielddata/RadioBoxDataImportExport.java b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/importexport/fielddata/RadioBoxDataImportExport.java
new file mode 100644
index 000000000..6b1c926ab
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/importexport/fielddata/RadioBoxDataImportExport.java
@@ -0,0 +1,47 @@
+package org.opencdmp.commons.types.descriptiontemplate.importexport.fielddata;
+
+import jakarta.xml.bind.annotation.*;
+
+import java.util.List;
+
+@XmlAccessorType(XmlAccessType.FIELD)
+public class RadioBoxDataImportExport extends BaseFieldDataImportExport {
+ public static final String XmlElementName = "radioBoxData";
+
+ @XmlElementWrapper(name = "options")
+ @XmlElement(name = "option")
+ private List options;
+
+ public List getOptions() {
+ return options;
+ }
+
+ public void setOptions(List options) {
+ this.options = options;
+ }
+
+ @XmlAccessorType(XmlAccessType.FIELD)
+ public static class RadioBoxOption {
+ @XmlAttribute(name = "label")
+ private String label;
+ @XmlAttribute(name = "value")
+ private String value;
+
+ public String getLabel() {
+ return label;
+ }
+
+ public void setLabel(String label) {
+ this.label = label;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public void setValue(String value) {
+ this.value = value;
+ }
+ }
+}
+
diff --git a/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/importexport/fielddata/ReferenceTypeDataImportExport.java b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/importexport/fielddata/ReferenceTypeDataImportExport.java
new file mode 100644
index 000000000..e3c00cecd
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/importexport/fielddata/ReferenceTypeDataImportExport.java
@@ -0,0 +1,34 @@
+package org.opencdmp.commons.types.descriptiontemplate.importexport.fielddata;
+
+import jakarta.xml.bind.annotation.XmlAccessType;
+import jakarta.xml.bind.annotation.XmlAccessorType;
+import jakarta.xml.bind.annotation.XmlAttribute;
+
+import java.util.UUID;
+
+@XmlAccessorType(XmlAccessType.FIELD)
+public class ReferenceTypeDataImportExport extends BaseFieldDataImportExport {
+ public static final String XmlElementName = "labelAndMultiplicityData";
+
+ @XmlAttribute(name = "multipleSelect")
+ private Boolean multipleSelect;
+
+ @XmlAttribute(name = "referenceTypeId")
+ private UUID referenceTypeId;
+
+ public Boolean getMultipleSelect() {
+ return multipleSelect;
+ }
+
+ public void setMultipleSelect(Boolean multipleSelect) {
+ this.multipleSelect = multipleSelect;
+ }
+
+ public UUID getReferenceTypeId() {
+ return referenceTypeId;
+ }
+
+ public void setReferenceTypeId(UUID referenceTypeId) {
+ this.referenceTypeId = referenceTypeId;
+ }
+}
diff --git a/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/importexport/fielddata/SelectDataImportExport.java b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/importexport/fielddata/SelectDataImportExport.java
new file mode 100644
index 000000000..caa009f1e
--- /dev/null
+++ b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/importexport/fielddata/SelectDataImportExport.java
@@ -0,0 +1,45 @@
+package org.opencdmp.commons.types.descriptiontemplate.importexport.fielddata;
+
+import jakarta.xml.bind.annotation.*;
+
+import java.util.List;
+
+@XmlAccessorType(XmlAccessType.FIELD)
+public class SelectDataImportExport extends LabelAndMultiplicityDataImportExport {
+ public static final String XmlElementName = "selectData";
+ @XmlElementWrapper(name = "options")
+ @XmlElement(name = "options")
+ private List