diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/criteria/DataManagementPlanPublicCriteria.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/criteria/DataManagementPlanPublicCriteria.java index bd3d049bf..edc1ffa9f 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/dao/criteria/DataManagementPlanPublicCriteria.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/criteria/DataManagementPlanPublicCriteria.java @@ -11,6 +11,7 @@ public class DataManagementPlanPublicCriteria extends Criteria { private List grants; public List datasetProfile; private List dmpOrganisations; + private Integer role; public GrantStateType getGrantStatus() { return grantStatus; @@ -39,4 +40,11 @@ public class DataManagementPlanPublicCriteria extends Criteria { public void setDmpOrganisations(List dmpOrganisations) { this.dmpOrganisations = dmpOrganisations; } + + public Integer getRole() { + return role; + } + public void setRole(Integer role) { + this.role = role; + } } diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/criteria/DataRepositoryCriteria.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/criteria/DataRepositoryCriteria.java index f66eb8b3e..ecd577308 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/dao/criteria/DataRepositoryCriteria.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/criteria/DataRepositoryCriteria.java @@ -2,6 +2,16 @@ package eu.eudat.data.dao.criteria; import eu.eudat.data.entities.DataRepository; +import java.util.UUID; + public class DataRepositoryCriteria extends Criteria { + private UUID creationUserId; + + public UUID getCreationUserId() { + return creationUserId; + } + public void setCreationUserId(UUID creationUserId) { + this.creationUserId = creationUserId; + } } diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/criteria/DatasetPublicCriteria.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/criteria/DatasetPublicCriteria.java index fd4934d7a..9554ed5b4 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/dao/criteria/DatasetPublicCriteria.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/criteria/DatasetPublicCriteria.java @@ -17,6 +17,7 @@ public class DatasetPublicCriteria extends Criteria{ private List dmpOrganisations; private List tags; private List dmpIds; + private Integer role; public GrantStateType getGrantStatus() { return grantStatus; @@ -59,4 +60,11 @@ public class DatasetPublicCriteria extends Criteria{ public void setDmpIds(List dmpIds) { this.dmpIds = dmpIds; } + + public Integer getRole() { + return role; + } + public void setRole(Integer role) { + this.role = role; + } } diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/criteria/ExternalDatasetCriteria.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/criteria/ExternalDatasetCriteria.java index f2e775366..a5a6275e8 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/dao/criteria/ExternalDatasetCriteria.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/criteria/ExternalDatasetCriteria.java @@ -1,7 +1,15 @@ package eu.eudat.data.dao.criteria; - import eu.eudat.data.entities.ExternalDataset; +import java.util.UUID; public class ExternalDatasetCriteria extends Criteria { + private UUID creationUserId; + + public UUID getCreationUserId() { + return creationUserId; + } + public void setCreationUserId(UUID creationUserId) { + this.creationUserId = creationUserId; + } } diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/criteria/RegistryCriteria.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/criteria/RegistryCriteria.java index 44b890887..186f5e281 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/dao/criteria/RegistryCriteria.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/criteria/RegistryCriteria.java @@ -2,6 +2,16 @@ package eu.eudat.data.dao.criteria; import eu.eudat.data.entities.Registry; +import java.util.UUID; + public class RegistryCriteria extends Criteria { + private UUID creationUserId; + + public UUID getCreationUserId() { + return creationUserId; + } + public void setCreationUserId(UUID creationUserId) { + this.creationUserId = creationUserId; + } } diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/criteria/ServiceCriteria.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/criteria/ServiceCriteria.java index d7aeccac4..715511fb3 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/dao/criteria/ServiceCriteria.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/criteria/ServiceCriteria.java @@ -2,6 +2,16 @@ package eu.eudat.data.dao.criteria; import eu.eudat.data.entities.Service; +import java.util.UUID; + public class ServiceCriteria extends Criteria { + private UUID creationUserId; + + public UUID getCreationUserId() { + return creationUserId; + } + public void setCreationUserId(UUID creationUserId) { + this.creationUserId = creationUserId; + } } diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DMPDao.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DMPDao.java index 03cf68d74..3073e1857 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DMPDao.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DMPDao.java @@ -8,6 +8,7 @@ import eu.eudat.data.entities.UserDMP; import eu.eudat.data.entities.UserInfo; import eu.eudat.queryable.QueryableList; +import java.util.List; import java.util.UUID; public interface DMPDao extends DatabaseAccessLayer { @@ -16,6 +17,6 @@ public interface DMPDao extends DatabaseAccessLayer { QueryableList getUserDmps(DatasetWizardUserDmpCriteria datasetWizardAutocompleteRequest, UserInfo userInfo); - QueryableList getAuthenticated(QueryableList query, UUID principalId); + QueryableList getAuthenticated(QueryableList query, UUID principalId, List roles); } \ No newline at end of file diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DMPDaoImpl.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DMPDaoImpl.java index 9684373a5..e1c92d6d8 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DMPDaoImpl.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DMPDaoImpl.java @@ -5,7 +5,6 @@ import eu.eudat.data.dao.criteria.DataManagementPlanCriteria; import eu.eudat.data.dao.criteria.DatasetWizardUserDmpCriteria; import eu.eudat.data.dao.databaselayer.service.DatabaseService; import eu.eudat.data.entities.DMP; -import eu.eudat.data.entities.UserDMP; import eu.eudat.data.entities.UserInfo; import eu.eudat.queryable.QueryableList; import eu.eudat.queryable.types.FieldSelectionType; @@ -14,110 +13,119 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Component; +import javax.persistence.criteria.Join; import javax.persistence.criteria.JoinType; import java.util.Arrays; +import java.util.List; import java.util.UUID; import java.util.concurrent.CompletableFuture; @Component("dMPDao") public class DMPDaoImpl extends DatabaseAccess implements DMPDao { + @Autowired + public DMPDaoImpl(DatabaseService databaseService) { + super(databaseService); + } - @Autowired - public DMPDaoImpl(DatabaseService databaseService) { - super(databaseService); - } - - @Override - public QueryableList getWithCriteria(DataManagementPlanCriteria criteria) { - QueryableList query = getDatabaseService().getQueryable(DMP.getHints(), DMP.class); - if (criteria.getLike() != null && !criteria.getLike().isEmpty()) - query.where((builder, root) -> builder.or( - builder.like(builder.upper(root.get("label")), "%" + criteria.getLike().toUpperCase() + "%"), - builder.like(builder.upper(root.get("description")), "%" + criteria.getLike().toUpperCase() + "%"))); - if (criteria.getPeriodEnd() != null) - query.where((builder, root) -> builder.lessThan(root.get("created"), criteria.getPeriodEnd())); - if (criteria.getPeriodStart() != null) - query.where((builder, root) -> builder.greaterThan(root.get("created"), criteria.getPeriodStart())); - if (criteria.getGrants() != null && !criteria.getGrants().isEmpty()) - query.where(((builder, root) -> root.get("grant").in(criteria.getGrants()))); - if (!criteria.getAllVersions()) - query.initSubQuery(String.class).where((builder, root) -> builder.equal(root.get("version"), - query.subQueryMax((builder1, externalRoot, nestedRoot) -> builder1.equal(externalRoot.get("groupId"), - nestedRoot.get("groupId")), Arrays.asList(new SelectionField(FieldSelectionType.FIELD, "version")), String.class))); - if (criteria.getGroupIds() != null && !criteria.getGroupIds().isEmpty()) - query.where((builder, root) -> root.get("groupId").in(criteria.getGroupIds())); - if (criteria.getStatus() != null) { - if (criteria.getStatus() == DMP.DMPStatus.FINALISED.getValue()) { - query.where((builder, root) -> builder.and(builder.equal(root.get("status"), DMP.DMPStatus.FINALISED.getValue()), builder.notEqual(root.get("isPublic"), true))); - } else if (criteria.getStatus() == DMP.DMPStatus.ACTIVE.getValue()) { - query.where((builder, root) -> builder.equal(root.get("status"), DMP.DMPStatus.ACTIVE.getValue())); - } - } - if (criteria.getIsPublic()) - query.where(((builder, root) -> builder.equal(root.get("isPublic"), true))); - if (criteria.getRole() != null) { + @Override + public QueryableList getWithCriteria(DataManagementPlanCriteria criteria) { + QueryableList query = getDatabaseService().getQueryable(DMP.getHints(), DMP.class); + if (criteria.getLike() != null && !criteria.getLike().isEmpty()) + query.where((builder, root) -> builder.or( + builder.like(builder.upper(root.get("label")), "%" + criteria.getLike().toUpperCase() + "%"), + builder.like(builder.upper(root.get("description")), "%" + criteria.getLike().toUpperCase() + "%"))); + if (criteria.getPeriodEnd() != null) + query.where((builder, root) -> builder.lessThan(root.get("created"), criteria.getPeriodEnd())); + if (criteria.getPeriodStart() != null) + query.where((builder, root) -> builder.greaterThan(root.get("created"), criteria.getPeriodStart())); + if (criteria.getGrants() != null && !criteria.getGrants().isEmpty()) + query.where(((builder, root) -> root.get("grant").in(criteria.getGrants()))); + if (!criteria.getAllVersions()) + query.initSubQuery(String.class).where((builder, root) -> builder.equal(root.get("version"), + query.subQueryMax((builder1, externalRoot, nestedRoot) -> builder1.equal(externalRoot.get("groupId"), + nestedRoot.get("groupId")), Arrays.asList(new SelectionField(FieldSelectionType.FIELD, "version")), String.class))); + if (criteria.getGroupIds() != null && !criteria.getGroupIds().isEmpty()) + query.where((builder, root) -> root.get("groupId").in(criteria.getGroupIds())); + if (criteria.getStatus() != null) { + if (criteria.getStatus() == DMP.DMPStatus.FINALISED.getValue()) { + query.where((builder, root) -> builder.and(builder.equal(root.get("status"), DMP.DMPStatus.FINALISED.getValue()), builder.notEqual(root.get("isPublic"), true))); + } else if (criteria.getStatus() == DMP.DMPStatus.ACTIVE.getValue()) { + query.where((builder, root) -> builder.equal(root.get("status"), DMP.DMPStatus.ACTIVE.getValue())); + } + } + if (criteria.getIsPublic()) + query.where(((builder, root) -> builder.equal(root.get("isPublic"), true))); + /*if (criteria.getRole() != null) { if (criteria.getRole().equals(UserDMP.UserDMPRoles.OWNER.getValue())) { query.where((builder, root) -> builder.equal(root.join("users", JoinType.LEFT).get("role"), UserDMP.UserDMPRoles.OWNER.getValue())); } else if (criteria.getRole().equals(UserDMP.UserDMPRoles.USER.getValue())) { query.where((builder, root) -> builder.equal(root.join("users", JoinType.LEFT).get("role"), UserDMP.UserDMPRoles.USER.getValue())); } - } - if (criteria.getOrganisations() != null && !criteria.getOrganisations().isEmpty()) { - query.where((builder, root) -> root.join("organisations").get("reference").in(criteria.getOrganisations())); - } - if (criteria.getCollaborators() != null && !criteria.getCollaborators().isEmpty()) { - query.where((builder, root) -> root.join("users", JoinType.LEFT).join("user", JoinType.LEFT).get("id").in(criteria.getCollaborators())); - } - if (criteria.getDatasetTemplates() != null && !criteria.getDatasetTemplates().isEmpty()) { - query.where(((builder, root) -> root.join("associatedDmps", JoinType.LEFT).get("id").in(criteria.getDatasetTemplates()))); - } - query.where((builder, root) -> builder.notEqual(root.get("status"), DMP.DMPStatus.DELETED.getValue())); - return query; - } + }*/ + if (criteria.getOrganisations() != null && !criteria.getOrganisations().isEmpty()) { + query.where((builder, root) -> root.join("organisations").get("reference").in(criteria.getOrganisations())); + } + if (criteria.getCollaborators() != null && !criteria.getCollaborators().isEmpty()) { + query.where((builder, root) -> root.join("users", JoinType.LEFT).join("user", JoinType.LEFT).get("id").in(criteria.getCollaborators())); + } + if (criteria.getDatasetTemplates() != null && !criteria.getDatasetTemplates().isEmpty()) { + query.where((builder, root) -> root.join("associatedDmps", JoinType.LEFT).get("id").in(criteria.getDatasetTemplates())); + } + query.where((builder, root) -> builder.notEqual(root.get("status"), DMP.DMPStatus.DELETED.getValue())); + return query; + } - public QueryableList getAuthenticated(QueryableList query, UUID principal) { - query.where((builder, root) -> builder.equal(root.join("users", JoinType.LEFT).join("user").get("id"), principal)); - return query; - } + public QueryableList getAuthenticated(QueryableList query, UUID principal, List roles) { + if (roles != null && !roles.isEmpty()) { + query.where((builder, root) -> { + Join userJoin = root.join("users", JoinType.LEFT); + return builder.and(builder.equal(userJoin.join("user", JoinType.LEFT).get("id"), principal), userJoin.get("role").in(roles)); + }); + } else { + query.where((builder, root) -> builder.equal(root.join("users", JoinType.LEFT).join("user", JoinType.LEFT).get("id"), principal)); + } - @Override - public DMP createOrUpdate(DMP item) { - return this.getDatabaseService().createOrUpdate(item, DMP.class); - } + return query; + } - @Override - public DMP find(UUID id) { - return getDatabaseService().getQueryable(DMP.class).where((builder, root) -> builder.equal((root.get("id")), id)).getSingle(); - } + @Override + public DMP createOrUpdate(DMP item) { + return this.getDatabaseService().createOrUpdate(item, DMP.class); + } - @Override - public QueryableList getUserDmps(DatasetWizardUserDmpCriteria datasetWizardUserDmpCriteria, UserInfo userInfo) { - QueryableList query = getDatabaseService().getQueryable(DMP.class).where((builder, root) -> builder.or(builder.equal(root.get("creator"), userInfo), builder.isMember(userInfo, root.get("users")))); - if (datasetWizardUserDmpCriteria.getLike() != null && !datasetWizardUserDmpCriteria.getLike().isEmpty()) { - query.where((builder, root) -> builder.like(root.get("label"), "%" + datasetWizardUserDmpCriteria.getLike() + "%")); - } - return query; - } + @Override + public DMP find(UUID id) { + return getDatabaseService().getQueryable(DMP.class).where((builder, root) -> builder.equal((root.get("id")), id)).getSingle(); + } - @Override - public void delete(DMP item) { - this.getDatabaseService().delete(item); - } + @Override + public QueryableList getUserDmps(DatasetWizardUserDmpCriteria datasetWizardUserDmpCriteria, UserInfo userInfo) { + QueryableList query = getDatabaseService().getQueryable(DMP.class).where((builder, root) -> builder.or(builder.equal(root.get("creator"), userInfo), builder.isMember(userInfo, root.get("users")))); + if (datasetWizardUserDmpCriteria.getLike() != null && !datasetWizardUserDmpCriteria.getLike().isEmpty()) { + query.where((builder, root) -> builder.like(root.get("label"), "%" + datasetWizardUserDmpCriteria.getLike() + "%")); + } + return query; + } - @Override - public QueryableList asQueryable() { - return this.getDatabaseService().getQueryable(DMP.class); - } + @Override + public void delete(DMP item) { + this.getDatabaseService().delete(item); + } - @Async - @Override - public CompletableFuture createOrUpdateAsync(DMP item) { - return CompletableFuture.supplyAsync(() -> this.createOrUpdate(item)); - } + @Override + public QueryableList asQueryable() { + return this.getDatabaseService().getQueryable(DMP.class); + } - @Override - public DMP find(UUID id, String hint) { - throw new UnsupportedOperationException(); - } + @Async + @Override + public CompletableFuture createOrUpdateAsync(DMP item) { + return CompletableFuture.supplyAsync(() -> this.createOrUpdate(item)); + } + + @Override + public DMP find(UUID id, String hint) { + throw new UnsupportedOperationException(); + } } diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DataRepositoryDaoImpl.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DataRepositoryDaoImpl.java index c74a997d6..4658b44f6 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DataRepositoryDaoImpl.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DataRepositoryDaoImpl.java @@ -24,7 +24,11 @@ public class DataRepositoryDaoImpl extends DatabaseAccess implem public QueryableList getWithCriteria(DataRepositoryCriteria criteria) { QueryableList query = this.getDatabaseService().getQueryable(DataRepository.class); if (criteria.getLike() != null) - query.where((builder, root) -> builder.equal(root.get("reference"), criteria.getLike())); + query.where((builder, root) -> builder.or( + builder.like(builder.upper(root.get("reference")), "%" + criteria.getLike().toUpperCase() + "%"), + builder.equal(builder.upper(root.get("label")), criteria.getLike().toUpperCase()))); + if (criteria.getCreationUserId() != null) + query.where((builder, root) -> builder.equal(root.get("creationUser").get("id"), criteria.getCreationUserId())); return query; } diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetDaoImpl.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetDaoImpl.java index fec0ab7cb..1a68dcead 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetDaoImpl.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetDaoImpl.java @@ -3,8 +3,8 @@ package eu.eudat.data.dao.entities; import eu.eudat.data.dao.DatabaseAccess; import eu.eudat.data.dao.criteria.DatasetCriteria; import eu.eudat.data.dao.databaselayer.service.DatabaseService; -import eu.eudat.data.entities.DMP; import eu.eudat.data.entities.Dataset; +import eu.eudat.data.entities.UserDMP; import eu.eudat.data.entities.UserInfo; import eu.eudat.queryable.QueryableList; import eu.eudat.queryable.types.FieldSelectionType; @@ -43,8 +43,11 @@ public class DatasetDaoImpl extends DatabaseAccess implements DatasetDa query.initSubQuery(String.class).where((builder, root) -> builder.equal(root.get("dmp").get("version"), query.subQueryMax((builder1, externalRoot, nestedRoot) -> builder1.equal(externalRoot.get("dmp").get("groupId"), nestedRoot.get("dmp").get("groupId")), Arrays.asList(new SelectionField(FieldSelectionType.COMPOSITE_FIELD, "dmp:version")), String.class))); if (criteria.getDmpIds() != null && !criteria.getDmpIds().isEmpty()) query.where((builder, root) -> root.get("dmp").get("id").in(criteria.getDmpIds())); - if (criteria.getRole() != null) + if (criteria.getRole() != null) { query.where((builder, root) -> builder.equal(root.join("dmp").join("users").get("role"), criteria.getRole())); + } else { + query.where((builder, root) -> root.join("dmp").join("users").get("role").in(UserDMP.UserDMPRoles.getAllValues())); + } if (criteria.getOrganisations() != null && !criteria.getOrganisations().isEmpty()) query.where((builder, root) -> root.join("dmp").join("organisations").get("reference").in(criteria.getOrganisations())); if (criteria.getGrants() != null && !criteria.getGrants().isEmpty()) @@ -52,9 +55,9 @@ public class DatasetDaoImpl extends DatabaseAccess implements DatasetDa if (criteria.getCollaborators() != null && !criteria.getCollaborators().isEmpty()) query.where((builder, root) -> root.join("dmp", JoinType.LEFT).join("users", JoinType.LEFT).join("user", JoinType.LEFT).get("id").in(criteria.getCollaborators())); if (criteria.getDatasetTemplates() != null && !criteria.getDatasetTemplates().isEmpty()) - query.where(((builder, root) -> root.get("profile").get("id").in(criteria.getDatasetTemplates()))); - query.where(((builder, root) -> builder.notEqual(root.get("status"), Dataset.Status.DELETED.getValue()))); - query.where(((builder, root) -> builder.notEqual(root.get("status"), Dataset.Status.CANCELED.getValue()))); + query.where((builder, root) -> root.get("profile").get("id").in(criteria.getDatasetTemplates())); + query.where((builder, root) -> builder.notEqual(root.get("status"), Dataset.Status.DELETED.getValue())); + query.where((builder, root) -> builder.notEqual(root.get("status"), Dataset.Status.CANCELED.getValue())); return query; } @@ -87,7 +90,7 @@ public class DatasetDaoImpl extends DatabaseAccess implements DatasetDa public QueryableList getAuthenticated(QueryableList query, UserInfo principal) { if (principal.getId() == null) query.where((builder, root) -> builder.equal(root.get("isPublic"), true)); else { - query.where((builder, root) -> builder.or(builder.equal(root.get("dmp").get("creator"), principal), builder.equal(root.join("dmp", JoinType.LEFT).join("users", JoinType.LEFT).join("user", JoinType.LEFT).get("id"), principal.getId()))); + query.where((builder, root) -> builder.equal(root.join("dmp", JoinType.LEFT).join("users", JoinType.LEFT).join("user", JoinType.LEFT).get("id"), principal.getId())); } return query; } diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/ExternalDatasetDaoImpl.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/ExternalDatasetDaoImpl.java index 76b1ec4f7..163eed579 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/ExternalDatasetDaoImpl.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/ExternalDatasetDaoImpl.java @@ -25,7 +25,11 @@ public class ExternalDatasetDaoImpl extends DatabaseAccess impl public QueryableList getWithCriteria(ExternalDatasetCriteria criteria) { QueryableList query = this.getDatabaseService().getQueryable(ExternalDataset.class); if (criteria.getLike() != null && !criteria.getLike().isEmpty()) - query.where((builder, root) -> builder.like(builder.upper(root.get("label")), "%" + criteria.getLike().toUpperCase() + "%")); + query.where((builder, root) -> builder.or( + builder.like(builder.upper(root.get("reference")), "%" + criteria.getLike().toUpperCase() + "%"), + builder.equal(builder.upper(root.get("label")), criteria.getLike().toUpperCase()))); + if (criteria.getCreationUserId() != null) + query.where((builder, root) -> builder.equal(root.join("creationUser").get("id"), criteria.getCreationUserId())); return query; } diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/FunderDaoImpl.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/FunderDaoImpl.java index 8335f71e5..40262d743 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/FunderDaoImpl.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/FunderDaoImpl.java @@ -28,14 +28,15 @@ public class FunderDaoImpl extends DatabaseAccess implements FunderDao { builder.or(builder.like(builder.upper(root.get("label")), "%" + criteria.getLike().toUpperCase() + "%"), builder.or(builder.like(builder.upper(root.get("definition")), "%" + criteria.getLike().toUpperCase() + "%")))); if (criteria.getReference() != null) - query.where((builder, root) -> builder.like(root.get("reference"), "%" + criteria.getReference() + "%")); + query.where((builder, root) -> builder.like(builder.upper(root.get("reference")), "%" + criteria.getReference().toUpperCase() + "%")); query.where((builder, root) -> builder.notEqual(root.get("status"), Funder.Status.DELETED.getValue())); return query; } @Override public QueryableList getAuthenticated(QueryableList query, UserInfo principal) { - return null; + query.where((builder, root) -> builder.equal(root.get("creationUser"), principal)); + return query; } @Override diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/GrantDaoImpl.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/GrantDaoImpl.java index 47d22c064..bb91b39ad 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/GrantDaoImpl.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/GrantDaoImpl.java @@ -11,6 +11,7 @@ import eu.eudat.types.grant.GrantStateType; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Component; +import schemasMicrosoftComOfficeOffice.LeftDocument; import javax.persistence.criteria.JoinType; import java.util.Date; @@ -51,6 +52,8 @@ public class GrantDaoImpl extends DatabaseAccess implements GrantDao { } if (criteria.getFunderId() != null && !criteria.getFunderId().trim().isEmpty()) query.where((builder, root) -> builder.equal(root.get("funder").get("id"), UUID.fromString(criteria.getFunderId()))); + if (criteria.getFunderReference() != null && !criteria.getFunderReference().isEmpty()) + query.where((builder, root) -> builder.equal(root.join("funder", JoinType.LEFT).get("reference"), criteria.getFunderReference())); query.where((builder, root) -> builder.notEqual(root.get("status"), Grant.Status.DELETED.getValue())); return query; } diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/RegistryDaoImpl.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/RegistryDaoImpl.java index c7ed94b75..c02fee715 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/RegistryDaoImpl.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/RegistryDaoImpl.java @@ -24,7 +24,12 @@ public class RegistryDaoImpl extends DatabaseAccess implements Registr public QueryableList getWithCriteria(RegistryCriteria criteria) { QueryableList query = this.getDatabaseService().getQueryable(Registry.class); if (criteria.getLike() != null) - query.where((builder, root) -> builder.equal(root.get("reference"), criteria.getLike())); + if (criteria.getLike() != null) + query.where((builder, root) -> builder.or( + builder.like(builder.upper(root.get("reference")), "%" + criteria.getLike().toUpperCase() + "%"), + builder.equal(builder.upper(root.get("label")), criteria.getLike().toUpperCase()))); + if (criteria.getCreationUserId() != null) + query.where((builder, root) -> builder.equal(root.get("creationUser").get("id"), criteria.getCreationUserId())); return query; } diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/ServiceDaoImpl.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/ServiceDaoImpl.java index 00406ab91..1843a4510 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/ServiceDaoImpl.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/ServiceDaoImpl.java @@ -24,7 +24,11 @@ public class ServiceDaoImpl extends DatabaseAccess implements ServiceDa public QueryableList getWithCriteria(ServiceCriteria criteria) { QueryableList query = this.getDatabaseService().getQueryable(Service.class); if (criteria.getLike() != null) - query.where((builder, root) -> builder.equal(root.get("reference"), criteria.getLike())); + query.where((builder, root) -> builder.or( + builder.like(builder.upper(root.get("reference")), "%" + criteria.getLike().toUpperCase() + "%"), + builder.equal(builder.upper(root.get("label")), criteria.getLike().toUpperCase()))); + if (criteria.getCreationUserId() != null) + query.where((builder, root) -> builder.equal(root.get("creationUser").get("id"), criteria.getCreationUserId())); return query; } diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/entities/DataRepository.java b/dmp-backend/data/src/main/java/eu/eudat/data/entities/DataRepository.java index a65eda92f..0d9d7a893 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/entities/DataRepository.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/entities/DataRepository.java @@ -3,7 +3,6 @@ package eu.eudat.data.entities; import eu.eudat.data.entities.helpers.EntityBinder; import eu.eudat.queryable.queryableentity.DataEntity; -import org.hibernate.annotations.GenericGenerator; import org.hibernate.annotations.Type; import javax.persistence.*; @@ -18,8 +17,6 @@ import java.util.UUID; public class DataRepository implements Serializable, DataEntity { @Id - @GeneratedValue - @GenericGenerator(name = "uuid2", strategy = "uuid2") @Column(name = "\"ID\"", updatable = false, nullable = false, columnDefinition = "BINARY(16)") private UUID id; @@ -39,11 +36,9 @@ public class DataRepository implements Serializable, DataEntity datasetDataRepositories; - @Column(name = "\"Status\"", nullable = false) private Short status; @@ -53,41 +48,35 @@ public class DataRepository implements Serializable, DataEntity getDatasetDataRepositories() { return datasetDataRepositories; } - public void setDatasetDataRepositories(Set datasetDataRepositories) { this.datasetDataRepositories = datasetDataRepositories; } + public UserInfo getCreationUser() { + return creationUser; + } + public void setCreationUser(UserInfo creationUser) { + this.creationUser = creationUser; + } + @Override public void update(DataRepository entity) { diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/entities/Dataset.java b/dmp-backend/data/src/main/java/eu/eudat/data/entities/Dataset.java index 3763b6de6..fe38a22cb 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/entities/Dataset.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/entities/Dataset.java @@ -276,32 +276,25 @@ public class Dataset implements DataEntity { @Override public void update(Dataset entity) { - this.setRegistries(entity.getRegistries()); - if (this.getDatasetDataRepositories() == null) this.setDatasetDataRepositories(new HashSet<>()); - if (!this.getDatasetDataRepositories().containsAll(entity.getDatasetDataRepositories())) { - this.getDatasetDataRepositories().removeAll(this.getDatasetDataRepositories()); - this.getDatasetDataRepositories().addAll(entity.getDatasetDataRepositories().stream().map(item -> { - item.setDataset(this); - return item; - }).collect(Collectors.toList())); - } this.setUri(entity.getUri()); this.setDescription(entity.getDescription()); this.setLabel(entity.getLabel()); this.setProperties(entity.getProperties()); - if (this.getDatasetExternalDatasets() == null) this.setDatasetExternalDatasets(new HashSet<>()); - if (!this.getDatasetExternalDatasets().containsAll(entity.getDatasetExternalDatasets())) { - this.getDatasetExternalDatasets().removeAll(this.getDatasetExternalDatasets()); - this.getDatasetExternalDatasets().addAll(entity.getDatasetExternalDatasets().stream().map(item -> { - item.setDataset(this); - return item; - }).collect(Collectors.toList())); - } - if (this.getServices() == null) this.setServices(new HashSet<>()); - if(!this.getServices().containsAll(entity.getServices())) { - this.getServices().removeAll(this.getServices()); + + this.getDatasetDataRepositories().removeAll(this.getDatasetDataRepositories()); + if (entity.getDatasetDataRepositories() != null) + this.getDatasetDataRepositories().addAll(entity.getDatasetDataRepositories()); + + this.getDatasetExternalDatasets().removeAll(this.getDatasetExternalDatasets()); + if (entity.getDatasetExternalDatasets() != null) + this.getDatasetExternalDatasets().addAll(entity.getDatasetExternalDatasets()); + + this.setRegistries(entity.getRegistries()); + + this.getServices().removeAll(this.getServices()); + if (entity.getServices() != null) this.getServices().addAll(entity.getServices()); - } + this.setDmp(entity.getDmp()); this.setStatus(entity.getStatus()); this.setProfile(entity.getProfile()); diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/entities/ExternalDataset.java b/dmp-backend/data/src/main/java/eu/eudat/data/entities/ExternalDataset.java index 51d5e474e..199bacff3 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/entities/ExternalDataset.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/entities/ExternalDataset.java @@ -40,10 +40,14 @@ public class ExternalDataset implements DataEntity { @OneToMany(mappedBy = "externalDataset", cascade = CascadeType.ALL, orphanRemoval = true) private Set datasets; + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "\"CreationUser\"", nullable = true) + private UserInfo creationUser; + + public UUID getId() { return id; } - public void setId(UUID id) { this.id = id; } @@ -51,7 +55,6 @@ public class ExternalDataset implements DataEntity { public String getLabel() { return label; } - public void setLabel(String label) { this.label = label; } @@ -59,7 +62,6 @@ public class ExternalDataset implements DataEntity { public String getAbbreviation() { return abbreviation; } - public void setAbbreviation(String abbreviation) { this.abbreviation = abbreviation; } @@ -67,7 +69,6 @@ public class ExternalDataset implements DataEntity { public String getReference() { return reference; } - public void setReference(String reference) { this.reference = reference; } @@ -75,7 +76,6 @@ public class ExternalDataset implements DataEntity { public Date getCreated() { return created; } - public void setCreated(Date created) { this.created = created; } @@ -83,7 +83,6 @@ public class ExternalDataset implements DataEntity { public Date getModified() { return modified; } - public void setModified(Date modified) { this.modified = modified; } @@ -91,16 +90,23 @@ public class ExternalDataset implements DataEntity { public Set getDatasets() { return datasets; } - public void setDatasets(Set datasets) { this.datasets = datasets; } + public UserInfo getCreationUser() { + return creationUser; + } + public void setCreationUser(UserInfo creationUser) { + this.creationUser = creationUser; + } + @Override public void update(ExternalDataset entity) { this.label = entity.getLabel(); this.abbreviation = entity.getAbbreviation(); this.modified = new Date(); + this.creationUser = entity.getCreationUser(); } @Override diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/entities/Funder.java b/dmp-backend/data/src/main/java/eu/eudat/data/entities/Funder.java index 2b6bce8b1..c1a3bb087 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/entities/Funder.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/entities/Funder.java @@ -94,6 +94,10 @@ public class Funder implements DataEntity { @Column(name = "\"Type\"") private Integer type; + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "\"CreationUser\"", nullable = true) + private UserInfo creationUser; + public UUID getId() { return id; @@ -151,6 +155,13 @@ public class Funder implements DataEntity { this.type = type; } + public UserInfo getCreationUser() { + return creationUser; + } + public void setCreationUser(UserInfo creationUser) { + this.creationUser = creationUser; + } + @Override public void update(Funder entity) { this.label = entity.getLabel(); @@ -160,6 +171,7 @@ public class Funder implements DataEntity { this.created = entity.getCreated(); this.modified = new Date(); this.type = entity.getType(); + this.creationUser = entity.getCreationUser(); } @Override diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/entities/Registry.java b/dmp-backend/data/src/main/java/eu/eudat/data/entities/Registry.java index dafef8ad0..6a40378cd 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/entities/Registry.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/entities/Registry.java @@ -17,7 +17,6 @@ import java.util.UUID; @Table(name = "\"Registry\"") public class Registry implements DataEntity { - @Id @Column(name = "\"ID\"", updatable = false, nullable = false, columnDefinition = "BINARY(16)") private UUID id; @@ -38,7 +37,6 @@ public class Registry implements DataEntity { @Column(name = "\"Definition\"", columnDefinition = "xml", nullable = true) private String definition; - @OneToMany(fetch = FetchType.LAZY) @JoinTable(name = "\"DatasetRegistry\"", joinColumns = {@JoinColumn(name = "\"Registry\"", referencedColumnName = "\"ID\"")}, @@ -46,11 +44,9 @@ public class Registry implements DataEntity { ) private Set datasets; - @Column(name = "\"Status\"", nullable = false) private Short status; - @Column(name = "\"Created\"") @Convert(converter = DateToUTCConverter.class) private Date created = null; @@ -59,32 +55,28 @@ public class Registry implements DataEntity { @Convert(converter = DateToUTCConverter.class) private Date modified = new Date(); + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "\"CreationUser\"", nullable = true) + private UserInfo creationUser; + public Short getStatus() { return status; } - - public void setStatus(Short status) { this.status = status; } - public Date getCreated() { return created; } - - public void setCreated(Date created) { this.created = created; } - public Date getModified() { return modified; } - - public void setModified(Date modified) { this.modified = modified; } @@ -92,7 +84,6 @@ public class Registry implements DataEntity { public UUID getId() { return id; } - public void setId(UUID id) { this.id = id; } @@ -100,7 +91,6 @@ public class Registry implements DataEntity { public String getLabel() { return label; } - public void setLabel(String label) { this.label = label; } @@ -108,7 +98,6 @@ public class Registry implements DataEntity { public String getAbbreviation() { return abbreviation; } - public void setAbbreviation(String abbreviation) { this.abbreviation = abbreviation; } @@ -116,7 +105,6 @@ public class Registry implements DataEntity { public String getReference() { return reference; } - public void setReference(String reference) { this.reference = reference; } @@ -124,7 +112,6 @@ public class Registry implements DataEntity { public String getUri() { return uri; } - public void setUri(String uri) { this.uri = uri; } @@ -132,7 +119,6 @@ public class Registry implements DataEntity { public String getDefinition() { return definition; } - public void setDefinition(String definition) { this.definition = definition; } @@ -140,11 +126,16 @@ public class Registry implements DataEntity { public Set getDatasets() { return datasets; } - public void setDatasets(Set datasets) { this.datasets = datasets; } + public UserInfo getCreationUser() { + return creationUser; + } + public void setCreationUser(UserInfo creationUser) { + this.creationUser = creationUser; + } @Override public void update(Registry entity) { diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/entities/Researcher.java b/dmp-backend/data/src/main/java/eu/eudat/data/entities/Researcher.java index 3066d914a..1ede09a23 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/entities/Researcher.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/entities/Researcher.java @@ -62,41 +62,34 @@ public class Researcher implements DataEntity { @Convert(converter = DateToUTCConverter.class) private Date modified = new Date(); + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "\"CreationUser\"", nullable = true) + private UserInfo creationUser; public Short getStatus() { return status; } - - public void setStatus(Short status) { this.status = status; } - public Date getCreated() { return created; } - - public void setCreated(Date created) { this.created = created; } - public Date getModified() { return modified; } - - public void setModified(Date modified) { this.modified = modified; } - public UUID getId() { return id; } - public void setId(UUID id) { this.id = id; } @@ -104,7 +97,6 @@ public class Researcher implements DataEntity { public String getLabel() { return label; } - public void setLabel(String label) { this.label = label; } @@ -112,7 +104,6 @@ public class Researcher implements DataEntity { public String getPrimaryEmail() { return primaryEmail; } - public void setPrimaryEmail(String primaryEmail) { this.primaryEmail = primaryEmail; } @@ -120,7 +111,6 @@ public class Researcher implements DataEntity { public String getReference() { return reference; } - public void setReference(String reference) { this.reference = reference; } @@ -128,7 +118,6 @@ public class Researcher implements DataEntity { public String getUri() { return uri; } - public void setUri(String uri) { this.uri = uri; } @@ -136,7 +125,6 @@ public class Researcher implements DataEntity { public String getDefinition() { return definition; } - public void setDefinition(String definition) { this.definition = definition; } @@ -144,11 +132,16 @@ public class Researcher implements DataEntity { public Set getdMPs() { return dMPs; } - public void setdMPs(Set dMPs) { this.dMPs = dMPs; } + public UserInfo getCreationUser() { + return creationUser; + } + public void setCreationUser(UserInfo creationUser) { + this.creationUser = creationUser; + } @Override public void update(Researcher entity) { diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/entities/Service.java b/dmp-backend/data/src/main/java/eu/eudat/data/entities/Service.java index 14ca76f60..c71977292 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/entities/Service.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/entities/Service.java @@ -20,7 +20,6 @@ public class Service implements DataEntity { @Column(name = "\"ID\"", updatable = false, nullable = false, columnDefinition = "BINARY(16)") private UUID id; - @Column(name = "\"Label\"") private String label; @@ -37,15 +36,12 @@ public class Service implements DataEntity { @Column(name = "\"Definition\"", columnDefinition = "xml", nullable = false) private String definition; - @OneToMany(mappedBy = "service", cascade = CascadeType.ALL, orphanRemoval = true) private Set services; - @Column(name = "\"Status\"", nullable = false) private Short status; - @Column(name = "\"Created\"") @Convert(converter = DateToUTCConverter.class) private Date created = null; @@ -54,41 +50,35 @@ public class Service implements DataEntity { @Convert(converter = DateToUTCConverter.class) private Date modified = new Date(); + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "\"CreationUser\"", nullable = true) + private UserInfo creationUser; + public Short getStatus() { return status; } - - public void setStatus(Short status) { this.status = status; } - public Date getCreated() { return created; } - - public void setCreated(Date created) { this.created = created; } - public Date getModified() { return modified; } - - public void setModified(Date modified) { this.modified = modified; } - public UUID getId() { return id; } - public void setId(UUID id) { this.id = id; } @@ -96,7 +86,6 @@ public class Service implements DataEntity { public String getLabel() { return label; } - public void setLabel(String label) { this.label = label; } @@ -104,7 +93,6 @@ public class Service implements DataEntity { public String getAbbreviation() { return abbreviation; } - public void setAbbreviation(String abbreviation) { this.abbreviation = abbreviation; } @@ -112,7 +100,6 @@ public class Service implements DataEntity { public String getReference() { return reference; } - public void setReference(String reference) { this.reference = reference; } @@ -120,7 +107,6 @@ public class Service implements DataEntity { public String getUri() { return uri; } - public void setUri(String uri) { this.uri = uri; } @@ -128,7 +114,6 @@ public class Service implements DataEntity { public String getDefinition() { return definition; } - public void setDefinition(String definition) { this.definition = definition; } @@ -136,11 +121,17 @@ public class Service implements DataEntity { public Set getServices() { return services; } - public void setServices(Set services) { this.services = services; } + public UserInfo getCreationUser() { + return creationUser; + } + public void setCreationUser(UserInfo creationUser) { + this.creationUser = creationUser; + } + @Override public void update(Service entity) { diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/entities/UserDMP.java b/dmp-backend/data/src/main/java/eu/eudat/data/entities/UserDMP.java index 6e000136d..217b81821 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/entities/UserDMP.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/entities/UserDMP.java @@ -5,6 +5,7 @@ import eu.eudat.queryable.queryableentity.DataEntity; import org.hibernate.annotations.GenericGenerator; import javax.persistence.*; +import java.util.LinkedList; import java.util.List; import java.util.UUID; @@ -25,6 +26,14 @@ public class UserDMP implements DataEntity { return value; } + public static List getAllValues() { + List list = new LinkedList<>(); + for (Enum en : UserDMP.UserDMPRoles.values()) { + list.add(((UserDMPRoles) en).value); + } + return list; + } + public static UserDMPRoles fromInteger(Integer value) { switch (value) { case 0: diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/query/items/table/dataset/DatasetPublicTableRequest.java b/dmp-backend/data/src/main/java/eu/eudat/data/query/items/table/dataset/DatasetPublicTableRequest.java index ccaef9eaf..6aa363095 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/query/items/table/dataset/DatasetPublicTableRequest.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/query/items/table/dataset/DatasetPublicTableRequest.java @@ -45,6 +45,7 @@ public class DatasetPublicTableRequest extends TableQuery root.get("profile").get("id").in(this.getCriteria().getDatasetProfile()))); if (this.getCriteria().getDmpOrganisations() != null && !this.getCriteria().getDmpOrganisations().isEmpty()) query .where(((builder, root) -> root.join("dmp").join("organisations").get("reference").in(this.getCriteria().getDmpOrganisations()))); + query.where((builder, root) -> builder.notEqual(root.get("status"), Dataset.Status.DELETED.getValue())); return query; } diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/query/items/table/dmp/DataManagmentPlanPublicTableRequest.java b/dmp-backend/data/src/main/java/eu/eudat/data/query/items/table/dmp/DataManagmentPlanPublicTableRequest.java index bb2d08333..78d9dfeb3 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/query/items/table/dmp/DataManagmentPlanPublicTableRequest.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/query/items/table/dmp/DataManagmentPlanPublicTableRequest.java @@ -29,10 +29,10 @@ public class DataManagmentPlanPublicTableRequest extends TableQuery root.get("profile").get("id").in(this.getCriteria().datasetProfile))); - if (this.getCriteria().getDmpOrganisations() != null && !this.getCriteria().getDmpOrganisations().isEmpty()) query - .where(((builder, root) -> root.join("organisations").get("reference").in(this.getCriteria().getDmpOrganisations()))); + if (this.getCriteria().datasetProfile != null && !this.getCriteria().datasetProfile.isEmpty()) + query.where((builder, root) -> root.join("associatedDmps").get("id").in(this.getCriteria().datasetProfile)); + if (this.getCriteria().getDmpOrganisations() != null && !this.getCriteria().getDmpOrganisations().isEmpty()) + query.where(((builder, root) -> root.join("organisations").get("reference").in(this.getCriteria().getDmpOrganisations()))); return query; } diff --git a/dmp-backend/web/src/main/java/eu/eudat/cache/ResponsesCache.java b/dmp-backend/web/src/main/java/eu/eudat/cache/ResponsesCache.java index 0e0bcc339..fc1dba6ae 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/cache/ResponsesCache.java +++ b/dmp-backend/web/src/main/java/eu/eudat/cache/ResponsesCache.java @@ -36,6 +36,7 @@ public class ResponsesCache { caches.add(new GuavaCache("services", CacheBuilder.newBuilder().expireAfterAccess(HOW_MANY, TIME_UNIT).build())); caches.add(new GuavaCache("tags", CacheBuilder.newBuilder().expireAfterAccess(HOW_MANY, TIME_UNIT).build())); caches.add(new GuavaCache("researchers", CacheBuilder.newBuilder().expireAfterAccess(HOW_MANY, TIME_UNIT).build())); + caches.add(new GuavaCache("externalDatasets", CacheBuilder.newBuilder().expireAfterAccess(HOW_MANY, TIME_UNIT).build())); simpleCacheManager.setCaches(caches); System.out.println("OK"); return simpleCacheManager; diff --git a/dmp-backend/web/src/main/java/eu/eudat/configurations/dynamicfunder/DynamicFunderConfigurationDevelImpl.java b/dmp-backend/web/src/main/java/eu/eudat/configurations/dynamicfunder/DynamicFunderConfigurationDevelImpl.java index ffe8fbafa..a1839073d 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/configurations/dynamicfunder/DynamicFunderConfigurationDevelImpl.java +++ b/dmp-backend/web/src/main/java/eu/eudat/configurations/dynamicfunder/DynamicFunderConfigurationDevelImpl.java @@ -40,7 +40,7 @@ public class DynamicFunderConfigurationDevelImpl implements DynamicFunderConfigu JAXBContext jaxbContext = JAXBContext.newInstance(Configuration.class); Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller(); - is = new URL("file:///"+current + "/web/src/main/resources/FunderConfiguration.xml").openStream(); + is = new URL("file:///"+ current + "/web/src/main/resources/FunderConfiguration.xml").openStream(); this.configuration = (Configuration) jaxbUnmarshaller.unmarshal(is); } catch (Exception ex) { ex.printStackTrace(); diff --git a/dmp-backend/web/src/main/java/eu/eudat/configurations/dynamicfunder/DynamicFunderConfigurationProdImpl.java b/dmp-backend/web/src/main/java/eu/eudat/configurations/dynamicfunder/DynamicFunderConfigurationProdImpl.java index f5e0686ee..699ff9580 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/configurations/dynamicfunder/DynamicFunderConfigurationProdImpl.java +++ b/dmp-backend/web/src/main/java/eu/eudat/configurations/dynamicfunder/DynamicFunderConfigurationProdImpl.java @@ -41,7 +41,7 @@ public class DynamicFunderConfigurationProdImpl implements DynamicFunderConfigur JAXBContext jaxbContext = JAXBContext.newInstance(Configuration.class); Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller(); - is = new URL("file:///" + this.environment.getProperty("configuration.resources.path") + "FunderConfiguration.xml").openStream(); + is = new URL(Paths.get(fileUrl).toUri().toURL().toString()).openStream(); this.configuration = (Configuration) jaxbUnmarshaller.unmarshal(is); } catch (Exception ex) { ex.printStackTrace(); diff --git a/dmp-backend/web/src/main/java/eu/eudat/configurations/dynamicgrant/DynamicGrantConfigurationDevelImpl.java b/dmp-backend/web/src/main/java/eu/eudat/configurations/dynamicgrant/DynamicGrantConfigurationDevelImpl.java index a3b950d70..92acd774a 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/configurations/dynamicgrant/DynamicGrantConfigurationDevelImpl.java +++ b/dmp-backend/web/src/main/java/eu/eudat/configurations/dynamicgrant/DynamicGrantConfigurationDevelImpl.java @@ -48,7 +48,7 @@ public class DynamicGrantConfigurationDevelImpl implements DynamicGrantConfigura JAXBContext jaxbContext = JAXBContext.newInstance(Configuration.class); Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller(); - is = new URL("file:///"+current + "/web/src/main/resources/GrantConfiguration.xml").openStream(); + is = new URL("file:///"+ current + "/web/src/main/resources/GrantConfiguration.xml").openStream(); this.configuration = (Configuration) jaxbUnmarshaller.unmarshal(is); } catch (Exception ex) { ex.printStackTrace(); diff --git a/dmp-backend/web/src/main/java/eu/eudat/configurations/dynamicgrant/DynamicGrantConfigurationProdImpl.java b/dmp-backend/web/src/main/java/eu/eudat/configurations/dynamicgrant/DynamicGrantConfigurationProdImpl.java index 7d7e29348..9fc72b985 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/configurations/dynamicgrant/DynamicGrantConfigurationProdImpl.java +++ b/dmp-backend/web/src/main/java/eu/eudat/configurations/dynamicgrant/DynamicGrantConfigurationProdImpl.java @@ -48,7 +48,7 @@ public class DynamicGrantConfigurationProdImpl implements DynamicGrantConfigurat JAXBContext jaxbContext = JAXBContext.newInstance(Configuration.class); Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller(); - is = new URL("file:///" + this.environment.getProperty("configuration.resources.path") + "GrantConfiguration.xml").openStream(); + is = new URL(Paths.get(fileUrl).toUri().toURL().toString()).openStream(); this.configuration = (Configuration) jaxbUnmarshaller.unmarshal(is); } catch (Exception ex) { ex.printStackTrace(); diff --git a/dmp-backend/web/src/main/java/eu/eudat/configurations/dynamicproject/DynamicProjectConfigurationDevelImpl.java b/dmp-backend/web/src/main/java/eu/eudat/configurations/dynamicproject/DynamicProjectConfigurationDevelImpl.java index 50622a8f2..757990db1 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/configurations/dynamicproject/DynamicProjectConfigurationDevelImpl.java +++ b/dmp-backend/web/src/main/java/eu/eudat/configurations/dynamicproject/DynamicProjectConfigurationDevelImpl.java @@ -42,7 +42,7 @@ public class DynamicProjectConfigurationDevelImpl implements DynamicProjectConfi JAXBContext jaxbContext = JAXBContext.newInstance(Configuration.class); Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller(); - is = new URL("file:///"+current + "/web/src/main/resources/ProjectConfiguration.xml").openStream(); + is = new URL("file:///"+ current + "/web/src/main/resources/ProjectConfiguration.xml").openStream(); this.configuration = (Configuration) jaxbUnmarshaller.unmarshal(is); } catch (Exception ex) { ex.printStackTrace(); diff --git a/dmp-backend/web/src/main/java/eu/eudat/configurations/dynamicproject/DynamicProjectConfigurationProdImpl.java b/dmp-backend/web/src/main/java/eu/eudat/configurations/dynamicproject/DynamicProjectConfigurationProdImpl.java index 79654de69..a6627c6d1 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/configurations/dynamicproject/DynamicProjectConfigurationProdImpl.java +++ b/dmp-backend/web/src/main/java/eu/eudat/configurations/dynamicproject/DynamicProjectConfigurationProdImpl.java @@ -45,7 +45,7 @@ public class DynamicProjectConfigurationProdImpl implements DynamicProjectConfig JAXBContext jaxbContext = JAXBContext.newInstance(Configuration.class); Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller(); - is = new URL("file:///" + this.environment.getProperty("configuration.resources.path") + "ProjectConfiguration.xml").openStream(); + is = new URL(Paths.get(fileUrl).toUri().toURL().toString()).openStream(); this.configuration = (Configuration) jaxbUnmarshaller.unmarshal(is); } catch (Exception ex) { ex.printStackTrace(); diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/Admin.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/Admin.java index 12cab1917..11760957b 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/Admin.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/Admin.java @@ -7,12 +7,14 @@ import eu.eudat.exceptions.datasetprofile.DatasetProfileWithDatasetsExeption; import eu.eudat.logic.managers.AdminManager; import eu.eudat.logic.managers.DatasetProfileManager; import eu.eudat.logic.managers.UserManager; +import eu.eudat.logic.proxy.config.configloaders.ConfigLoader; import eu.eudat.logic.security.claims.ClaimedAuthorities; import eu.eudat.logic.services.ApiContext; import eu.eudat.models.data.admin.composite.DatasetProfile; import eu.eudat.models.data.datasetprofile.DatasetProfileListingModel; import eu.eudat.models.data.helpers.common.DataTableData; import eu.eudat.models.data.helpers.responses.ResponseItem; +import org.springframework.core.env.Environment; import eu.eudat.models.data.security.Principal; import eu.eudat.models.data.user.composite.PagedDatasetProfile; import eu.eudat.types.ApiMessageCode; @@ -37,12 +39,14 @@ public class Admin extends BaseController { private DatasetProfileManager datasetProfileManager; private UserManager userManager; + private ConfigLoader configLoader; @Autowired - public Admin(ApiContext apiContext, DatasetProfileManager datasetProfileManager, UserManager userManager, Logger logger) { + public Admin(ApiContext apiContext, DatasetProfileManager datasetProfileManager, UserManager userManager, Logger logger, ConfigLoader configLoader) { super(apiContext); this.datasetProfileManager = datasetProfileManager; this.userManager = userManager; + this.configLoader = configLoader; } @Transactional @@ -90,7 +94,7 @@ public class Admin extends BaseController { @RequestMapping(method = RequestMethod.POST, value = {"/datasetprofiles/getPaged"}, produces = "application/json") public @ResponseBody - ResponseEntity>> getPaged(@RequestBody DatasetProfileTableRequestItem datasetProfileTableRequestItem, Principal principal) throws Exception { + ResponseEntity>> getPaged(@RequestBody DatasetProfileTableRequestItem datasetProfileTableRequestItem, @ClaimedAuthorities(claims = {ADMIN}) Principal principal) throws Exception { DataTableData datasetProfileTableData = this.datasetProfileManager.getPaged(datasetProfileTableRequestItem); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem>().status(ApiMessageCode.NO_MESSAGE).payload(datasetProfileTableData)); } @@ -116,7 +120,7 @@ public class Admin extends BaseController { @Transactional @RequestMapping(method = RequestMethod.DELETE, value = {"{id}"}, consumes = "application/json", produces = "application/json") public @ResponseBody - ResponseEntity> inactivate(@PathVariable String id, Principal principal) { + ResponseEntity> inactivate(@PathVariable String id, @ClaimedAuthorities(claims = {ADMIN}) Principal principal) { try { eu.eudat.data.entities.DatasetProfile ret = AdminManager.inactivate(this.getApiContext().getOperationsContext().getDatabaseRepository().getDatasetProfileDao(), this.getApiContext().getOperationsContext().getDatabaseRepository().getDatasetDao(), id); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE)); @@ -149,4 +153,8 @@ public class Admin extends BaseController { .status(ApiMessageCode.SUCCESS_MESSAGE).message("")); } + @RequestMapping(method = RequestMethod.GET, value = {"/getRDACommonStandards"}, produces = "application/json") + public ResponseEntity getRDACommonStandards(@ClaimedAuthorities(claims = {ADMIN}) Principal principal) { + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem>().status(ApiMessageCode.SUCCESS_MESSAGE).payload(configLoader.getRdaProperties())); + } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/DMPProfileController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/DMPProfileController.java index a53653305..1a54587fa 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/DMPProfileController.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/DMPProfileController.java @@ -46,7 +46,7 @@ public class DMPProfileController extends BaseController { @Transactional @RequestMapping(method = RequestMethod.POST, consumes = "application/json", produces = "application/json") public @ResponseBody - ResponseEntity> createOrUpdate(@RequestBody DataManagementPlanProfileListingModel dataManagementPlan, Principal principal) throws Exception { + ResponseEntity> createOrUpdate(@RequestBody DataManagementPlanProfileListingModel dataManagementPlan, @ClaimedAuthorities(claims = {ADMIN}) Principal principal) throws Exception { this.dataManagementProfileManager.createOrUpdate(dataManagementPlan, principal); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE).message("Created")); } diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/DMPs.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/DMPs.java index f7323b650..5208e5d43 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/DMPs.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/DMPs.java @@ -13,6 +13,7 @@ import eu.eudat.exceptions.datamanagementplan.DMPNewVersionException; import eu.eudat.exceptions.datamanagementplan.DMPWithDatasetsDeleteException; import eu.eudat.logic.managers.DataManagementPlanManager; import eu.eudat.logic.managers.DatasetManager; +import eu.eudat.logic.proxy.config.configloaders.ConfigLoader; import eu.eudat.logic.security.claims.ClaimedAuthorities; import eu.eudat.logic.services.ApiContext; import eu.eudat.logic.services.operations.DatabaseRepository; @@ -59,24 +60,26 @@ public class DMPs extends BaseController { private Environment environment; private DataManagementPlanManager dataManagementPlanManager; private DatasetManager datasetManager; + private ConfigLoader configLoader; @Autowired public DMPs(ApiContext apiContext, DynamicGrantConfiguration dynamicGrantConfiguration, Environment environment, - DataManagementPlanManager dataManagementPlanManager, DatasetManager datasetManager) { + DataManagementPlanManager dataManagementPlanManager, DatasetManager datasetManager, ConfigLoader configLoader) { super(apiContext); this.dynamicGrantConfiguration = dynamicGrantConfiguration; this.environment = environment; this.dataManagementPlanManager = dataManagementPlanManager; this.datasetManager = datasetManager; + this.configLoader = configLoader; } - @Transactional + /*@Transactional @RequestMapping(method = RequestMethod.GET, value = {"{id}/unlock"}, produces = "application/json") public @ResponseBody ResponseEntity> unlock(@PathVariable(value = "id") UUID id, Principal principal) throws Exception { this.dataManagementPlanManager.unlock(id); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE).message("Unlocked")); - } + }*/ @RequestMapping(method = RequestMethod.POST, value = {"/paged"}, consumes = "application/json", produces = "application/json") public @ResponseBody @@ -87,10 +90,10 @@ public class DMPs extends BaseController { @RequestMapping(method = RequestMethod.GET, value = {"{id}"}) public @ResponseBody - ResponseEntity getSingle(@PathVariable String id, @RequestHeader("Content-Type") String contentType, Principal principal) throws IllegalAccessException, InstantiationException, IOException { - if (contentType.equals("application/xml") || contentType.equals("application/msword")) { //|| contentType.equals("application/pdf") - ResponseEntity document = this.dataManagementPlanManager.getDocument(id, contentType); - return document; + ResponseEntity getSingle(@PathVariable String id, @RequestHeader("Content-Type") String contentType, + @ClaimedAuthorities(claims = {Authorities.ADMIN, Authorities.MANAGER, Authorities.USER, Authorities.ANONYMOUS}) Principal principal) throws IllegalAccessException, InstantiationException, IOException { + if (contentType.equals("application/xml") || contentType.equals("application/msword")) { + return this.dataManagementPlanManager.getDocument(id, contentType, principal, this.configLoader); } else { eu.eudat.models.data.dmp.DataManagementPlan dataManagementPlan = this.dataManagementPlanManager.getSingle(id, principal, this.dynamicGrantConfiguration); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.NO_MESSAGE).payload(dataManagementPlan)); @@ -106,8 +109,8 @@ public class DMPs extends BaseController { @RequestMapping(method = RequestMethod.GET, value = {"rda/{id}"}) public @ResponseBody - ResponseEntity getRDAJsonDocument(@PathVariable String id, Principal principal) throws IOException { - return this.dataManagementPlanManager.getRDAJsonDocument(id); + ResponseEntity getRDAJsonDocument(@PathVariable String id, @ClaimedAuthorities(claims = {Authorities.ADMIN, Authorities.MANAGER, Authorities.USER, Authorities.ANONYMOUS}) Principal principal) throws IOException { + return this.dataManagementPlanManager.getRDAJsonDocument(id, principal); } @RequestMapping(method = RequestMethod.GET, value = {"/overview/{id}"}) @@ -186,8 +189,9 @@ public class DMPs extends BaseController { @RequestMapping(method = RequestMethod.GET, value = {"/getPDF/{id}"}) public @ResponseBody - ResponseEntity getPDFDocument(@PathVariable String id, @RequestHeader("Content-Type") String contentType) throws IllegalAccessException, IOException, InstantiationException, InterruptedException { - File file = this.dataManagementPlanManager.getWordDocument(id); + ResponseEntity getPDFDocument(@PathVariable String id, @RequestHeader("Content-Type") String contentType, + @ClaimedAuthorities(claims = {Authorities.ADMIN, Authorities.MANAGER, Authorities.USER, Authorities.ANONYMOUS}) Principal principal) throws IllegalAccessException, IOException, InstantiationException, InterruptedException { + File file = this.dataManagementPlanManager.getWordDocument(id, principal, configLoader); String name = file.getName().substring(0, file.getName().length() - 5); File pdffile = datasetManager.convertToPDF(file, environment, name); InputStream resource = new FileInputStream(pdffile); @@ -204,9 +208,7 @@ public class DMPs extends BaseController { resource.close(); Files.deleteIfExists(file.toPath()); Files.deleteIfExists(pdffile.toPath()); - return new ResponseEntity<>(content, - responseHeaders, - HttpStatus.OK); + return new ResponseEntity<>(content, responseHeaders, HttpStatus.OK); } @RequestMapping(method = RequestMethod.POST, value = {"/upload"}) @@ -218,8 +220,10 @@ public class DMPs extends BaseController { @RequestMapping(method = RequestMethod.POST, value = {"/public/paged"}, consumes = "application/json", produces = "application/json") public @ResponseBody - ResponseEntity>> getPublicPaged(@RequestBody DataManagmentPlanPublicTableRequest dmpTableRequest, @RequestParam String fieldsGroup) throws Exception { - DataTableData dmp = this.dataManagementPlanManager.getPaged(dmpTableRequest, fieldsGroup); + ResponseEntity>> getPublicPaged(@RequestBody DataManagmentPlanPublicTableRequest dmpTableRequest, + @ClaimedAuthorities(claims = {Authorities.ADMIN, Authorities.MANAGER, Authorities.USER, Authorities.ANONYMOUS}) Principal principal, + @RequestParam String fieldsGroup) throws Exception { + DataTableData dmp = this.dataManagementPlanManager.getPublicPaged(dmpTableRequest, fieldsGroup, principal); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem>().status(ApiMessageCode.NO_MESSAGE).payload(dmp)); } @@ -262,7 +266,7 @@ public class DMPs extends BaseController { @RequestMapping(method = RequestMethod.POST, value = {"/createZenodoDoi/{id}"}) public ResponseEntity> createZenodoDoi(@PathVariable String id, Principal principal) { try { - String zenodoDOI = this.dataManagementPlanManager.createZenodoDoi(UUID.fromString(id), principal); + String zenodoDOI = this.dataManagementPlanManager.createZenodoDoi(UUID.fromString(id), principal, configLoader); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE).message("Successfully created DOI for Data Datamanagement Plan in question.").payload(zenodoDOI)); } catch (Exception e) { e.printStackTrace(); diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/DataRepositories.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/DataRepositories.java index 68e0d87f6..cd9589615 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/DataRepositories.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/DataRepositories.java @@ -2,12 +2,10 @@ package eu.eudat.controllers; import eu.eudat.data.entities.DataRepository; import eu.eudat.logic.managers.DataRepositoryManager; -import eu.eudat.logic.managers.ResearcherManager; import eu.eudat.logic.proxy.config.exceptions.HugeResultSet; import eu.eudat.logic.proxy.config.exceptions.NoURLFound; import eu.eudat.logic.services.ApiContext; import eu.eudat.models.data.datarepository.DataRepositoryModel; -import eu.eudat.models.data.dmp.Researcher; import eu.eudat.models.data.helpers.responses.ResponseItem; import eu.eudat.models.data.security.Principal; import eu.eudat.types.ApiMessageCode; @@ -18,7 +16,6 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.*; import java.util.List; -import java.util.Map; @RestController @@ -36,18 +33,18 @@ public class DataRepositories extends BaseController { @RequestMapping(method = RequestMethod.GET, produces = "application/json") public @ResponseBody - ResponseEntity>>> listExternalDataRepositories( - @RequestParam(value = "query", required = false) String query, @RequestParam(value = "type", required = false) String type + ResponseEntity>> listExternalDataRepositories( + @RequestParam(value = "query", required = false) String query, @RequestParam(value = "type", required = false) String type, Principal principal ) throws HugeResultSet, NoURLFound { - List> remoteRepos = this.getApiContext().getOperationsContext().getRemoteFetcher().getRepositories(query, type); - return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem>>().status(ApiMessageCode.NO_MESSAGE).payload(remoteRepos)); + List dataRepositoryModels = this.dataRepositoryManager.getDataRepositories(query, type, principal); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem>().status(ApiMessageCode.NO_MESSAGE).payload(dataRepositoryModels)); } @Transactional @RequestMapping(method = RequestMethod.POST, consumes = "application/json", produces = "application/json") public @ResponseBody ResponseEntity> create(@RequestBody eu.eudat.models.data.datarepository.DataRepositoryModel dataRepositoryModel, Principal principal) throws Exception { - DataRepository dataRepository = this.dataRepositoryManager.create(dataRepositoryModel); + DataRepository dataRepository = this.dataRepositoryManager.create(dataRepositoryModel, principal); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().payload(dataRepository).status(ApiMessageCode.SUCCESS_MESSAGE)); } diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/DatasetProfileController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/DatasetProfileController.java index 1202c31ac..5f16cb390 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/DatasetProfileController.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/DatasetProfileController.java @@ -39,18 +39,18 @@ public class DatasetProfileController extends BaseController { this.datasetProfileManager = datasetProfileManager; } - @Transactional +/* @Transactional @RequestMapping(method = RequestMethod.POST, value = {"/datasetprofile/save/{id}"}, consumes = "application/json", produces = "application/json") public ResponseEntity updateDataset(@PathVariable String id, @RequestBody PropertiesModel properties) { eu.eudat.data.entities.Dataset dataset = this.getApiContext().getOperationsContext().getDatabaseRepository().getDatasetDao().find(UUID.fromString(id)); - Map values = new HashMap(); + Map values = new HashMap<>(); properties.toMap(values); JSONObject jobject = new JSONObject(values); dataset.setProperties(jobject.toString()); dataset.setStatus((short) properties.getStatus()); this.getApiContext().getOperationsContext().getDatabaseRepository().getDatasetDao().createOrUpdate(dataset); //TODO return ResponseEntity.status(HttpStatus.OK).body(properties); - } + }*/ @Transactional @RequestMapping(method = RequestMethod.POST, value = {"/datasetprofile/clone/{id}"}, consumes = "application/json", produces = "application/json") diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/DatasetProfiles.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/DatasetProfiles.java index 35375e148..372ad6b1d 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/DatasetProfiles.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/DatasetProfiles.java @@ -1,25 +1,19 @@ package eu.eudat.controllers; -import eu.eudat.data.entities.DMP; import eu.eudat.data.query.items.item.datasetprofile.DatasetProfileAutocompleteRequest; import eu.eudat.data.query.items.table.datasetprofile.DatasetProfileTableRequestItem; -import eu.eudat.exceptions.datamanagementplan.DMPWithDatasetsDeleteException; import eu.eudat.logic.managers.DatasetProfileManager; import eu.eudat.logic.services.ApiContext; import eu.eudat.models.data.datasetprofile.DatasetProfileAutocompleteItem; import eu.eudat.models.data.datasetprofile.DatasetProfileListingModel; -import eu.eudat.models.data.helpers.common.DataTableData; import eu.eudat.models.data.helpers.responses.ResponseItem; -import eu.eudat.models.data.security.Principal; import eu.eudat.types.ApiMessageCode; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.*; import java.util.List; -import java.util.UUID; @RestController @@ -42,10 +36,10 @@ public class DatasetProfiles extends BaseController { return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem>().status(ApiMessageCode.NO_MESSAGE).payload(datasetProfileAutocompleteItems)); } - @RequestMapping(method = RequestMethod.GET, value = {"/datasetprofiles/getAll"}, produces = "application/json") + @RequestMapping(method = RequestMethod.POST, value = {"/datasetprofiles/getAll"}, produces = "application/json") public @ResponseBody - ResponseEntity>> getAll() throws InstantiationException, IllegalAccessException { - List datasetProfileTableData = this.datasetProfileManager.getAll(); + ResponseEntity>> getAll(@RequestBody DatasetProfileTableRequestItem tableRequestItem) throws InstantiationException, IllegalAccessException { + List datasetProfileTableData = this.datasetProfileManager.getAll(tableRequestItem); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem>().status(ApiMessageCode.NO_MESSAGE).payload(datasetProfileTableData)); } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/DatasetWizardController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/DatasetWizardController.java index d07bcd1e0..f25beabdd 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/DatasetWizardController.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/DatasetWizardController.java @@ -1,6 +1,5 @@ package eu.eudat.controllers; -import eu.eudat.data.dao.entities.DatasetDao; import eu.eudat.data.entities.Dataset; import eu.eudat.data.query.items.item.dataset.DatasetWizardAutocompleteRequest; import eu.eudat.data.query.items.item.datasetprofile.DatasetProfileWizardAutocompleteRequest; @@ -8,6 +7,7 @@ import eu.eudat.exceptions.datasetwizard.DatasetWizardCannotUnlockException; import eu.eudat.logic.managers.DatasetManager; import eu.eudat.logic.managers.DatasetWizardManager; import eu.eudat.logic.managers.UserManager; +import eu.eudat.logic.proxy.config.configloaders.ConfigLoader; import eu.eudat.logic.security.claims.ClaimedAuthorities; import eu.eudat.logic.services.ApiContext; import eu.eudat.logic.services.forms.VisibilityRuleService; @@ -48,13 +48,15 @@ public class DatasetWizardController extends BaseController { private Environment environment; private DatasetManager datasetManager; private UserManager userManager; + private ConfigLoader configLoader; @Autowired - public DatasetWizardController(ApiContext apiContext, Environment environment, DatasetManager datasetManager, UserManager userManager) { + public DatasetWizardController(ApiContext apiContext, Environment environment, DatasetManager datasetManager, UserManager userManager, ConfigLoader configLoader) { super(apiContext); this.environment = environment; this.datasetManager = datasetManager; this.userManager = userManager; + this.configLoader = configLoader; } @RequestMapping(method = RequestMethod.POST, value = {"/userDmps"}, produces = "application/json") @@ -79,8 +81,8 @@ public class DatasetWizardController extends BaseController { VisibilityRuleService visibilityRuleService = this.getApiContext().getUtilitiesService().getVisibilityRuleService(); return this.datasetManager.getDocument(id, visibilityRuleService, contentType); } - else if (contentType.equals("application/msword")){ - File file = datasetManager.getWordDocument(this.environment, id, this.getApiContext().getUtilitiesService().getVisibilityRuleService()); + else if (contentType.equals("application/msword")) { + File file = datasetManager.getWordDocument(this.configLoader, id, this.getApiContext().getUtilitiesService().getVisibilityRuleService()); InputStream resource = new FileInputStream(file); HttpHeaders responseHeaders = new HttpHeaders(); responseHeaders.setContentLength(file.length()); @@ -133,7 +135,7 @@ public class DatasetWizardController extends BaseController { @RequestMapping(method = RequestMethod.GET, value = {"/getPDF/{id}"}) public @ResponseBody ResponseEntity getPDFDocument(@PathVariable String id) throws IllegalAccessException, IOException, InstantiationException, InterruptedException { - File file = datasetManager.getWordDocument(this.environment, id, this.getApiContext().getUtilitiesService().getVisibilityRuleService()); + File file = datasetManager.getWordDocument(this.configLoader, id, this.getApiContext().getUtilitiesService().getVisibilityRuleService()); String fileName = file.getName(); if (fileName.endsWith(".docx")){ fileName = fileName.substring(0, fileName.length() - 5); diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/Datasets.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/Datasets.java index 02d56eca6..067cee359 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/Datasets.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/Datasets.java @@ -46,7 +46,8 @@ public class Datasets extends BaseController { @RequestMapping(method = RequestMethod.POST, value = {"/public/paged"}, consumes = "application/json", produces = "application/json") public @ResponseBody - ResponseEntity>> getPublicPaged(@RequestBody DatasetPublicTableRequest datasetTableRequest, @ClaimedAuthorities(claims = {Authorities.ANONYMOUS}) Principal principal) throws Exception { + ResponseEntity>> getPublicPaged(@RequestBody DatasetPublicTableRequest datasetTableRequest, + @ClaimedAuthorities(claims = {Authorities.ADMIN, Authorities.MANAGER, Authorities.USER, Authorities.ANONYMOUS}) Principal principal) throws Exception { DataTableData dataTable = this.datasetManager.getPaged(datasetTableRequest, principal); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem>().status(ApiMessageCode.NO_MESSAGE).payload(dataTable)); } diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/ExternalDatasets.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/ExternalDatasets.java index c118de055..532cacdac 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/ExternalDatasets.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/ExternalDatasets.java @@ -48,7 +48,7 @@ public class ExternalDatasets extends BaseController { ResponseEntity>> getWithExternal( @RequestParam(value = "query", required = false) String query, @RequestParam(value = "type", required = false) String type, Principal principal ) throws NoURLFound, InstantiationException, HugeResultSet, IllegalAccessException { - List dataTable = externalDatasetManager.getWithExternal(query); + List dataTable = externalDatasetManager.getWithExternal(query, type, principal); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem>().payload(dataTable).status(ApiMessageCode.NO_MESSAGE)); } @@ -63,7 +63,7 @@ public class ExternalDatasets extends BaseController { @RequestMapping(method = RequestMethod.POST, value = {"/externaldatasets"}, consumes = "application/json", produces = "application/json") public @ResponseBody ResponseEntity> create(@RequestBody eu.eudat.models.data.externaldataset.ExternalDatasetModel externalDatasetModel, Principal principal) throws Exception { - ExternalDataset externalDataset = this.externalDatasetManager.create(externalDatasetModel); + ExternalDataset externalDataset = this.externalDatasetManager.create(externalDatasetModel, principal); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().payload(externalDataset).status(ApiMessageCode.SUCCESS_MESSAGE)); } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/Grants.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/Grants.java index 0ba69119f..8e8bbb56e 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/Grants.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/Grants.java @@ -60,21 +60,21 @@ public class Grants extends BaseController { return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().payload(grant).status(ApiMessageCode.NO_MESSAGE)); } - @Transactional + /*@Transactional @RequestMapping(method = RequestMethod.POST, consumes = "application/json", produces = "application/json") public @ResponseBody ResponseEntity> addGrant(@Valid @RequestBody eu.eudat.models.data.grant.Grant grant, Principal principal) throws IOException, ParseException { this.grantManager.createOrUpdate(grant, principal); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE).message("Created")); - } + }*/ - @Transactional + /*@Transactional @RequestMapping(method = RequestMethod.DELETE, value = {"{id}"}, consumes = "application/json", produces = "application/json") public @ResponseBody ResponseEntity> inactivate(@PathVariable String id, Principal principal) throws IllegalAccessException, InstantiationException { this.grantManager.inactivate(id); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE)); - } + }*/ @RequestMapping(method = RequestMethod.POST, value = {"/external"}, consumes = "application/json", produces = "application/json") public @ResponseBody diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/Login.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/Login.java index a6315f15a..954ab00e2 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/Login.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/Login.java @@ -3,10 +3,21 @@ package eu.eudat.controllers; import eu.eudat.core.logger.Logger; import eu.eudat.exceptions.security.NullEmailException; import eu.eudat.logic.managers.UserManager; +import eu.eudat.logic.proxy.config.configloaders.ConfigLoader; import eu.eudat.logic.security.CustomAuthenticationProvider; +import eu.eudat.logic.security.customproviders.ConfigurableProvider.models.ConfigurableProvidersModel; import eu.eudat.logic.security.validators.b2access.B2AccessTokenValidator; import eu.eudat.logic.security.validators.b2access.helpers.B2AccessRequest; import eu.eudat.logic.security.validators.b2access.helpers.B2AccessResponseToken; +import eu.eudat.logic.security.validators.configurableProvider.ConfigurableProviderTokenValidator; +import eu.eudat.logic.security.validators.configurableProvider.helpers.ConfigurableProviderRequest; +import eu.eudat.logic.security.validators.configurableProvider.helpers.ConfigurableProviderResponseToken; +import eu.eudat.logic.security.validators.linkedin.LinkedInTokenValidator; +import eu.eudat.logic.security.validators.linkedin.helpers.LinkedInRequest; +import eu.eudat.logic.security.validators.linkedin.helpers.LinkedInResponseToken; +import eu.eudat.logic.security.validators.openaire.OpenAIRETokenValidator; +import eu.eudat.logic.security.validators.openaire.helpers.OpenAIRERequest; +import eu.eudat.logic.security.validators.openaire.helpers.OpenAIREResponseToken; import eu.eudat.logic.security.validators.orcid.ORCIDTokenValidator; import eu.eudat.logic.security.validators.orcid.helpers.ORCIDRequest; import eu.eudat.logic.security.validators.orcid.helpers.ORCIDResponseToken; @@ -37,19 +48,27 @@ public class Login { private TwitterTokenValidator twitterTokenValidator; private B2AccessTokenValidator b2AccessTokenValidator; private ORCIDTokenValidator orcidTokenValidator; + private LinkedInTokenValidator linkedInTokenValidator; + private OpenAIRETokenValidator openAIRETokenValidator; + private ConfigurableProviderTokenValidator configurableProviderTokenValidator; + private ConfigLoader configLoader; private Logger logger; private UserManager userManager; @Autowired public Login(CustomAuthenticationProvider customAuthenticationProvider, AuthenticationService nonVerifiedUserAuthenticationService, - TwitterTokenValidator twitterTokenValidator, B2AccessTokenValidator b2AccessTokenValidator, ORCIDTokenValidator orcidTokenValidator, - UserManager userManager ,Logger logger) { + TwitterTokenValidator twitterTokenValidator, LinkedInTokenValidator linkedInTokenValidator, B2AccessTokenValidator b2AccessTokenValidator, + ORCIDTokenValidator orcidTokenValidator, OpenAIRETokenValidator openAIRETokenValidator, ConfigurableProviderTokenValidator configurableProviderTokenValidator, ConfigLoader configLoader, UserManager userManager, Logger logger) { this.customAuthenticationProvider = customAuthenticationProvider; this.nonVerifiedUserAuthenticationService = nonVerifiedUserAuthenticationService; this.twitterTokenValidator = twitterTokenValidator; + this.linkedInTokenValidator = linkedInTokenValidator; this.b2AccessTokenValidator = b2AccessTokenValidator; this.orcidTokenValidator = orcidTokenValidator; + this.openAIRETokenValidator = openAIRETokenValidator; + this.configurableProviderTokenValidator = configurableProviderTokenValidator; + this.configLoader = configLoader; this.logger = logger; this.userManager = userManager; } @@ -76,6 +95,12 @@ public class Login { return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().payload(this.twitterTokenValidator.getRequestToken()).status(ApiMessageCode.NO_MESSAGE)); } + @RequestMapping(method = RequestMethod.POST, value = {"/linkedInRequestToken"}, produces = "application/json", consumes = "application/json") + public @ResponseBody + ResponseEntity> linkedInRequestToken(@RequestBody LinkedInRequest linkedInRequest) { + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().payload(this.linkedInTokenValidator.getAccessToken(linkedInRequest)).status(ApiMessageCode.NO_MESSAGE)); + } + @RequestMapping(method = RequestMethod.POST, value = {"/b2AccessRequestToken"}, produces = "application/json", consumes = "application/json") public @ResponseBody ResponseEntity> b2AccessRequestToken(@RequestBody B2AccessRequest b2AccessRequest) { @@ -88,6 +113,18 @@ public class Login { return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().payload(this.orcidTokenValidator.getAccessToken(orcidRequest)).status(ApiMessageCode.NO_MESSAGE)); } + @RequestMapping(method = RequestMethod.POST, value = {"/openAireRequestToken"}, produces = "application/json", consumes = "application/json") + public @ResponseBody + ResponseEntity> openAIRERequestToken(@RequestBody OpenAIRERequest openAIRERequest) { + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().payload(this.openAIRETokenValidator.getAccessToken(openAIRERequest)).status(ApiMessageCode.NO_MESSAGE)); + } + + @RequestMapping(method = RequestMethod.POST, value = {"/configurableProviderRequestToken"}, produces = "application/json", consumes = "application/json") + public @ResponseBody + ResponseEntity> configurableProviderRequestToken(@RequestBody ConfigurableProviderRequest configurableProviderRequest) { + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().payload(this.configurableProviderTokenValidator.getAccessToken(configurableProviderRequest)).status(ApiMessageCode.NO_MESSAGE)); + } + @RequestMapping(method = RequestMethod.POST, value = {"/me"}, consumes = "application/json", produces = "application/json") public @ResponseBody ResponseEntity> authMe(Principal principal) throws NullEmailException { @@ -103,4 +140,10 @@ public class Login { this.logger.info(principal, "Logged Out"); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.NO_MESSAGE)); } + + @RequestMapping(method = RequestMethod.GET, value = {"/configurableLogin"}, consumes = "application/json", produces = "application/json") + public @ResponseBody + ResponseEntity> getConfigurableProviders() { + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().payload(new ConfigurableProvidersModel().fromDataModel(configLoader.getConfigurableProviders())).status(ApiMessageCode.NO_MESSAGE)); + } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/Organisations.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/Organisations.java index 8ba8d4ac2..76b5557f3 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/Organisations.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/Organisations.java @@ -2,6 +2,7 @@ package eu.eudat.controllers; import eu.eudat.data.query.items.table.organisations.OrganisationsTableRequest; import eu.eudat.logic.managers.OrganisationsManager; +import eu.eudat.logic.proxy.config.ExternalUrlCriteria; import eu.eudat.logic.proxy.config.exceptions.HugeResultSet; import eu.eudat.logic.proxy.config.exceptions.NoURLFound; import eu.eudat.logic.services.ApiContext; @@ -38,7 +39,8 @@ public class Organisations extends BaseController { ResponseEntity> listExternalOrganisations( @RequestParam(value = "query", required = false) String query, @RequestParam(value = "type", required = false) String type ) throws HugeResultSet, NoURLFound { - List> remoteRepos = this.getApiContext().getOperationsContext().getRemoteFetcher().getOrganisations(query, type); + ExternalUrlCriteria externalUrlCriteria = new ExternalUrlCriteria(query); + List> remoteRepos = this.getApiContext().getOperationsContext().getRemoteFetcher().getOrganisations(externalUrlCriteria, type); OrganisationsExternalSourcesModel organisationsExternalSourcesModel = new OrganisationsExternalSourcesModel().fromExternalItem(remoteRepos); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().payload(organisationsExternalSourcesModel).status(ApiMessageCode.NO_MESSAGE)); } diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/QuickWizardController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/QuickWizardController.java index 044700940..adedfcb4f 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/QuickWizardController.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/QuickWizardController.java @@ -44,10 +44,12 @@ public class QuickWizardController extends BaseController { Funder funderEntity; //Create Funder - if (quickWizard.getFunder().getExistFunder() == null - && quickWizard.getFunder().getLabel() == null) { - funderEntity = null; - } else if (quickWizard.getFunder().getExistFunder() == null && quickWizard.getFunder().getLabel() != null){ + if (quickWizard.getFunder() == null) { + throw new Exception("Funder is a mandatory entity"); + } else if (quickWizard.getFunder().getExistFunder() == null && quickWizard.getFunder().getLabel() == null) { + // funderEntity = null; + throw new Exception("Funder is a mandatory entity"); + } else if (quickWizard.getFunder().getExistFunder() == null && quickWizard.getFunder().getLabel() != null) { funderEntity = this.quickWizardManager.createOrUpdate(quickWizard.getFunder().toDataFunder(), principal); } else { funderEntity = quickWizard.getFunder().getExistFunder().toDataModel(); @@ -90,8 +92,6 @@ public class QuickWizardController extends BaseController { return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE).message("Created")); } - - @RequestMapping(method = RequestMethod.POST, value = {"/datasetcreate"}, consumes = "application/json", produces = "application/json") public @ResponseBody ResponseEntity> addDatasetWizard(@RequestBody DatasetCreateWizardModel datasetCreateWizardModel, Principal principal) throws Exception{ @@ -101,5 +101,4 @@ public class QuickWizardController extends BaseController { return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE).message("Dataset added!")); } - } diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/Registries.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/Registries.java index 1134d4317..6289d4f0f 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/Registries.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/Registries.java @@ -9,7 +9,6 @@ import eu.eudat.models.data.helpers.responses.ResponseItem; import eu.eudat.models.data.registries.RegistryModel; import eu.eudat.models.data.security.Principal; import eu.eudat.types.ApiMessageCode; -import org.apache.regexp.RE; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -17,7 +16,6 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.*; import java.util.List; -import java.util.Map; @RestController @@ -35,17 +33,17 @@ public class Registries extends BaseController { @RequestMapping(method = RequestMethod.GET, value = {"/external/registries"}, produces = "application/json") public @ResponseBody - ResponseEntity>>> listExternalRegistries(@RequestParam(value = "query", required = false) String query - , @RequestParam(value = "type", required = false) String type) throws HugeResultSet, NoURLFound { - List> remoteRepos = this.getApiContext().getOperationsContext().getRemoteFetcher().getRegistries(query, type); - return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem>>().payload(remoteRepos).status(ApiMessageCode.NO_MESSAGE)); + ResponseEntity>> listExternalRegistries(@RequestParam(value = "query", required = false) String query + , @RequestParam(value = "type", required = false) String type, Principal principal) throws HugeResultSet, NoURLFound { + List registryModels = this.registryManager.getRegistries(query, type, principal); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem>().payload(registryModels).status(ApiMessageCode.NO_MESSAGE)); } @Transactional @RequestMapping(method = RequestMethod.POST, value = {"/registries"}, consumes = "application/json", produces = "application/json") public @ResponseBody ResponseEntity> create(@RequestBody RegistryModel registryModel, Principal principal) throws Exception { - Registry registry = this.registryManager.create(registryModel); + Registry registry = this.registryManager.create(registryModel, principal); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().payload(registry).status(ApiMessageCode.SUCCESS_MESSAGE)); } diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/Researchers.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/Researchers.java index 8a73d28f3..b6f7b8da3 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/Researchers.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/Researchers.java @@ -36,7 +36,7 @@ public class Researchers extends BaseController { @RequestMapping(method = RequestMethod.POST, value = {"/getWithExternal"}, consumes = "application/json", produces = "application/json") public @ResponseBody ResponseEntity>> getWithExternal(@RequestBody ResearcherCriteriaRequest researcherCriteriaRequest, Principal principal) throws HugeResultSet, NoURLFound { - List dataTable = this.researcherManager.getCriteriaWithExternal(researcherCriteriaRequest); + List dataTable = this.researcherManager.getCriteriaWithExternal(researcherCriteriaRequest, principal); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem>().payload(dataTable).status(ApiMessageCode.NO_MESSAGE)); } @@ -44,7 +44,7 @@ public class Researchers extends BaseController { @RequestMapping(method = RequestMethod.POST, consumes = "application/json", produces = "application/json") public @ResponseBody ResponseEntity> create(@RequestBody eu.eudat.models.data.researcher.Researcher researcher, Principal principal) throws Exception { - this.researcherManager.create(researcher); + this.researcherManager.create(researcher, principal); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE)); } diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/Services.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/Services.java index 36b2703cb..02bfd279e 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/Services.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/Services.java @@ -16,7 +16,6 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.*; import java.util.List; -import java.util.Map; @RestController @@ -34,18 +33,18 @@ public class Services extends BaseController { @RequestMapping(method = RequestMethod.GET, value = {"/external/services"}, produces = "application/json") public @ResponseBody - ResponseEntity>>> listExternalServices( - @RequestParam(value = "query", required = false) String query, @RequestParam(value = "type", required = false) String type + ResponseEntity>> listExternalServices( + @RequestParam(value = "query", required = false) String query, @RequestParam(value = "type", required = false) String type, Principal principal ) throws HugeResultSet, NoURLFound { - List> remoteRepos = this.getApiContext().getOperationsContext().getRemoteFetcher().getServices(query, type); - return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem>>().payload(remoteRepos).status(ApiMessageCode.NO_MESSAGE)); + List serviceModels = this.serviceManager.getServices(query, type, principal); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem>().payload(serviceModels).status(ApiMessageCode.NO_MESSAGE)); } @Transactional @RequestMapping(method = RequestMethod.POST, value = {"/services"}, consumes = "application/json", produces = "application/json") public @ResponseBody ResponseEntity> create(@RequestBody ServiceModel serviceModel, Principal principal) throws Exception { - Service service = serviceManager.create(serviceModel); + Service service = serviceManager.create(serviceModel, principal); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().payload(service).status(ApiMessageCode.SUCCESS_MESSAGE)); } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/TagController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/TagController.java index 02bcb3186..4f1bad5cf 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/TagController.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/TagController.java @@ -5,6 +5,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import eu.eudat.elastic.criteria.TagCriteria; import eu.eudat.elastic.entities.Dataset; import eu.eudat.elastic.repository.Repository; +import eu.eudat.logic.proxy.config.ExternalUrlCriteria; import eu.eudat.logic.proxy.config.exceptions.HugeResultSet; import eu.eudat.logic.proxy.config.exceptions.NoURLFound; import eu.eudat.logic.services.ApiContext; @@ -47,14 +48,10 @@ public class TagController extends BaseController { public @ResponseBody ResponseEntity> listExternalTagModel( @RequestParam(value = "query", required = false) String query, @RequestParam(value = "type", required = false) String type) throws HugeResultSet, NoURLFound, IOException { - List> remoteRepos = this.getApiContext().getOperationsContext().getRemoteFetcher().getTags(query, type); + ExternalUrlCriteria externalUrlCriteria = new ExternalUrlCriteria(query); + List> remoteRepos = this.getApiContext().getOperationsContext().getRemoteFetcher().getTags(externalUrlCriteria, type); TagExternalSourcesModel researchersExternalSourcesModel = new TagExternalSourcesModel().fromExternalItem(remoteRepos); -// ObjectMapper mapper = new ObjectMapper(); -// String fileUrl = this.environment.getProperty("configuration.resources.path") + this.environment.getProperty("dataset.tags.mock"); -// List> data = mapper.readValue(new File(fileUrl), new TypeReference>>(){}); -// TagExternalSourcesModel researchersExternalSourcesModel = new TagExternalSourcesModel().fromExternalItem(data); - return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().payload(researchersExternalSourcesModel).status(ApiMessageCode.NO_MESSAGE)); } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/handlers/PrincipalArgumentResolver.java b/dmp-backend/web/src/main/java/eu/eudat/logic/handlers/PrincipalArgumentResolver.java index 7e304042f..ebc287b72 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/handlers/PrincipalArgumentResolver.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/handlers/PrincipalArgumentResolver.java @@ -37,13 +37,17 @@ public final class PrincipalArgumentResolver implements HandlerMethodArgumentRes public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception { String token = nativeWebRequest.getHeader("AuthToken"); - Boolean checkMailNull = ((ServletWebRequest) nativeWebRequest).getRequest().getRequestURI().startsWith("/api/emailConfirmation"); + boolean checkMailNull = ((ServletWebRequest) nativeWebRequest).getRequest().getRequestURI().startsWith("/api/emailConfirmation"); AuthenticationService authenticationService = checkMailNull ? this.nonVerifiedUserAuthenticationService : this.verifiedUserAuthenticationService; Optional claimsAnnotation = Arrays.stream(methodParameter.getParameterAnnotations()).filter(annotation -> annotation.annotationType().equals(ClaimedAuthorities.class)).findAny(); List claimList = claimsAnnotation.map(annotation -> Arrays.asList(((ClaimedAuthorities) annotation).claims())).orElse(Authorities.all()); - if (claimList.size() == 1 && claimList.get(0).equals(Authorities.ANONYMOUS)) + if (claimList.size() == 1 && claimList.get(0).equals(Authorities.ANONYMOUS)) { return new Principal(); + } else if (claimList.contains(Authorities.ANONYMOUS) && token == null) { + return new Principal(); + } + if (token == null) throw new UnauthorisedException("Authentication Information Is Missing"); UUID authToken; try { diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DashBoardManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DashBoardManager.java index c1f7ac711..d351e492b 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DashBoardManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DashBoardManager.java @@ -8,7 +8,7 @@ import eu.eudat.data.dao.entities.DMPDao; import eu.eudat.data.dao.entities.DatasetDao; import eu.eudat.data.dao.entities.OrganisationDao; import eu.eudat.data.dao.entities.GrantDao; -import eu.eudat.data.entities.UserInfo; +import eu.eudat.data.entities.*; import eu.eudat.logic.builders.model.models.RecentActivityDataBuilder; import eu.eudat.logic.services.ApiContext; import eu.eudat.logic.services.operations.DatabaseRepository; @@ -40,23 +40,26 @@ public class DashBoardManager { public DashBoardStatistics getStatistics() { DashBoardStatistics statistics = new DashBoardStatistics(); - DatasetCriteria datasetCriteria = new DatasetCriteria(); DataManagementPlanCriteria dataManagementPlanCriteria = new DataManagementPlanCriteria(); OrganisationCriteria organisationCriteria = new OrganisationCriteria(); - datasetCriteria.setAllVersions(false); dataManagementPlanCriteria.setAllVersions(false); - organisationCriteria.setPublic(false); + dataManagementPlanCriteria.setIsPublic(true); + organisationCriteria.setPublic(true); - CompletableFuture dmpFuture = databaseRepository.getDmpDao().getWithCriteria(dataManagementPlanCriteria).countAsync() - .whenComplete((dmpsStats, throwable) -> statistics.setTotalDataManagementPlanCount(dmpsStats)); - CompletableFuture datasetFuture = databaseRepository.getDatasetDao().getWithCriteria(datasetCriteria).countAsync() - .whenComplete((datasetsStats, throwable) -> statistics.setTotalDataSetCount(datasetsStats)); - CompletableFuture grantFuture = databaseRepository.getGrantDao().asQueryable().countAsync() - .whenComplete((grantsStats, throwable) -> statistics.setTotalGrantCount(grantsStats)); - CompletableFuture organisationFuture = databaseRepository.getOrganisationDao().getWithCriteria(organisationCriteria).countAsync() - .whenComplete((organisationStats, throwable) -> statistics.setTotalOrganisationCount(organisationStats)); + List dmps = databaseRepository.getDmpDao().getWithCriteria(dataManagementPlanCriteria).toList(); + long numberOfDatasets = 0; + LinkedList grants = new LinkedList<>(); + for (DMP dmp : dmps) { + numberOfDatasets = numberOfDatasets + dmp.getDataset().stream() + .filter(item -> item.getStatus() == Dataset.Status.FINALISED.getValue()).count(); + grants.add(dmp.getGrant()); + } + + statistics.setTotalDataManagementPlanCount((long) dmps.size()); + statistics.setTotalDataSetCount(numberOfDatasets); + statistics.setTotalGrantCount(grants.stream().distinct().count()); + statistics.setTotalOrganisationCount(databaseRepository.getOrganisationDao().getWithCriteria(organisationCriteria).count()); - CompletableFuture.allOf(dmpFuture, datasetFuture, grantFuture, organisationFuture).join(); return statistics; } @@ -73,9 +76,9 @@ public class DashBoardManager { DataManagementPlanCriteria dataManagementPlanCriteria = new DataManagementPlanCriteria(); dataManagementPlanCriteria.setAllVersions(false); GrantCriteria grantCriteria = new GrantCriteria(); - OrganisationCriteria organisationCriteria = new OrganisationCriteria(); - CompletableFuture dmpFuture = dataManagementPlanRepository.getAuthenticated(dataManagementPlanRepository.getWithCriteria(dataManagementPlanCriteria), principal.getId()).countAsync() + List roles = new LinkedList<>(); + CompletableFuture dmpFuture = dataManagementPlanRepository.getAuthenticated(dataManagementPlanRepository.getWithCriteria(dataManagementPlanCriteria), principal.getId(), roles).countAsync() .whenComplete((dmpsStats, throwable) -> statistics.setTotalDataManagementPlanCount(dmpsStats)); CompletableFuture datasetFuture = datasetRepository.getAuthenticated(datasetRepository.getWithCriteria(datasetCriteria), user).countAsync() .whenComplete((datasetsStats, throwable) -> statistics.setTotalDataSetCount(datasetsStats)); @@ -102,7 +105,8 @@ public class DashBoardManager { GrantCriteria grantCriteria = new GrantCriteria(); RecentActivityDataBuilder recentActivityDataBuilder = apiContext.getOperationsContext().getBuilderFactory().getBuilder(RecentActivityDataBuilder.class); - CompletableFuture> dmps = dataManagementPlanRepository.getAuthenticated(dataManagementPlanRepository.getWithCriteria(dataManagementPlanCriteria), principal.getId()) + List roles = new LinkedList<>(); + CompletableFuture> dmps = dataManagementPlanRepository.getAuthenticated(dataManagementPlanRepository.getWithCriteria(dataManagementPlanCriteria), principal.getId(), roles) .withHint("dmpRecentActivity") .orderBy((builder, root) -> builder.desc(root.get("modified"))) .take(numberofactivities) @@ -135,8 +139,9 @@ public class DashBoardManager { DatasetDao datasetRepository = databaseRepository.getDatasetDao(); GrantDao grantRepository = databaseRepository.getGrantDao(); + List roles = new LinkedList<>(); List searchBarItems = new LinkedList<>(); - CompletableFuture> dmps = dataManagementPlanRepository.getAuthenticated(dataManagementPlanRepository.asQueryable(), principal.getId()) + CompletableFuture> dmps = dataManagementPlanRepository.getAuthenticated(dataManagementPlanRepository.asQueryable(), principal.getId(), roles) .withHint("dmpRecentActivity") .where((builder, root) -> builder.like(builder.upper(root.get("label")), "%" + like.toUpperCase() + "%")) .orderBy((builder, root) -> builder.desc(root.get("modified"))) diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java index 094169e14..8dde96a2d 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java @@ -16,6 +16,7 @@ import eu.eudat.exceptions.datamanagementplan.DMPNewVersionException; import eu.eudat.exceptions.datamanagementplan.DMPWithDatasetsDeleteException; import eu.eudat.exceptions.security.UnauthorisedException; import eu.eudat.logic.builders.entity.UserInfoBuilder; +import eu.eudat.logic.proxy.config.configloaders.ConfigLoader; import eu.eudat.logic.services.ApiContext; import eu.eudat.logic.services.forms.VisibilityRuleService; import eu.eudat.logic.services.operations.DatabaseRepository; @@ -39,6 +40,7 @@ import eu.eudat.models.data.listingmodels.DataManagementPlanListingModel; import eu.eudat.models.data.listingmodels.DataManagementPlanOverviewModel; import eu.eudat.models.data.listingmodels.DatasetListingModel; import eu.eudat.models.data.listingmodels.UserInfoListingModel; +import eu.eudat.models.data.rda.RDAExportModel; import eu.eudat.models.data.security.Principal; import eu.eudat.models.data.user.composite.PagedDatasetProfile; import eu.eudat.models.data.userinfo.UserListingModel; @@ -59,6 +61,8 @@ import org.springframework.web.multipart.MultipartFile; import org.w3c.dom.Document; import org.w3c.dom.Element; +import javax.persistence.criteria.Join; +import javax.persistence.criteria.JoinType; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Unmarshaller; @@ -92,7 +96,9 @@ public class DataManagementPlanManager { public DataTableData getPaged(DataManagementPlanTableRequest dataManagementPlanTableRequest, Principal principal, String fieldsGroup) throws Exception { UUID principalID = principal.getId(); QueryableList items = apiContext.getOperationsContext().getDatabaseRepository().getDmpDao().getWithCriteria(dataManagementPlanTableRequest.getCriteria()); - QueryableList authItems = apiContext.getOperationsContext().getDatabaseRepository().getDmpDao().getAuthenticated(items, principalID); + List roles = new LinkedList<>(); + if (dataManagementPlanTableRequest.getCriteria().getRole() != null) roles.add(dataManagementPlanTableRequest.getCriteria().getRole()); + QueryableList authItems = apiContext.getOperationsContext().getDatabaseRepository().getDmpDao().getAuthenticated(items, principalID, roles); QueryableList pagedItems = PaginationManager.applyPaging(authItems, dataManagementPlanTableRequest); DataTableData dataTable = new DataTableData<>(); @@ -115,20 +121,27 @@ public class DataManagementPlanManager { .whenComplete((resultList, throwable) -> dataTable.setData(resultList)); } else { itemsFuture = pagedItems - .selectAsync(item -> new DataManagementPlanListingModel().fromDataModel(item)) + .selectAsync(item -> new DataManagementPlanListingModel().fromDataModelAssociatedProfiles(item)) .whenComplete((resultList, throwable) -> dataTable.setData(resultList)); } - CompletableFuture countFuture = authItems.countAsync().whenComplete((count, throwable) -> { - dataTable.setTotalCount(count); - }); + CompletableFuture countFuture = authItems.countAsync().whenComplete((count, throwable) -> + dataTable.setTotalCount(count) + ); CompletableFuture.allOf(itemsFuture, countFuture).join(); return dataTable; } - public DataTableData getPaged(DataManagmentPlanPublicTableRequest dataManagementPlanPublicTableRequest, String fieldsGroup) throws Exception { + public DataTableData getPublicPaged(DataManagmentPlanPublicTableRequest dataManagementPlanPublicTableRequest, String fieldsGroup, Principal principal) throws Exception { dataManagementPlanPublicTableRequest.setQuery(databaseRepository.getDmpDao().asQueryable().withHint(HintedModelFactory.getHint(DataManagementPlanListingModel.class))); QueryableList items = dataManagementPlanPublicTableRequest.applyCriteria(); + + if (principal.getId() != null && dataManagementPlanPublicTableRequest.getCriteria().getRole() != null) { + items.where((builder, root) -> { + Join userJoin = root.join("users", JoinType.LEFT); + return builder.and(builder.equal(userJoin.join("user", JoinType.LEFT).get("id"), principal.getId()), builder.equal(userJoin.get("role"), dataManagementPlanPublicTableRequest.getCriteria().getRole())); + }); + } QueryableList pagedItems = PaginationManager.applyPaging(items, dataManagementPlanPublicTableRequest); DataTableData dataTable = new DataTableData<>(); @@ -163,44 +176,38 @@ public class DataManagementPlanManager { return; } - public File getWordDocument(String id) throws InstantiationException, IllegalAccessException, IOException { + public File getWordDocument(String id, Principal principal, ConfigLoader configLoader) throws IOException { WordBuilder wordBuilder = new WordBuilder(); VisibilityRuleService visibilityRuleService = this.utilitiesService.getVisibilityRuleService(); DatasetWizardModel dataset = new DatasetWizardModel(); - String fileUrl = environment.getProperty("configuration.h2020template"); - InputStream is = new URL(Paths.get(fileUrl).toUri().toURL().toString()).openStream(); - XWPFDocument document = new XWPFDocument(is); + XWPFDocument document = configLoader.getDocument(); eu.eudat.data.entities.DMP dmpEntity = databaseRepository.getDmpDao().find(UUID.fromString(id)); + if (!dmpEntity.isPublic() && dmpEntity.getUsers().stream().filter(userInfo -> userInfo.getUser().getId() == principal.getId()).collect(Collectors.toList()).size() == 0) + throw new UnauthorisedException(); - // Space above DMP title. - XWPFParagraph parAboveDmpTitle = document.createParagraph(); - XWPFParagraph parAboveDmpTitle1 = document.createParagraph(); - XWPFParagraph parAboveDmpTitle2 = document.createParagraph(); - XWPFParagraph parAboveDmpTitle3 = document.createParagraph(); - + // DMP info on top of the document. + wordBuilder.addParagraphContent("Data Management Plan Information", document, ParagraphStyle.HEADER1, BigInteger.ZERO); // DMP title custom style. - //wordBuilder.addParagraphContent(dmpEntity.getLabel(), document, ParagraphStyle.TITLE, BigInteger.ZERO); - XWPFParagraph dmpLabelParagraph = document.createParagraph(); - XWPFRun run = dmpLabelParagraph.createRun(); - run.setText(dmpEntity.getLabel()); - run.setBold(true); - run.setFontSize(20); - - // Space below DMP title. - XWPFParagraph parBelowDmpTitle = document.createParagraph(); - + wordBuilder.addParagraphContent(dmpEntity.getLabel(), document, ParagraphStyle.HEADER2, BigInteger.ZERO); wordBuilder.addParagraphContent(dmpEntity.getDescription(), document, ParagraphStyle.TEXT, BigInteger.ZERO); - wordBuilder.addParagraphContent("Organisations", document, ParagraphStyle.HEADER2, BigInteger.ZERO); + wordBuilder.addParagraphContent("Funder", document, ParagraphStyle.HEADER3, BigInteger.ZERO); + if (dmpEntity.getGrant().getFunder() != null) + wordBuilder.addParagraphContent(dmpEntity.getGrant().getFunder().getLabel(), document, ParagraphStyle.TEXT, BigInteger.ZERO); + + wordBuilder.addParagraphContent("Grant", document, ParagraphStyle.HEADER3, BigInteger.ZERO); + wordBuilder.addParagraphContent(dmpEntity.getGrant().getLabel(), document, ParagraphStyle.TEXT, BigInteger.ZERO); + + wordBuilder.addParagraphContent("Organisations", document, ParagraphStyle.HEADER3, BigInteger.ZERO); if (dmpEntity.getOrganisations().size() > 0) { - wordBuilder.addParagraphContent(dmpEntity.getOrganisations().stream().map(x -> x.getLabel()).collect(Collectors.joining(", ")) + wordBuilder.addParagraphContent(dmpEntity.getOrganisations().stream().map(Organisation::getLabel).collect(Collectors.joining(", ")) , document, ParagraphStyle.TEXT, BigInteger.ZERO); } - wordBuilder.addParagraphContent("Researchers", document, ParagraphStyle.HEADER2, BigInteger.ZERO); + wordBuilder.addParagraphContent("Researchers", document, ParagraphStyle.HEADER3, BigInteger.ZERO); if (dmpEntity.getResearchers().size() > 0) { - wordBuilder.addParagraphContent(dmpEntity.getResearchers().stream().map(x -> x.getLabel()).collect(Collectors.joining(", ")) + wordBuilder.addParagraphContent(dmpEntity.getResearchers().stream().map(Researcher::getLabel).collect(Collectors.joining(", ")) , document, ParagraphStyle.TEXT, BigInteger.ZERO); } @@ -213,51 +220,108 @@ public class DataManagementPlanManager { XWPFParagraph parBreakDMP = document.createParagraph(); parBreakDMP.setPageBreak(true); - wordBuilder.addParagraphContent("Datasets", document, ParagraphStyle.TITLE, BigInteger.ZERO); - dmpEntity.getDataset().stream().forEach(datasetEntity -> { - Map properties = new HashMap<>(); - if (datasetEntity.getProperties() != null) { - JSONObject jobject = new JSONObject(datasetEntity.getProperties()); - properties = jobject.toMap(); - } + wordBuilder.addParagraphContent("Datasets", document, ParagraphStyle.HEADER1, BigInteger.ZERO); + // Space below Datasets. + XWPFParagraph parBreakDatasets = document.createParagraph(); + dmpEntity.getDataset().stream() + .filter(item -> item.getStatus() != Dataset.Status.CANCELED.getValue()) + .filter(item -> item.getStatus() != Dataset.Status.DELETED.getValue()) + .forEach(datasetEntity -> { + Map properties = new HashMap<>(); + if (datasetEntity.getProperties() != null) { + JSONObject jObject = new JSONObject(datasetEntity.getProperties()); + properties = jObject.toMap(); + } - // Custom style for the Dataset title. - //wordBuilder.addParagraphContent("Title: " + datasetEntity.getLabel(), document, ParagraphStyle.HEADER1, BigInteger.ZERO); - XWPFParagraph datasetLabelParagraph = document.createParagraph(); - XWPFRun runDatasetTitle1 = datasetLabelParagraph.createRun(); - runDatasetTitle1.setText("Title: "); - runDatasetTitle1.setBold(true); - runDatasetTitle1.setFontSize(12); - XWPFRun runDatasetTitle = datasetLabelParagraph.createRun(); - runDatasetTitle.setText(datasetEntity.getLabel()); - runDatasetTitle.setColor("2E75B6"); - runDatasetTitle.setBold(true); - runDatasetTitle.setFontSize(12); + // Custom style for the Dataset title. + //wordBuilder.addParagraphContent("Title: " + datasetEntity.getLabel(), document, ParagraphStyle.HEADER1, BigInteger.ZERO); + XWPFParagraph datasetLabelParagraph = document.createParagraph(); + datasetLabelParagraph.setStyle("Heading2"); + XWPFRun runDatasetTitle1 = datasetLabelParagraph.createRun(); + runDatasetTitle1.setText("Title: "); + runDatasetTitle1.setBold(true); + runDatasetTitle1.setFontSize(12); + XWPFRun runDatasetTitle = datasetLabelParagraph.createRun(); + runDatasetTitle.setText(datasetEntity.getLabel()); + runDatasetTitle.setColor("2E75B6"); + runDatasetTitle.setBold(true); + runDatasetTitle.setFontSize(12); - XWPFParagraph datasetTemplateParagraph = document.createParagraph(); - XWPFRun runDatasetTemplate1 = datasetTemplateParagraph.createRun(); - runDatasetTemplate1.setText("Template: "); - runDatasetTemplate1.setBold(true); - runDatasetTemplate1.setFontSize(12); - XWPFRun runDatasetTemplate = datasetTemplateParagraph.createRun(); - runDatasetTemplate.setText(datasetEntity.getProfile().getLabel()); - runDatasetTemplate.setColor("2E75B6"); - runDatasetTemplate.setBold(true); - runDatasetTemplate.setFontSize(12); + XWPFParagraph datasetTemplateParagraph = document.createParagraph(); + datasetTemplateParagraph.setStyle("Heading3"); + XWPFRun runDatasetTemplate1 = datasetTemplateParagraph.createRun(); + runDatasetTemplate1.setText("Template: "); + runDatasetTemplate1.setBold(true); + runDatasetTemplate1.setFontSize(12); + XWPFRun runDatasetTemplate = datasetTemplateParagraph.createRun(); + runDatasetTemplate.setText(datasetEntity.getProfile().getLabel()); + runDatasetTemplate.setColor("2E75B6"); + runDatasetTemplate.setBold(true); + runDatasetTemplate.setFontSize(12); + + XWPFParagraph externalReferencesParagraph = document.createParagraph(); + externalReferencesParagraph.setStyle("Heading3"); + XWPFRun externalReferencesRun = externalReferencesParagraph.createRun(); + externalReferencesRun.setText("External References"); + externalReferencesRun.setColor("2E75B6"); + externalReferencesRun.setBold(true); + externalReferencesRun.setFontSize(12); + + wordBuilder.addParagraphContent("Data Repositories", document, ParagraphStyle.HEADER4, BigInteger.ZERO); + if (datasetEntity.getDatasetDataRepositories().size() > 0) { + wordBuilder.addParagraphContent(datasetEntity.getDatasetDataRepositories().stream().map(DatasetDataRepository::getDataRepository).map(DataRepository::getLabel).collect(Collectors.joining(", ")) + , document, ParagraphStyle.TEXT, BigInteger.ZERO); + } + wordBuilder.addParagraphContent("External Datasets", document, ParagraphStyle.HEADER4, BigInteger.ZERO); + if (datasetEntity.getDatasetExternalDatasets().size() > 0) { + wordBuilder.addParagraphContent(datasetEntity.getDatasetExternalDatasets().stream().map(DatasetExternalDataset::getExternalDataset).map(ExternalDataset::getLabel).collect(Collectors.joining(", ")) + , document, ParagraphStyle.TEXT, BigInteger.ZERO); + } + wordBuilder.addParagraphContent("Registries", document, ParagraphStyle.HEADER4, BigInteger.ZERO); + if (datasetEntity.getRegistries().size() > 0) { + wordBuilder.addParagraphContent(datasetEntity.getRegistries().stream().map(Registry::getLabel).collect(Collectors.joining(", ")) + , document, ParagraphStyle.TEXT, BigInteger.ZERO); + } + wordBuilder.addParagraphContent("Services", document, ParagraphStyle.HEADER4, BigInteger.ZERO); + if (datasetEntity.getServices().size() > 0) { + wordBuilder.addParagraphContent(datasetEntity.getServices().stream().map(DatasetService::getService).map(Service::getLabel).collect(Collectors.joining(", ")) + , document, ParagraphStyle.TEXT, BigInteger.ZERO); + } + /*wordBuilder.addParagraphContent("Tags", document, ParagraphStyle.HEADER3, BigInteger.ZERO); + if (datasetEntity.().size() > 0) { + wordBuilder.addParagraphContent(datasetEntity.getServices().stream().map(DatasetService::getService).map(Service::getLabel).collect(Collectors.joining(", ")) + , document, ParagraphStyle.HEADER4, BigInteger.ZERO); + }*/ + + + wordBuilder.addParagraphContent(datasetEntity.getDescription(), document, ParagraphStyle.TEXT, BigInteger.ZERO); + + // Dataset Description custom style. + XWPFParagraph datasetDescriptionParagraph = document.createParagraph(); + datasetDescriptionParagraph.setStyle("Heading3"); + XWPFRun datasetDescriptionRun = datasetDescriptionParagraph.createRun(); + datasetDescriptionRun.setText("Dataset Description"); + datasetDescriptionRun.setColor("2E75B6"); + datasetDescriptionRun.setBold(true); + datasetDescriptionRun.setFontSize(12); + + PagedDatasetProfile pagedDatasetProfile = datasetManager.getPagedProfile(dataset, datasetEntity); + visibilityRuleService.setProperties(properties); + visibilityRuleService.buildVisibilityContext(pagedDatasetProfile.getRules()); + try { + wordBuilder.build(document, pagedDatasetProfile, visibilityRuleService); + } catch (IOException e) { + e.printStackTrace(); + } + // Page break at the end of the Dataset. + XWPFParagraph parBreakDataset = document.createParagraph(); + }); + + // Removes the top empty headings. + for (int i = 0; i < 6; i++) { + document.removeBodyElement(0); + } - wordBuilder.addParagraphContent(datasetEntity.getDescription(), document, ParagraphStyle.TEXT, BigInteger.ZERO); - wordBuilder.addParagraphContent("Dataset Description", document, ParagraphStyle.HEADER1, BigInteger.ZERO); - PagedDatasetProfile pagedDatasetProfile = datasetManager.getPagedProfile(dataset, datasetEntity); - visibilityRuleService.setProperties(properties); - visibilityRuleService.buildVisibilityContext(pagedDatasetProfile.getRules()); - try { - wordBuilder.build(document, pagedDatasetProfile, visibilityRuleService); - } catch (IOException e) { - e.printStackTrace(); - } - // Page break at the end of the Dataset. - XWPFParagraph parBreakDataset = document.createParagraph(); - }); String fileName = dmpEntity.getLabel(); fileName = fileName.replaceAll("[^a-zA-Z0-9+ ]", ""); File exportFile = new File(fileName + ".docx"); @@ -360,7 +424,8 @@ public class DataManagementPlanManager { public List getWithCriteria(DMPDao dmpsRepository, DataManagementPlanCriteriaRequest dataManagementPlanCriteria, Principal principal) throws IllegalAccessException, InstantiationException { UUID principalID = principal.getId(); QueryableList items = dmpsRepository.getWithCriteria(dataManagementPlanCriteria.getCriteria()).withHint(HintedModelFactory.getHint(DataManagementPlan.class)); - QueryableList authenticatedItems = dmpsRepository.getAuthenticated(items, principalID); + List roles = new LinkedList<>(); + QueryableList authenticatedItems = dmpsRepository.getAuthenticated(items, principalID, roles); List datamanagementPlans = authenticatedItems.select(item -> new DataManagementPlan().fromDataModel(item)); return datamanagementPlans; } @@ -429,7 +494,7 @@ public class DataManagementPlanManager { UserInfo user = apiContext.getOperationsContext().getDatabaseRepository().getUserInfoDao().find(principal.getId()); createOrganisationsIfTheyDontExist(newDmp, apiContext.getOperationsContext().getDatabaseRepository().getOrganisationDao()); - createResearchersIfTheyDontExist(newDmp, apiContext.getOperationsContext().getDatabaseRepository().getResearcherDao()); + createResearchersIfTheyDontExist(newDmp, apiContext.getOperationsContext().getDatabaseRepository().getResearcherDao(), user); createFunderIfItDoesntExist(newDmp, apiContext.getOperationsContext().getDatabaseRepository().getFunderDao()); createGrantIfItDoesntExist(newDmp, apiContext.getOperationsContext().getDatabaseRepository().getGrantDao()); if (newDmp.getProject().getLabel() == null || newDmp.getProject().getLabel().trim().isEmpty()) { @@ -445,7 +510,7 @@ public class DataManagementPlanManager { newDmp.setCreated(dmp.getCreated() == null ? new Date() : dmp.getCreated()); if (newDmp.getUsers()!= null && newDmp.getUsers().stream().filter(userInfo -> userInfo.getUser().getId() == principal.getId()) .collect(Collectors.toList()).size() == 0) { - List userDMPList = newDmp.getUsers().stream().collect(Collectors.toList()); + List userDMPList = new ArrayList<>(newDmp.getUsers()); for (UserInfoListingModel userInfoListingModel : dataManagementPlan.getUsers()) { for (UserDMP userDMP : userDMPList) { if (!(userDMP.getUser().getId().equals(userInfoListingModel.getId()))) { @@ -456,7 +521,9 @@ public class DataManagementPlanManager { } checkIfUserCanEditGrant(newDmp, user); - checkIfGrandHasCreationUser(newDmp, user); + assignGrandUserIfInternal(newDmp, user); + assignFunderUserIfInternal(newDmp, user); + assignProjectUserIfInternal(newDmp, user); apiContext.getOperationsContext().getDatabaseRepository().getGrantDao().createOrUpdate(newDmp.getGrant()); newDmp = apiContext.getOperationsContext().getDatabaseRepository().getDmpDao().createOrUpdate(newDmp); @@ -521,9 +588,9 @@ public class DataManagementPlanManager { if (latestVersionDMP.get(0).getVersion().equals(oldDmp.getVersion())) { DMP newDmp = dataManagementPlan.toDataModel(); - createOrganisationsIfTheyDontExist(newDmp, databaseRepository.getOrganisationDao()); - createResearchersIfTheyDontExist(newDmp, databaseRepository.getResearcherDao()); UserInfo user = apiContext.getOperationsContext().getBuilderFactory().getBuilder(UserInfoBuilder.class).id(principal.getId()).build(); + createOrganisationsIfTheyDontExist(newDmp, databaseRepository.getOrganisationDao()); + createResearchersIfTheyDontExist(newDmp, databaseRepository.getResearcherDao(), user); createFunderIfItDoesntExist(newDmp, databaseRepository.getFunderDao()); createGrantIfItDoesntExist(newDmp, databaseRepository.getGrantDao()); @@ -537,7 +604,9 @@ public class DataManagementPlanManager { newDmp.setId(null); checkIfUserCanEditGrant(newDmp, user); - checkIfGrandHasCreationUser(newDmp, user); + assignGrandUserIfInternal(newDmp, user); + assignFunderUserIfInternal(newDmp, user); + assignProjectUserIfInternal(newDmp, user); databaseRepository.getGrantDao().createOrUpdate(newDmp.getGrant()); newDmp = databaseRepository.getDmpDao().createOrUpdate(newDmp); @@ -552,9 +621,10 @@ public class DataManagementPlanManager { public void clone(DataManagementPlanNewVersionModel dataManagementPlan, Principal principal) throws Exception { DMP newDmp = dataManagementPlan.toDataModel(); - createOrganisationsIfTheyDontExist(newDmp, databaseRepository.getOrganisationDao()); - createResearchersIfTheyDontExist(newDmp, databaseRepository.getResearcherDao()); + UserInfo user = apiContext.getOperationsContext().getBuilderFactory().getBuilder(UserInfoBuilder.class).id(principal.getId()).build(); + createOrganisationsIfTheyDontExist(newDmp, databaseRepository.getOrganisationDao()); + createResearchersIfTheyDontExist(newDmp, databaseRepository.getResearcherDao(), user); createFunderIfItDoesntExist(newDmp, databaseRepository.getFunderDao()); createGrantIfItDoesntExist(newDmp, databaseRepository.getGrantDao()); @@ -568,7 +638,9 @@ public class DataManagementPlanManager { newDmp.setId(null); checkIfUserCanEditGrant(newDmp, user); - checkIfGrandHasCreationUser(newDmp, user); + assignGrandUserIfInternal(newDmp, user); + assignFunderUserIfInternal(newDmp, user); + assignProjectUserIfInternal(newDmp, user); databaseRepository.getGrantDao().createOrUpdate(newDmp.getGrant()); newDmp = databaseRepository.getDmpDao().createOrUpdate(newDmp); @@ -588,14 +660,17 @@ public class DataManagementPlanManager { apiContext.getOperationsContext().getDatabaseRepository().getDmpDao().createOrUpdate(oldDmp); } - private void createResearchersIfTheyDontExist(DMP newDmp, ResearcherDao researcherRepository) { + private void createResearchersIfTheyDontExist(DMP newDmp, ResearcherDao researcherRepository, UserInfo user) { if (newDmp.getResearchers() != null && !newDmp.getResearchers().isEmpty()) { for (eu.eudat.data.entities.Researcher researcher : newDmp.getResearchers()) { ResearcherCriteria criteria = new ResearcherCriteria(); criteria.setLike(researcher.getReference()); List entries = researcherRepository.getWithCriteria(criteria).toList(); if (entries != null && !entries.isEmpty()) researcher.setId(entries.get(0).getId()); - else researcherRepository.createOrUpdate(researcher); + else { + researcher.setCreationUser(user); + researcherRepository.createOrUpdate(researcher); + } } } } @@ -634,7 +709,6 @@ public class DataManagementPlanManager { eu.eudat.data.entities.Funder funderEntity = funderDao.getWithCritetia(criteria).getSingleOrDefault(); if (funderEntity != null) funder.setId(funderEntity.getId()); else { - funder.setType(Funder.FunderType.EXTERNAL.getValue()); funderDao.createOrUpdate(funder); } } @@ -681,12 +755,24 @@ public class DataManagementPlanManager { } } - private void checkIfGrandHasCreationUser(DMP dmp, UserInfo user) { - if (dmp.getGrant().getCreationUser() == null) { + private void assignGrandUserIfInternal(DMP dmp, UserInfo user) { + if (dmp.getGrant().getCreationUser() == null && dmp.getGrant().getReference().startsWith("dmp:")) { dmp.getGrant().setCreationUser(user); } } + private void assignFunderUserIfInternal(DMP dmp, UserInfo user) { + if (dmp.getGrant().getFunder().getCreationUser() == null && dmp.getGrant().getFunder().getReference().startsWith("dmp:")) { + dmp.getGrant().getFunder().setCreationUser(user); + } + } + + private void assignProjectUserIfInternal(DMP dmp, UserInfo user) { + if (dmp.getProject().getCreationUser() == null && dmp.getProject().getReference().startsWith("dmp:")) { + dmp.getProject().setCreationUser(user); + } + } + private void copyDatasets(DMP newDmp, DatasetDao datasetDao) { List> futures = new LinkedList<>(); for (Dataset dataset : newDmp.getDataset()) { @@ -747,10 +833,12 @@ public class DataManagementPlanManager { } } - public FileEnvelope getXmlDocument(String id) throws InstantiationException, IllegalAccessException, IOException { + public FileEnvelope getXmlDocument(String id, Principal principal) throws InstantiationException, IllegalAccessException, IOException { ExportXmlBuilder xmlBuilder = new ExportXmlBuilder(); VisibilityRuleService visibilityRuleService = utilitiesService.getVisibilityRuleService(); eu.eudat.data.entities.DMP dmp = databaseRepository.getDmpDao().find(UUID.fromString(id)); + if (!dmp.isPublic() && dmp.getUsers().stream().filter(userInfo -> userInfo.getUser().getId() == principal.getId()).collect(Collectors.toList()).size() == 0) + throw new UnauthorisedException(); List datasets = dmp.getDataset().stream().collect(Collectors.toList()); String fileName = dmp.getLabel(); fileName = fileName.replaceAll("[^a-zA-Z0-9+ ]", ""); @@ -856,11 +944,11 @@ public class DataManagementPlanManager { return fileEnvelope; } - public ResponseEntity getRDAJsonDocument(String id) throws IOException { + public ResponseEntity getRDAJsonDocument(String id, Principal principal) throws IOException { eu.eudat.data.entities.DMP dmp = databaseRepository.getDmpDao().find(UUID.fromString(id)); - DmpRDAExportModel dmpExport = new DmpRDAExportModel().fromDataModel(dmp); - RDAExportModel rdaExportModel = new RDAExportModel(); - rdaExportModel.setDmp(dmpExport); + if (!dmp.isPublic() && dmp.getUsers().stream().filter(userInfo -> userInfo.getUser().getId() == principal.getId()).collect(Collectors.toList()).size() == 0) + throw new UnauthorisedException(); + RDAExportModel rdaExportModel = new RDAExportModel().fromDataModel(dmp); ObjectMapper mapper = new ObjectMapper(); String fileName = dmp.getLabel(); @@ -886,20 +974,17 @@ public class DataManagementPlanManager { return new ResponseEntity<>(content, responseHeaders, HttpStatus.OK); } - public ResponseEntity getDocument(String id, String contentType) throws InstantiationException, IllegalAccessException, IOException { + public ResponseEntity getDocument(String id, String contentType, Principal principal, ConfigLoader configLoader) throws InstantiationException, IllegalAccessException, IOException { File file; switch (contentType) { case "application/xml": - file = getXmlDocument(id).getFile(); + file = getXmlDocument(id, principal).getFile(); break; case "application/msword": - file = getWordDocument(id); + file = getWordDocument(id, principal, configLoader); break; - /*case "application/pdf": - file = getPdfDocument(id); - break;*/ default: - file = getXmlDocument(id).getFile(); + file = getXmlDocument(id, principal).getFile(); } InputStream resource = new FileInputStream(file); HttpHeaders responseHeaders = new HttpHeaders(); @@ -932,8 +1017,8 @@ public class DataManagementPlanManager { } catch (IOException | JAXBException ex) { ex.printStackTrace(); } - // TODO Iterate through the list of dataManagmentPlans. - // Creates new dataManagmentPlan to fill it with the data model that was parsed from the xml. + // TODO Iterate through the list of dataManagementPlans. + // Creates new dataManagementPlan to fill it with the data model that was parsed from the xml. // Creates properties. DataManagementPlan dm = new DataManagementPlan(); DataManagementPlanProfile dmpProfile = new DataManagementPlanProfile(); @@ -1064,7 +1149,7 @@ public class DataManagementPlanManager { return (dmp.getUsers().stream().filter(userDMP -> userDMP.getRole().equals(UserDMP.UserDMPRoles.OWNER.getValue())).findFirst().get().getUser().getId()).equals(principal.getId()); } - public String createZenodoDoi(UUID id, Principal principal) throws Exception { + public String createZenodoDoi(UUID id, Principal principal, ConfigLoader configLoader) throws Exception { DMP dmp = this.apiContext.getOperationsContext().getDatabaseRepository().getDmpDao().find(id); if (!isUserOwnerOfDmp(dmp, principal)) throw new Exception("User is not authorized to invoke this action"); @@ -1098,7 +1183,7 @@ public class DataManagementPlanManager { fileHeaders.setContentType(MediaType.MULTIPART_FORM_DATA); LinkedMultiValueMap addFileMap = new LinkedMultiValueMap<>(); - File file = getWordDocument(id.toString()); + File file = getWordDocument(id.toString(), principal, configLoader); addFileMap.add("filename", file.getName()); FileSystemResource fileSystemResource = new FileSystemResource(file); addFileMap.add("file", fileSystemResource); diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataRepositoryManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataRepositoryManager.java index 53d46bc1a..31634fe0c 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataRepositoryManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataRepositoryManager.java @@ -1,12 +1,23 @@ package eu.eudat.logic.managers; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import eu.eudat.data.dao.criteria.DataRepositoryCriteria; import eu.eudat.data.entities.DataRepository; -import eu.eudat.data.entities.Researcher; +import eu.eudat.logic.proxy.config.ExternalUrlCriteria; +import eu.eudat.logic.proxy.config.exceptions.HugeResultSet; +import eu.eudat.logic.proxy.config.exceptions.NoURLFound; import eu.eudat.logic.services.ApiContext; import eu.eudat.models.data.datarepository.DataRepositoryModel; +import eu.eudat.models.data.security.Principal; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + /** * Created by ikalyvas on 9/3/2018. */ @@ -19,8 +30,29 @@ public class DataRepositoryManager { this.apiContext = apiContext; } - public DataRepository create(eu.eudat.models.data.datarepository.DataRepositoryModel dataRepositoryModel) throws Exception { + public DataRepository create(eu.eudat.models.data.datarepository.DataRepositoryModel dataRepositoryModel, Principal principal) throws Exception { DataRepository dataRepository = dataRepositoryModel.toDataModel(); + dataRepository.getCreationUser().setId(principal.getId()); return apiContext.getOperationsContext().getDatabaseRepository().getDataRepositoryDao().createOrUpdate(dataRepository); } + + public List getDataRepositories(String query, String type, Principal principal) throws HugeResultSet, NoURLFound { + ExternalUrlCriteria externalUrlCriteria = new ExternalUrlCriteria(query); + List> remoteRepos = this.apiContext.getOperationsContext().getRemoteFetcher().getRepositories(externalUrlCriteria, type); + + DataRepositoryCriteria criteria = new DataRepositoryCriteria(); + if (!query.isEmpty()) criteria.setLike(query); + criteria.setCreationUserId(principal.getId()); + + List dataRepositoryModels = new LinkedList<>(); + if (type.equals("")) { + List dataRepositoryList = (this.apiContext.getOperationsContext().getDatabaseRepository().getDataRepositoryDao().getWithCriteria(criteria)).toList(); + dataRepositoryModels = dataRepositoryList.stream().map(item -> new DataRepositoryModel().fromDataModel(item)).collect(Collectors.toList()); + } + + ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + dataRepositoryModels.addAll(remoteRepos.stream().map(item -> mapper.convertValue(item, DataRepositoryModel.class)).collect(Collectors.toList())); + + return dataRepositoryModels; + } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetManager.java index b361cb96a..5b04ef777 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetManager.java @@ -12,6 +12,7 @@ import eu.eudat.elastic.criteria.DatasetCriteria; import eu.eudat.elastic.repository.DatasetRepository; import eu.eudat.logic.builders.BuilderFactory; import eu.eudat.logic.builders.entity.UserInfoBuilder; +import eu.eudat.logic.proxy.config.configloaders.ConfigLoader; import eu.eudat.logic.services.ApiContext; import eu.eudat.logic.services.forms.VisibilityRuleService; import eu.eudat.logic.services.operations.DatabaseRepository; @@ -32,6 +33,8 @@ import eu.eudat.models.data.user.composite.PagedDatasetProfile; import eu.eudat.queryable.QueryableList; import org.apache.commons.io.IOUtils; import org.apache.poi.xwpf.usermodel.XWPFDocument; +import org.apache.poi.xwpf.usermodel.XWPFParagraph; +import org.apache.poi.xwpf.usermodel.XWPFRun; import org.json.JSONObject; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.env.Environment; @@ -46,6 +49,8 @@ import org.w3c.dom.Node; import org.w3c.dom.NodeList; import javax.activation.MimetypesFileTypeMap; +import javax.persistence.criteria.Join; +import javax.persistence.criteria.JoinType; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Unmarshaller; @@ -141,6 +146,16 @@ public class DatasetManager { } else items.where((builder, root) -> root.get("id").in(new UUID[]{UUID.randomUUID()})); } + + if (principal.getId() != null && datasetTableRequest.getCriteria().getRole() != null) { + items.where((builder, root) -> { + Join userJoin = root.join("dmp", JoinType.LEFT).join("users", JoinType.LEFT); + return builder.and(builder.equal(userJoin.join("user", JoinType.LEFT).get("id"), principal.getId()), builder.equal(userJoin.get("role"), datasetTableRequest.getCriteria().getRole())); + }); + } + String[] strings = new String[1]; + strings[0] = "-dmp:publishedAt|join|"; + datasetTableRequest.getOrderings().setFields(strings); QueryableList pagedItems = PaginationManager.applyPaging(items, datasetTableRequest); DataTableData dataTable = new DataTableData<>(); @@ -223,8 +238,8 @@ public class DatasetManager { eu.eudat.models.data.user.composite.DatasetProfile datasetprofile = userManager.generateDatasetProfileModel(datasetEntity.getProfile()); datasetprofile.setStatus(dataset.getStatus()); if (datasetEntity.getProperties() != null) { - JSONObject jobject = new JSONObject(datasetEntity.getProperties()); - Map properties = jobject.toMap(); + JSONObject jObject = new JSONObject(datasetEntity.getProperties()); + Map properties = jObject.toMap(); datasetprofile.fromJsonObject(properties); } PagedDatasetProfile pagedDatasetProfile = new PagedDatasetProfile(); @@ -232,25 +247,81 @@ public class DatasetManager { return pagedDatasetProfile; } - public File getWordDocument(Environment environment, String id, VisibilityRuleService visibilityRuleService) throws InstantiationException, IllegalAccessException, IOException { + public File getWordDocument(ConfigLoader configLoader, String id, VisibilityRuleService visibilityRuleService) throws IOException { WordBuilder wordBuilder = new WordBuilder(); DatasetWizardModel dataset = new DatasetWizardModel(); - String fileUrl = environment.getProperty("configuration.h2020template"); - InputStream is = new URL(Paths.get(fileUrl).toUri().toURL().toString()).openStream(); - XWPFDocument document = new XWPFDocument(is); + XWPFDocument document = configLoader.getDocument(); eu.eudat.data.entities.Dataset datasetEntity = databaseRepository.getDatasetDao().find(UUID.fromString(id), HintedModelFactory.getHint(DatasetWizardModel.class)); - wordBuilder.addParagraphContent(datasetEntity.getLabel(), document, ParagraphStyle.TITLE, BigInteger.ZERO); + wordBuilder.addParagraphContent(datasetEntity.getLabel(), document, ParagraphStyle.HEADER1, BigInteger.ZERO); + + // Space below Dataset title. + XWPFParagraph parBreakDataset = document.createParagraph(); + + XWPFParagraph datasetTemplateParagraph = document.createParagraph(); + datasetTemplateParagraph.setStyle("Heading2"); + XWPFRun runDatasetTemplate1 = datasetTemplateParagraph.createRun(); + runDatasetTemplate1.setText("Template: "); + runDatasetTemplate1.setBold(true); + runDatasetTemplate1.setFontSize(12); + XWPFRun runDatasetTemplate = datasetTemplateParagraph.createRun(); + runDatasetTemplate.setText(datasetEntity.getProfile().getLabel()); + runDatasetTemplate.setColor("2E75B6"); + runDatasetTemplate.setBold(true); + runDatasetTemplate.setFontSize(12); + + XWPFParagraph externalReferencesParagraph = document.createParagraph(); + externalReferencesParagraph.setStyle("Heading2"); + XWPFRun externalReferencesRun = externalReferencesParagraph.createRun(); + externalReferencesRun.setText("External References"); + externalReferencesRun.setColor("2E75B6"); + externalReferencesRun.setBold(true); + externalReferencesRun.setFontSize(12); + + wordBuilder.addParagraphContent("Data Repositories", document, ParagraphStyle.HEADER3, BigInteger.ZERO); + if (datasetEntity.getDatasetDataRepositories().size() > 0) { + wordBuilder.addParagraphContent(datasetEntity.getDatasetDataRepositories().stream().map(DatasetDataRepository::getDataRepository).map(DataRepository::getLabel).collect(Collectors.joining(", ")) + , document, ParagraphStyle.TEXT, BigInteger.ZERO); + } + wordBuilder.addParagraphContent("External Datasets", document, ParagraphStyle.HEADER3, BigInteger.ZERO); + if (datasetEntity.getDatasetExternalDatasets().size() > 0) { + wordBuilder.addParagraphContent(datasetEntity.getDatasetExternalDatasets().stream().map(DatasetExternalDataset::getExternalDataset).map(ExternalDataset::getLabel).collect(Collectors.joining(", ")) + , document, ParagraphStyle.TEXT, BigInteger.ZERO); + } + wordBuilder.addParagraphContent("Registries", document, ParagraphStyle.HEADER3, BigInteger.ZERO); + if (datasetEntity.getRegistries().size() > 0) { + wordBuilder.addParagraphContent(datasetEntity.getRegistries().stream().map(Registry::getLabel).collect(Collectors.joining(", ")) + , document, ParagraphStyle.TEXT, BigInteger.ZERO); + } + wordBuilder.addParagraphContent("Services", document, ParagraphStyle.HEADER3, BigInteger.ZERO); + if (datasetEntity.getServices().size() > 0) { + wordBuilder.addParagraphContent(datasetEntity.getServices().stream().map(DatasetService::getService).map(Service::getLabel).collect(Collectors.joining(", ")) + , document, ParagraphStyle.TEXT, BigInteger.ZERO); + } + /*wordBuilder.addParagraphContent("Tags", document, ParagraphStyle.HEADER3, BigInteger.ZERO); + if (datasetEntity.().size() > 0) { + wordBuilder.addParagraphContent(datasetEntity.getServices().stream().map(DatasetService::getService).map(Service::getLabel).collect(Collectors.joining(", ")) + , document, ParagraphStyle.HEADER4, BigInteger.ZERO); + }*/ + Map properties = new HashMap<>(); if (datasetEntity.getProperties() != null) { - JSONObject jobject = new JSONObject(datasetEntity.getProperties()); - properties = jobject.toMap(); + JSONObject jObject = new JSONObject(datasetEntity.getProperties()); + properties = jObject.toMap(); } + + wordBuilder.addParagraphContent("Dataset Description", document, ParagraphStyle.HEADER2, BigInteger.ZERO); PagedDatasetProfile pagedDatasetProfile = getPagedProfile(dataset, datasetEntity); visibilityRuleService.setProperties(properties); visibilityRuleService.buildVisibilityContext(pagedDatasetProfile.getRules()); wordBuilder.build(document, pagedDatasetProfile, visibilityRuleService); String label = datasetEntity.getLabel().replaceAll("[^a-zA-Z0-9+ ]", ""); File exportFile = new File(label + ".docx"); + + // Removes the top empty headings. + for (int i = 0; i < 6; i++) { + document.removeBodyElement(0); + } + FileOutputStream out = new FileOutputStream(exportFile); document.write(out); out.close(); @@ -335,10 +406,11 @@ public class DatasetManager { UserInfo userInfo = apiContext.getOperationsContext().getBuilderFactory().getBuilder(UserInfoBuilder.class).id(principal.getId()).build(); dataset.setCreator(userInfo); - createRegistriesIfTheyDontExist(apiContext.getOperationsContext().getDatabaseRepository().getRegistryDao(), dataset); createDataRepositoriesIfTheyDontExist(apiContext.getOperationsContext().getDatabaseRepository().getDataRepositoryDao(), dataset); - createServicesIfTheyDontExist(dataset); createExternalDatasetsIfTheyDontExist(dataset); + createRegistriesIfTheyDontExist(apiContext.getOperationsContext().getDatabaseRepository().getRegistryDao(), dataset); + createServicesIfTheyDontExist(dataset); + Dataset dataset1 = apiContext.getOperationsContext().getDatabaseRepository().getDatasetDao().createOrUpdate(dataset); datasetWizardModel.setId(dataset1.getId()); updateTags(apiContext.getOperationsContext().getDatasetRepository(), datasetWizardModel); @@ -402,11 +474,8 @@ public class DatasetManager { } private void createDataRepositoriesIfTheyDontExist(DataRepositoryDao dataRepositoryDao, eu.eudat.data.entities.Dataset dataset) { - Set datasetDataRepositories = dataset.getDatasetDataRepositories(); - dataset.setDatasetDataRepositories(new HashSet<>()); - - if (datasetDataRepositories != null && !datasetDataRepositories.isEmpty()) { - for (eu.eudat.data.entities.DatasetDataRepository datasetDataRepository : datasetDataRepositories) { + if (dataset.getDatasetDataRepositories() != null && !dataset.getDatasetDataRepositories().isEmpty()) { + for (eu.eudat.data.entities.DatasetDataRepository datasetDataRepository : dataset.getDatasetDataRepositories()) { DataRepositoryCriteria criteria = new DataRepositoryCriteria(); criteria.setLike(datasetDataRepository.getDataRepository().getReference()); List entries = dataRepositoryDao.getWithCriteria(criteria).toList(); @@ -415,8 +484,9 @@ public class DatasetManager { datasetDataRepository.setDataset(dataset); dataset.getDatasetDataRepositories().add(datasetDataRepository); } else { - //datasetDataRepository.getDataRepository().setId(UUID.randomUUID()); + datasetDataRepository.getDataRepository().setId(UUID.randomUUID()); DataRepository dataRepository = dataRepositoryDao.createOrUpdate(datasetDataRepository.getDataRepository()); + datasetDataRepository.setDataset(dataset); datasetDataRepository.setDataRepository(dataRepository); dataset.getDatasetDataRepositories().add(datasetDataRepository); } @@ -425,41 +495,35 @@ public class DatasetManager { } private void createServicesIfTheyDontExist(eu.eudat.data.entities.Dataset dataset) { - Set services = dataset.getServices(); - dataset.setServices(new HashSet<>()); - if (services != null && !services.isEmpty()) { - for (eu.eudat.data.entities.DatasetService datasetService : services) { + if (dataset.getServices() != null && !dataset.getServices().isEmpty()) { + for (DatasetService service : dataset.getServices()) { ServiceCriteria criteria = new ServiceCriteria(); - criteria.setLike(datasetService.getService().getLabel()); + criteria.setLike(service.getService().getReference()); List entries = databaseRepository.getServiceDao().getWithCriteria(criteria).toList(); if (entries != null && !entries.isEmpty()) { - datasetService.getService().setId(entries.get(0).getId()); - datasetService.setDataset(dataset); - dataset.getServices().add(datasetService); - } else { - datasetService.getService().setCreated(new Date()); - Service service = databaseRepository.getServiceDao().createOrUpdate(datasetService.getService()); - datasetService.setService(service); - datasetService.setDataset(dataset); - dataset.getServices().add(datasetService); + service.setDataset(dataset); + service.getService().setCreated(new Date()); + service.setService(service.getService()); + this.databaseRepository.getServiceDao().createOrUpdate(service.getService()); + dataset.getServices().add(service); } } } } private void createExternalDatasetsIfTheyDontExist(eu.eudat.data.entities.Dataset dataset) { - Set externalDatasets = dataset.getDatasetExternalDatasets(); - dataset.setDatasetExternalDatasets(new HashSet<>()); - if (externalDatasets != null && !externalDatasets.isEmpty()) { - for (eu.eudat.data.entities.DatasetExternalDataset datasetExternalDataset : externalDatasets) { + if (dataset.getDatasetExternalDatasets() != null && !dataset.getDatasetExternalDatasets().isEmpty()) { + for (eu.eudat.data.entities.DatasetExternalDataset datasetExternalDataset : dataset.getDatasetExternalDatasets()) { ExternalDatasetCriteria criteria = new ExternalDatasetCriteria(); - criteria.setLike(datasetExternalDataset.getExternalDataset().getLabel()); + criteria.setLike(datasetExternalDataset.getExternalDataset().getReference()); List entries = databaseRepository.getExternalDatasetDao().getWithCriteria(criteria).toList(); if (entries != null && !entries.isEmpty()) { datasetExternalDataset.getExternalDataset().setId(entries.get(0).getId()); datasetExternalDataset.setDataset(dataset); dataset.getDatasetExternalDatasets().add(datasetExternalDataset); } else { + datasetExternalDataset.getExternalDataset().setId(UUID.randomUUID()); + datasetExternalDataset.setDataset(dataset); ExternalDataset externalDataset = databaseRepository.getExternalDatasetDao().createOrUpdate(datasetExternalDataset.getExternalDataset()); datasetExternalDataset.setExternalDataset(externalDataset); dataset.getDatasetExternalDatasets().add(datasetExternalDataset); diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetProfileManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetProfileManager.java index 32888ab1e..7bff0808a 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetProfileManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetProfileManager.java @@ -19,10 +19,9 @@ import eu.eudat.models.data.datasetprofile.DatasetProfileAutocompleteItem; import eu.eudat.models.data.datasetprofile.DatasetProfileListingModel; import eu.eudat.models.data.entities.xmlmodels.datasetprofiledefinition.Field; import eu.eudat.models.data.externaldataset.ExternalAutocompleteFieldModel; -import eu.eudat.models.data.helpermodels.Tuple; import eu.eudat.models.data.helpers.common.DataTableData; -import eu.eudat.models.data.security.Principal; import eu.eudat.queryable.QueryableList; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.*; import org.springframework.stereotype.Component; @@ -45,6 +44,7 @@ public class DatasetProfileManager { private ApiContext apiContext; private DatabaseRepository databaseRepository; + @Autowired public DatasetProfileManager(ApiContext apiContext) { this.apiContext = apiContext; @@ -81,9 +81,8 @@ public class DatasetProfileManager { return apiContext.getOperationsContext().getBuilderFactory().getBuilder(DataTableDataBuilder.class).data(datasetProfiles).totalCount(items.count()).build(); } - public List getAll() throws IllegalAccessException, InstantiationException { - DatasetProfileCriteria criteria = new DatasetProfileCriteria(); - QueryableList items = databaseRepository.getDatasetProfileDao().getWithCriteria(criteria); + public List getAll(DatasetProfileTableRequestItem tableRequestItem) throws IllegalAccessException, InstantiationException { + QueryableList items = databaseRepository.getDatasetProfileDao().getWithCriteria(tableRequestItem.getCriteria()); List datasetProfiles = items.select(item -> new DatasetProfileListingModel().fromDataModel(item)); return datasetProfiles; } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DocumentManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DocumentManager.java index db7fcf3a9..1f7cfbee1 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DocumentManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DocumentManager.java @@ -1,6 +1,7 @@ package eu.eudat.logic.managers; import eu.eudat.data.dao.entities.DatasetDao; +import eu.eudat.logic.proxy.config.configloaders.ConfigLoader; import eu.eudat.logic.services.ApiContext; import eu.eudat.logic.services.forms.VisibilityRuleService; import eu.eudat.logic.utilities.documents.helpers.FileEnvelope; @@ -12,7 +13,6 @@ import eu.eudat.models.data.user.composite.PagedDatasetProfile; import org.apache.commons.io.IOUtils; import org.apache.poi.xwpf.usermodel.XWPFDocument; import org.json.JSONObject; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.env.Environment; import org.springframework.core.io.FileSystemResource; import org.springframework.http.*; @@ -39,17 +39,18 @@ public class DocumentManager { private ApiContext context; private DatasetManager datasetManager; - public DocumentManager(ApiContext context, DatasetManager datasetManager) { + private ConfigLoader configLoader; + + public DocumentManager(ApiContext context, DatasetManager datasetManager, ConfigLoader configLoader) { this.context = context; this.datasetManager = datasetManager; + this.configLoader = configLoader; } - public File getWordDocument(Environment environment, DatasetDao datatasetRepository, String id, VisibilityRuleService visibilityRuleService) throws InstantiationException, IllegalAccessException, IOException { + public File getWordDocument(ConfigLoader configLoader, DatasetDao datatasetRepository, String id, VisibilityRuleService visibilityRuleService) throws InstantiationException, IllegalAccessException, IOException { WordBuilder wordBuilder = new WordBuilder(); DatasetWizardModel dataset = new DatasetWizardModel(); - String fileUrl = environment.getProperty("configuration.h2020template"); - InputStream is = new URL(Paths.get(fileUrl).toUri().toURL().toString()).openStream(); - XWPFDocument document = new XWPFDocument(is); + XWPFDocument document = configLoader.getDocument(); eu.eudat.data.entities.Dataset datasetEntity = datatasetRepository.find(UUID.fromString(id), HintedModelFactory.getHint(DatasetWizardModel.class)); Map properties = new HashMap<>(); if (datasetEntity.getProperties() != null) { diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/EmailConfirmationManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/EmailConfirmationManager.java index ed1b8e747..907ceac18 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/EmailConfirmationManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/EmailConfirmationManager.java @@ -1,50 +1,90 @@ package eu.eudat.logic.managers; +import eu.eudat.data.entities.Credential; import eu.eudat.data.entities.LoginConfirmationEmail; import eu.eudat.data.entities.UserInfo; +import eu.eudat.data.entities.UserToken; import eu.eudat.exceptions.emailconfirmation.HasConfirmedEmailException; import eu.eudat.exceptions.emailconfirmation.TokenExpiredException; import eu.eudat.logic.services.ApiContext; +import eu.eudat.logic.services.operations.DatabaseRepository; import eu.eudat.models.data.security.Principal; +import eu.eudat.queryable.QueryableList; +import eu.eudat.queryable.jpa.predicates.OrderByPredicate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.util.Date; +import java.util.List; import java.util.UUID; @Component public class EmailConfirmationManager { private ApiContext apiContext; + private DatabaseRepository databaseRepository; @Autowired public EmailConfirmationManager(ApiContext apiContext) { this.apiContext = apiContext; + this.databaseRepository = apiContext.getOperationsContext().getDatabaseRepository(); } public void confirmEmail(String token) throws TokenExpiredException, HasConfirmedEmailException { LoginConfirmationEmail loginConfirmationEmail = apiContext.getOperationsContext() .getDatabaseRepository().getLoginConfirmationEmailDao().asQueryable() .where((builder, root) -> builder.equal(root.get("token"), UUID.fromString(token))).getSingle(); + if (loginConfirmationEmail.getExpiresAt().compareTo(new Date()) < 0) throw new TokenExpiredException("Token has expired."); - UserInfo user = apiContext.getOperationsContext().getDatabaseRepository().getUserInfoDao().asQueryable() + + UserInfo user = databaseRepository.getUserInfoDao().asQueryable() .where((builder, root) -> builder.equal(root.get("id"), loginConfirmationEmail.getUserId())).getSingle(); + if (user.getEmail() != null) throw new HasConfirmedEmailException("User already has confirmed his Email."); + loginConfirmationEmail.setIsConfirmed(true); + + // Checks if mail is used by another user. If it is, merges the new the old. + UserInfo oldUser = databaseRepository.getUserInfoDao().asQueryable().where((builder, root) -> builder.equal(root.get("email"), loginConfirmationEmail.getEmail())).getSingle(); + if (oldUser != null) { + mergeNewUserToOld(user, oldUser); + expireUserToken(user); + databaseRepository.getLoginConfirmationEmailDao().createOrUpdate(loginConfirmationEmail); + return; + } + user.setEmail(loginConfirmationEmail.getEmail()); - apiContext.getOperationsContext().getDatabaseRepository().getUserInfoDao().createOrUpdate(user); - apiContext.getOperationsContext().getDatabaseRepository().getLoginConfirmationEmailDao().createOrUpdate(loginConfirmationEmail); + databaseRepository.getUserInfoDao().createOrUpdate(user); + databaseRepository.getLoginConfirmationEmailDao().createOrUpdate(loginConfirmationEmail); } public void sendConfirmationEmail(String email, Principal principal) throws HasConfirmedEmailException { UserInfo user = apiContext.getOperationsContext().getDatabaseRepository().getUserInfoDao().find(principal.getId()); if (user.getEmail() != null) throw new HasConfirmedEmailException("User already has confirmed his Email."); + apiContext.getUtilitiesService().getConfirmationEmailService().createConfirmationEmail( - apiContext.getOperationsContext().getDatabaseRepository().getLoginConfirmationEmailDao(), + databaseRepository.getLoginConfirmationEmailDao(), apiContext.getUtilitiesService().getMailService(), email, - principal.getId()); + principal.getId() + ); + } + + private void mergeNewUserToOld(UserInfo newUser, UserInfo oldUser) { + Credential credential = databaseRepository.getCredentialDao().asQueryable().where((builder, root) -> builder.equal(root.get("userInfo"), newUser)).getSingle(); + credential.setUserInfo(oldUser); + databaseRepository.getCredentialDao().createOrUpdate(credential); + } + + private void expireUserToken(UserInfo user) { + UserToken userToken = databaseRepository.getUserTokenDao().asQueryable() + .where((builder, root) -> builder.equal(root.get("user"), user)) + .orderBy((builder, root) -> builder.desc(root.get("issuedAt"))) + .take(1) + .getSingle(); + userToken.setExpiresAt(new Date()); + databaseRepository.getUserTokenDao().createOrUpdate(userToken); } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/ExternalDatasetManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/ExternalDatasetManager.java index cab3d39b4..f8f72ce31 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/ExternalDatasetManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/ExternalDatasetManager.java @@ -1,24 +1,33 @@ package eu.eudat.logic.managers; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; import eu.eudat.logic.builders.model.criteria.ExternalDatasetCriteriaBuilder; import eu.eudat.logic.builders.model.models.DataTableDataBuilder; -import eu.eudat.data.dao.entities.ExternalDatasetDao; import eu.eudat.data.entities.ExternalDataset; import eu.eudat.data.dao.criteria.ExternalDatasetCriteria; +import eu.eudat.logic.proxy.config.ExternalUrlCriteria; import eu.eudat.logic.services.operations.DatabaseRepository; +import eu.eudat.models.data.external.ExternalDatasetSourcesModel; +import eu.eudat.models.data.external.ExternalSourcesItemModel; import eu.eudat.models.data.externaldataset.ExternalDatasetListingModel; import eu.eudat.data.query.items.table.externaldataset.ExternalDatasetTableRequest; +import eu.eudat.models.data.externaldataset.ExternalDatasetModel; import eu.eudat.models.data.helpers.common.DataTableData; import eu.eudat.logic.proxy.config.exceptions.HugeResultSet; import eu.eudat.logic.proxy.config.exceptions.NoURLFound; import eu.eudat.logic.proxy.fetching.RemoteFetcher; +import eu.eudat.models.data.security.Principal; import eu.eudat.queryable.QueryableList; import eu.eudat.logic.services.ApiContext; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import java.util.LinkedList; import java.util.List; +import java.util.Map; import java.util.UUID; +import java.util.stream.Collectors; @Component public class ExternalDatasetManager { @@ -40,10 +49,26 @@ public class ExternalDatasetManager { return apiContext.getOperationsContext().getBuilderFactory().getBuilder(DataTableDataBuilder.class).data(externalDatasetListingmodels).totalCount(items.count()).build(); } - public List getWithExternal(String query) throws HugeResultSet, NoURLFound, InstantiationException, IllegalAccessException { + public List getWithExternal(String query, String type, Principal principal) throws HugeResultSet, NoURLFound { + // Fetch the local saved external Datasets that belong to the user. ExternalDatasetCriteria criteria = apiContext.getOperationsContext().getBuilderFactory().getBuilder(ExternalDatasetCriteriaBuilder.class).like(query).build(); + criteria.setCreationUserId(principal.getId()); QueryableList items = apiContext.getOperationsContext().getDatabaseRepository().getExternalDatasetDao().getWithCriteria(criteria); + + // Fetch external Datasets from external sources. + ExternalUrlCriteria externalUrlCriteria = new ExternalUrlCriteria(query); + List> remoteRepos = remoteFetcher.getDatasets(externalUrlCriteria, type); + + // Parse items from external sources to listing models. + ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + List externalDatasetModels = remoteRepos.stream() + .map(item -> mapper.convertValue(item, ExternalDatasetListingModel.class)) + .collect(Collectors.toCollection(LinkedList::new)); + + // Merge fetched and local. List externalDatasets = items.select(item -> new ExternalDatasetListingModel().fromDataModel(item)); + externalDatasets.addAll(externalDatasetModels); + return externalDatasets; } @@ -54,8 +79,9 @@ public class ExternalDatasetManager { return externalDatasetModel; } - public ExternalDataset create(eu.eudat.models.data.externaldataset.ExternalDatasetModel externalDatasetModel) throws Exception { + public ExternalDataset create(eu.eudat.models.data.externaldataset.ExternalDatasetModel externalDatasetModel, Principal principal) throws Exception { ExternalDataset externalDataset = externalDatasetModel.toDataModel(); + externalDataset.getCreationUser().setId(principal.getId()); return apiContext.getOperationsContext().getDatabaseRepository().getExternalDatasetDao().createOrUpdate(externalDataset); } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/FunderManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/FunderManager.java index 8c882953a..1db66f391 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/FunderManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/FunderManager.java @@ -2,10 +2,12 @@ package eu.eudat.logic.managers; import eu.eudat.data.query.items.item.funder.FunderCriteriaRequest; import eu.eudat.logic.builders.model.models.FunderBuilder; +import eu.eudat.logic.proxy.config.ExternalUrlCriteria; import eu.eudat.logic.proxy.config.exceptions.HugeResultSet; import eu.eudat.logic.proxy.config.exceptions.NoURLFound; import eu.eudat.logic.proxy.fetching.RemoteFetcher; import eu.eudat.logic.services.ApiContext; +import eu.eudat.logic.utilities.helpers.ListHelper; import eu.eudat.models.data.external.ExternalSourcesItemModel; import eu.eudat.models.data.external.FundersExternalSourcesModel; import eu.eudat.models.data.funder.Funder; @@ -16,16 +18,19 @@ import org.springframework.stereotype.Component; import java.util.Comparator; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; @Component public class FunderManager { private ApiContext apiContext; private RemoteFetcher remoteFetcher; + private ListHelper listHelper; - public FunderManager(ApiContext apiContext, RemoteFetcher remoteFetcher) { + public FunderManager(ApiContext apiContext, RemoteFetcher remoteFetcher, ListHelper listHelper) { this.apiContext = apiContext; this.remoteFetcher = remoteFetcher; + this.listHelper = listHelper; } public List getCriteriaWithExternal(FunderCriteriaRequest funderCriteria, Principal principal) throws HugeResultSet, NoURLFound { @@ -33,20 +38,26 @@ public class FunderManager { userInfo.setId(principal.getId()); funderCriteria.getCriteria().setReference("dmp:"); QueryableList items = apiContext.getOperationsContext().getDatabaseRepository().getFunderDao().getWithCritetia(funderCriteria.getCriteria()); - //QueryableList authItems = apiContext.getOperationsContext().getDatabaseRepository().getFunderDao().getAuthenticated(items, userInfo); - List funders = items.select(item -> new eu.eudat.models.data.funder.Funder().fromDataModel(item)); - List> remoteRepos = remoteFetcher.getFunders(funderCriteria.getCriteria().getLike()); + QueryableList authItems = apiContext.getOperationsContext().getDatabaseRepository().getFunderDao().getAuthenticated(items, userInfo); + List funders = authItems.select(item -> new eu.eudat.models.data.funder.Funder().fromDataModel(item)); + ExternalUrlCriteria externalUrlCriteria = new ExternalUrlCriteria(funderCriteria.getCriteria().getLike()); + List> remoteRepos = remoteFetcher.getFunders(externalUrlCriteria); FundersExternalSourcesModel fundersExternalSourcesModel = new FundersExternalSourcesModel().fromExternalItem(remoteRepos); for (ExternalSourcesItemModel externalListingItem : fundersExternalSourcesModel) { eu.eudat.models.data.funder.Funder funder = apiContext.getOperationsContext().getBuilderFactory().getBuilder(FunderBuilder.class) .reference(externalListingItem.getRemoteId()).label(externalListingItem.getName()) .status(eu.eudat.data.entities.Funder.Status.fromInteger(0)) - .source(externalListingItem.getTag()) .build(); + if (externalListingItem.getSource() != null) { + funder.setSource(externalListingItem.getSource()); + } else { + funder.setSource(externalListingItem.getTag()); + } funders.add(funder); } funders.sort(Comparator.comparing(Funder::getLabel)); + funders = funders.stream().filter(listHelper.distinctByKey(Funder::getLabel)).collect(Collectors.toList()); return funders; } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/GrantManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/GrantManager.java index 6e3e07d1d..03213aa87 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/GrantManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/GrantManager.java @@ -4,16 +4,14 @@ import eu.eudat.data.dao.criteria.FunderCriteria; import eu.eudat.data.entities.Funder; import eu.eudat.data.query.items.table.grant.GrantTableRequest; import eu.eudat.exceptions.grant.GrantWithDMPsDeleteException; -import eu.eudat.logic.builders.entity.ContentBuilder; import eu.eudat.logic.builders.model.models.GrantBuilder; import eu.eudat.data.dao.entities.GrantDao; -import eu.eudat.data.entities.Content; import eu.eudat.data.entities.DMP; -import eu.eudat.exceptions.files.TempFileNotFoundException; +import eu.eudat.logic.proxy.config.ExternalUrlCriteria; import eu.eudat.logic.services.operations.DatabaseRepository; +import eu.eudat.logic.utilities.helpers.ListHelper; import eu.eudat.models.data.external.ExternalSourcesItemModel; import eu.eudat.models.data.external.GrantsExternalSourcesModel; -import eu.eudat.models.data.files.ContentFile; import eu.eudat.models.data.grant.Grant; import eu.eudat.models.data.helpers.common.DataTableData; import eu.eudat.data.query.items.item.grant.GrantCriteriaRequest; @@ -27,13 +25,12 @@ import eu.eudat.logic.services.ApiContext; import eu.eudat.logic.services.helpers.FileStorageService; import org.springframework.stereotype.Component; -import java.io.IOException; -import java.text.ParseException; import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.UUID; import java.util.concurrent.CompletableFuture; +import java.util.stream.Collectors; @Component public class GrantManager { @@ -42,12 +39,14 @@ public class GrantManager { private DatabaseRepository databaseRepository; private FileStorageService fileStorageService; private RemoteFetcher remoteFetcher; + private ListHelper listHelper; - public GrantManager(ApiContext apiContext) { + public GrantManager(ApiContext apiContext, ListHelper listHelper) { this.apiContext = apiContext; this.databaseRepository = apiContext.getOperationsContext().getDatabaseRepository(); this.fileStorageService = apiContext.getOperationsContext().getFileStorageService(); this.remoteFetcher = apiContext.getOperationsContext().getRemoteFetcher(); + this.listHelper = listHelper; } public DataTableData getPaged(GrantTableRequest grantTableRequest, Principal principal, String fieldsGroup) throws Exception { @@ -99,15 +98,15 @@ public class GrantManager { return grant; } - public eu.eudat.data.entities.Grant inactivate(String id) throws InstantiationException, IllegalAccessException { + /*public eu.eudat.data.entities.Grant inactivate(String id) throws InstantiationException, IllegalAccessException { GrantDao grantRepository = databaseRepository.getGrantDao(); eu.eudat.data.entities.Grant grant = grantRepository.find(UUID.fromString(id)); grant.setStatus(eu.eudat.data.entities.Grant.Status.DELETED.getValue()); grant = grantRepository.createOrUpdate(grant); return grant; - } + }*/ - public List getCriteriaWithExternal(GrantCriteriaRequest grantCriteria, Principal principal) throws IllegalAccessException, InstantiationException, HugeResultSet, NoURLFound { + public List getCriteriaWithExternal(GrantCriteriaRequest grantCriteria, Principal principal) throws HugeResultSet, NoURLFound { eu.eudat.data.entities.UserInfo userInfo = new eu.eudat.data.entities.UserInfo(); userInfo.setId(principal.getId()); if (grantCriteria.getCriteria().getFunderReference() != null && !grantCriteria.getCriteria().getFunderReference().trim().isEmpty()) { @@ -122,7 +121,11 @@ public class GrantManager { QueryableList items = apiContext.getOperationsContext().getDatabaseRepository().getGrantDao().getWithCriteria(grantCriteria.getCriteria()); QueryableList authItems = apiContext.getOperationsContext().getDatabaseRepository().getGrantDao().getAuthenticated(items, userInfo); List grants = authItems.select(item -> new Grant().fromDataModel(item)); - List> remoteRepos = remoteFetcher.getGrants(grantCriteria.getCriteria().getLike()); + + ExternalUrlCriteria externalUrlCriteria = new ExternalUrlCriteria(grantCriteria.getCriteria().getLike()); + if (grantCriteria.getCriteria().getFunderReference() != null) externalUrlCriteria.setFunderId(grantCriteria.getCriteria().getFunderReference()); + List> remoteRepos = remoteFetcher.getGrants(externalUrlCriteria); + GrantsExternalSourcesModel grantsExternalSourcesModel = new GrantsExternalSourcesModel().fromExternalItem(remoteRepos); for (ExternalSourcesItemModel externalListingItem : grantsExternalSourcesModel) { eu.eudat.models.data.grant.Grant grant = apiContext.getOperationsContext().getBuilderFactory().getBuilder(GrantBuilder.class) @@ -135,6 +138,7 @@ public class GrantManager { grants.add(grant); } grants.sort(Comparator.comparing(Grant::getLabel)); + grants = grants.stream().filter(listHelper.distinctByKey(Grant::getLabel)).collect(Collectors.toList()); return grants; } @@ -146,7 +150,7 @@ public class GrantManager { return grants; } - public void createOrUpdate(eu.eudat.models.data.grant.Grant grant, Principal principal) throws ParseException, IOException { + /*public void createOrUpdate(eu.eudat.models.data.grant.Grant grant, Principal principal) throws ParseException, IOException { eu.eudat.data.entities.Grant grantEntity = grant.toDataModel(); if (grant.getFiles() != null) { for (ContentFile file : grant.getFiles()) { @@ -167,7 +171,7 @@ public class GrantManager { grantEntity.setType(eu.eudat.data.entities.Grant.GrantType.INTERNAL.getValue()); grantEntity.setCreationUser(databaseRepository.getUserInfoDao().find(principal.getId())); databaseRepository.getGrantDao().createOrUpdate(grantEntity); - } + }*/ public void delete(UUID uuid) { eu.eudat.data.entities.Grant oldGrant = apiContext.getOperationsContext().getDatabaseRepository().getGrantDao().find(uuid); diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/ProjectManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/ProjectManager.java index 258e5ef2d..bd9b494b0 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/ProjectManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/ProjectManager.java @@ -1,5 +1,7 @@ package eu.eudat.logic.managers; +import eu.eudat.logic.proxy.config.ExternalUrlCriteria; +import eu.eudat.logic.utilities.helpers.ListHelper; import eu.eudat.models.data.external.ProjectsExternalSourcesModel; import eu.eudat.models.data.project.Project; import eu.eudat.data.query.items.item.project.ProjectCriteriaRequest; @@ -16,16 +18,19 @@ import org.springframework.stereotype.Component; import java.util.Comparator; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; @Component public class ProjectManager { private ApiContext apiContext; private RemoteFetcher remoteFetcher; + private ListHelper listHelper; - public ProjectManager(ApiContext apiContext) { + public ProjectManager(ApiContext apiContext, ListHelper listHelper) { this.apiContext = apiContext; this.remoteFetcher = apiContext.getOperationsContext().getRemoteFetcher(); + this.listHelper = listHelper; } public List getCriteriaWithExternal(ProjectCriteriaRequest projectCriteria, Principal principal) throws HugeResultSet, NoURLFound { @@ -35,7 +40,8 @@ public class ProjectManager { QueryableList items = apiContext.getOperationsContext().getDatabaseRepository().getProjectDao().getWithCritetia(projectCriteria.getCriteria()); QueryableList authItems = apiContext.getOperationsContext().getDatabaseRepository().getProjectDao().getAuthenticated(items, userInfo); List projects = authItems.select(item -> new Project().fromDataModel(item)); - List> remoteRepos = remoteFetcher.getProjects(projectCriteria.getCriteria().getLike()); + ExternalUrlCriteria externalUrlCriteria = new ExternalUrlCriteria(projectCriteria.getCriteria().getLike()); + List> remoteRepos = remoteFetcher.getProjects(externalUrlCriteria); ProjectsExternalSourcesModel projectsExternalSourcesModel = new ProjectsExternalSourcesModel().fromExternalItem(remoteRepos); for (ExternalSourcesItemModel externalListingItem : projectsExternalSourcesModel) { eu.eudat.models.data.project.Project project = apiContext.getOperationsContext().getBuilderFactory().getBuilder(ProjectBuilder.class) @@ -48,6 +54,7 @@ public class ProjectManager { projects.add(project); } projects.sort(Comparator.comparing(Project::getLabel)); + projects = projects.stream().filter(listHelper.distinctByKey(Project::getLabel)).collect(Collectors.toList()); return projects; } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/RegistryManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/RegistryManager.java index 33016f094..9220d6221 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/RegistryManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/RegistryManager.java @@ -1,13 +1,23 @@ package eu.eudat.logic.managers; -import eu.eudat.data.entities.DataRepository; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import eu.eudat.data.dao.criteria.RegistryCriteria; import eu.eudat.data.entities.Registry; +import eu.eudat.logic.proxy.config.ExternalUrlCriteria; +import eu.eudat.logic.proxy.config.exceptions.HugeResultSet; +import eu.eudat.logic.proxy.config.exceptions.NoURLFound; import eu.eudat.logic.services.ApiContext; -import eu.eudat.models.data.datarepository.DataRepositoryModel; import eu.eudat.models.data.registries.RegistryModel; +import eu.eudat.models.data.security.Principal; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + @Component public class RegistryManager { @@ -18,8 +28,30 @@ public class RegistryManager { this.apiContext = apiContext; } - public Registry create(RegistryModel registryModel) throws Exception { + public Registry create(RegistryModel registryModel, Principal principal) throws Exception { + if (registryModel.getLabel() == null || registryModel.getAbbreviation() == null || registryModel.getUri() == null) { + throw new Exception("Missing mandatory entity."); + } Registry registry = registryModel.toDataModel(); + registry.getCreationUser().setId(principal.getId()); return apiContext.getOperationsContext().getDatabaseRepository().getRegistryDao().createOrUpdate(registry); } + + public List getRegistries(String query, String type, Principal principal) throws HugeResultSet, NoURLFound { + ExternalUrlCriteria externalUrlCriteria = new ExternalUrlCriteria(query); + List> remoteRepos = this.apiContext.getOperationsContext().getRemoteFetcher().getRegistries(externalUrlCriteria, type); + + RegistryCriteria criteria = new RegistryCriteria(); + if (!query.isEmpty()) criteria.setLike(query); + criteria.setCreationUserId(principal.getId()); + List registryModels = new LinkedList<>(); + if (type.equals("")) { + List registryList = (this.apiContext.getOperationsContext().getDatabaseRepository().getRegistryDao().getWithCriteria(criteria)).toList(); + registryModels = registryList.stream().map(item -> new RegistryModel().fromDataModel(item)).collect(Collectors.toList()); + } + ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + registryModels.addAll(remoteRepos.stream().map(item -> mapper.convertValue(item, RegistryModel.class)).collect(Collectors.toList())); + + return registryModels; + } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/ResearcherManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/ResearcherManager.java index 4c98de920..e09988e80 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/ResearcherManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/ResearcherManager.java @@ -2,12 +2,14 @@ package eu.eudat.logic.managers; import eu.eudat.logic.builders.model.models.ResearcherBuilder; import eu.eudat.data.entities.Researcher; +import eu.eudat.logic.proxy.config.ExternalUrlCriteria; import eu.eudat.models.data.external.ExternalSourcesItemModel; import eu.eudat.models.data.external.ResearchersExternalSourcesModel; import eu.eudat.data.query.items.item.researcher.ResearcherCriteriaRequest; import eu.eudat.logic.proxy.config.exceptions.HugeResultSet; import eu.eudat.logic.proxy.config.exceptions.NoURLFound; import eu.eudat.logic.proxy.fetching.RemoteFetcher; +import eu.eudat.models.data.security.Principal; import eu.eudat.queryable.QueryableList; import eu.eudat.logic.services.ApiContext; import org.springframework.beans.factory.annotation.Autowired; @@ -15,6 +17,7 @@ import org.springframework.stereotype.Component; import java.util.List; import java.util.Map; +import java.util.UUID; import java.util.stream.Collectors; /** @@ -32,16 +35,19 @@ public class ResearcherManager { this.remoteFetcher = apiContext.getOperationsContext().getRemoteFetcher(); } - public Researcher create(eu.eudat.models.data.researcher.Researcher researcher) throws Exception { + public Researcher create(eu.eudat.models.data.researcher.Researcher researcher, Principal principal) throws Exception { Researcher researcherEntity = researcher.toDataModel(); + researcherEntity.setCreationUser(apiContext.getOperationsContext().getDatabaseRepository().getUserInfoDao().find(principal.getId())); return apiContext.getOperationsContext().getDatabaseRepository().getResearcherDao().createOrUpdate(researcherEntity); } - public List getCriteriaWithExternal(ResearcherCriteriaRequest researcherCriteriaRequest) throws HugeResultSet, NoURLFound { + public List getCriteriaWithExternal(ResearcherCriteriaRequest researcherCriteriaRequest, Principal principal) throws HugeResultSet, NoURLFound { QueryableList items = apiContext.getOperationsContext().getDatabaseRepository().getResearcherDao().getWithCriteria(researcherCriteriaRequest.getCriteria()); + items.where((builder, root) -> builder.equal(root.get("creationUser").get("id"), principal.getId())); List researchers = items.select(item -> new eu.eudat.models.data.dmp.Researcher().fromDataModel(item)); - List> remoteRepos = remoteFetcher.getResearchers(researcherCriteriaRequest.getCriteria().getName(),null); + ExternalUrlCriteria externalUrlCriteria = new ExternalUrlCriteria(researcherCriteriaRequest.getCriteria().getName()); + List> remoteRepos = remoteFetcher.getResearchers(externalUrlCriteria,null); ResearchersExternalSourcesModel researchersExternalSourcesModel = new ResearchersExternalSourcesModel().fromExternalItem(remoteRepos); for (ExternalSourcesItemModel externalListingItem : researchersExternalSourcesModel) { eu.eudat.models.data.dmp.Researcher researcher = apiContext.getOperationsContext().getBuilderFactory().getBuilder(ResearcherBuilder.class) diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/ServiceManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/ServiceManager.java index 109c972a8..222aa3675 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/ServiceManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/ServiceManager.java @@ -1,16 +1,23 @@ package eu.eudat.logic.managers; -import eu.eudat.data.entities.Registry; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import eu.eudat.data.dao.criteria.ServiceCriteria; import eu.eudat.data.entities.Service; +import eu.eudat.logic.proxy.config.ExternalUrlCriteria; +import eu.eudat.logic.proxy.config.exceptions.HugeResultSet; +import eu.eudat.logic.proxy.config.exceptions.NoURLFound; import eu.eudat.logic.services.ApiContext; -import eu.eudat.models.data.registries.RegistryModel; +import eu.eudat.models.data.security.Principal; import eu.eudat.models.data.services.ServiceModel; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -/** - * Created by ikalyvas on 9/3/2018. - */ +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + @Component public class ServiceManager { @@ -21,8 +28,27 @@ public class ServiceManager { this.apiContext = apiContext; } - public Service create(ServiceModel serviceModel) throws Exception { + public Service create(ServiceModel serviceModel, Principal principal) throws Exception { Service service = serviceModel.toDataModel(); + service.getCreationUser().setId(principal.getId()); return apiContext.getOperationsContext().getDatabaseRepository().getServiceDao().createOrUpdate(service); } + + public List getServices(String query, String type, Principal principal) throws HugeResultSet, NoURLFound { + ExternalUrlCriteria externalUrlCriteria = new ExternalUrlCriteria(query); + List> remoteRepos = this.apiContext.getOperationsContext().getRemoteFetcher().getServices(externalUrlCriteria, type); + + ServiceCriteria criteria = new ServiceCriteria(); + if (!query.isEmpty()) criteria.setLike(query); + criteria.setCreationUserId(principal.getId()); + List serviceModels = new LinkedList<>(); + if (type.equals("")) { + List serviceList = (this.apiContext.getOperationsContext().getDatabaseRepository().getServiceDao().getWithCriteria(criteria)).toList(); + serviceModels = serviceList.stream().map(item -> new ServiceModel().fromDataModel(item)).collect(Collectors.toList()); + } + ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + serviceModels.addAll(remoteRepos.stream().map(item -> mapper.convertValue(item, ServiceModel.class)).collect(Collectors.toList())); + + return serviceModels; + } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/UserManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/UserManager.java index 364723317..bf6910247 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/UserManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/UserManager.java @@ -28,10 +28,7 @@ import org.w3c.dom.Document; import org.w3c.dom.Element; import java.io.IOException; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.UUID; +import java.util.*; import java.util.stream.Collectors; @Component @@ -66,7 +63,8 @@ public class UserManager { public UserProfile getSingle(UUID userId) throws Exception { eu.eudat.data.entities.UserInfo user = apiContext.getOperationsContext().getDatabaseRepository().getUserInfoDao().find(userId); UserProfile profile = new UserProfile().fromDataModel(user); - List dmps = apiContext.getOperationsContext().getDatabaseRepository().getDmpDao().getAuthenticated(apiContext.getOperationsContext().getDatabaseRepository().getDmpDao().asQueryable(), userId).take(5).toList(); + List roles = new LinkedList<>(); + List dmps = apiContext.getOperationsContext().getDatabaseRepository().getDmpDao().getAuthenticated(apiContext.getOperationsContext().getDatabaseRepository().getDmpDao().asQueryable(), userId, roles).take(5).toList(); profile.setAssociatedDmps(dmps.stream().map(x -> new DataManagementPlan().fromDataModel(x)).collect(Collectors.toList())); return profile; } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/DataFieldsUrlConfiguration.java b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/DataFieldsUrlConfiguration.java index 829e75b88..0323e8011 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/DataFieldsUrlConfiguration.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/DataFieldsUrlConfiguration.java @@ -11,6 +11,7 @@ public class DataFieldsUrlConfiguration { private String uri; private String description; private String source; + private String count; public String getId() { return id; @@ -57,4 +58,13 @@ public class DataFieldsUrlConfiguration { public void setSource(String source) { this.source = source; } + + public String getCount() { + return count; + } + + @XmlElement(name = "count") + public void setCount(String count) { + this.count = count; + } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/DataSearchConfiguration.java b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/DataSearchConfiguration.java new file mode 100644 index 000000000..8ec232197 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/DataSearchConfiguration.java @@ -0,0 +1,24 @@ +package eu.eudat.logic.proxy.config; + +import javax.xml.bind.annotation.XmlElement; + +public class DataSearchConfiguration { + private String type; + private String queryParam; + + public String getType() { + return type; + } + @XmlElement(name = "type") + public void setType(String type) { + this.type = type; + } + + public String getQueryParam() { + return queryParam; + } + @XmlElement(name = "queryparam") + public void setQueryParam(String queryParam) { + this.queryParam = queryParam; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/ExternalUrlCriteria.java b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/ExternalUrlCriteria.java new file mode 100644 index 000000000..fd0ea091c --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/ExternalUrlCriteria.java @@ -0,0 +1,43 @@ +package eu.eudat.logic.proxy.config; + +public class ExternalUrlCriteria { + private String like; + private String page; + private String pageSize; + private String funderId; + + public String getLike() { + return like; + } + public void setLike(String like) { + this.like = like; + } + + public String getPage() { + return page; + } + public void setPage(String page) { + this.page = page; + } + + public String getPageSize() { + return pageSize; + } + public void setPageSize(String pageSize) { + this.pageSize = pageSize; + } + + public String getFunderId() { + return funderId; + } + public void setFunderId(String funderId) { + this.funderId = funderId; + } + + public ExternalUrlCriteria(String like) { + this.like = like; + } + + public ExternalUrlCriteria() { + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/UrlConfiguration.java b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/UrlConfiguration.java index 9a9912c5a..762153ad4 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/UrlConfiguration.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/UrlConfiguration.java @@ -12,11 +12,13 @@ public class UrlConfiguration { private DataUrlConfiguration data; private String type; private String paginationPath; + private String contentType; + private String funderQuery; + private String firstpage; public String getKey() { return key; } - @XmlElement(name = "key") public void setKey(String key) { this.key = key; @@ -25,7 +27,6 @@ public class UrlConfiguration { public String getLabel() { return label; } - @XmlElement(name = "label") public void setLabel(String label) { this.label = label; @@ -34,7 +35,6 @@ public class UrlConfiguration { public String getUrl() { return url; } - @XmlElement(name = "url") public void setUrl(String url) { this.url = url; @@ -43,7 +43,6 @@ public class UrlConfiguration { public Integer getOrdinal() { return ordinal; } - @XmlElement(name = "ordinal") public void setOrdinal(Integer ordinal) { this.ordinal = ordinal; @@ -52,7 +51,6 @@ public class UrlConfiguration { public DataUrlConfiguration getData() { return data; } - @XmlElement(name = "data") public void setData(DataUrlConfiguration data) { this.data = data; @@ -61,7 +59,6 @@ public class UrlConfiguration { public String getPaginationPath() { return paginationPath; } - @XmlElement(name = "paginationpath") public void setPaginationPath(String paginationPath) { this.paginationPath = paginationPath; @@ -70,9 +67,32 @@ public class UrlConfiguration { public String getType() { return type; } - @XmlElement(name = "type") public void setType(String type) { this.type = type; } + + public String getContentType() { + return contentType; + } + @XmlElement(name = "contenttype") + public void setContentType(String contentType) { + this.contentType = contentType; + } + + public String getFunderQuery() { + return funderQuery; + } + @XmlElement(name = "funderQuery") + public void setFunderQuery(String funderQuery) { + this.funderQuery = funderQuery; + } + + public String getFirstpage() { + return firstpage; + } + @XmlElement(name = "firstPage") + public void setFirstpage(String firstpage) { + this.firstpage = firstpage; + } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/configloaders/ConfigLoader.java b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/configloaders/ConfigLoader.java index ebbc88576..8a935aa53 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/configloaders/ConfigLoader.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/configloaders/ConfigLoader.java @@ -1,10 +1,14 @@ package eu.eudat.logic.proxy.config.configloaders; import eu.eudat.logic.proxy.config.ExternalUrls; +import eu.eudat.logic.security.customproviders.ConfigurableProvider.entities.ConfigurableProviders; +import org.apache.poi.xwpf.usermodel.XWPFDocument; + +import java.util.List; -/** - * Created by ikalyvas on 2/9/2018. - */ public interface ConfigLoader { ExternalUrls getExternalUrls(); + List getRdaProperties(); + XWPFDocument getDocument(); + ConfigurableProviders getConfigurableProviders(); } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/configloaders/DevelConfigLoader.java b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/configloaders/DevelConfigLoader.java index 4af836fbd..934a472c4 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/configloaders/DevelConfigLoader.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/configloaders/DevelConfigLoader.java @@ -1,6 +1,10 @@ package eu.eudat.logic.proxy.config.configloaders; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; import eu.eudat.logic.proxy.config.ExternalUrls; +import eu.eudat.logic.security.customproviders.ConfigurableProvider.entities.ConfigurableProviders; +import org.apache.poi.xwpf.usermodel.XWPFDocument; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Profile; import org.springframework.core.env.Environment; @@ -8,15 +12,22 @@ import org.springframework.stereotype.Service; import javax.xml.bind.JAXBContext; import javax.xml.bind.Unmarshaller; +import java.io.BufferedReader; +import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.net.URL; +import java.util.LinkedList; +import java.util.List; @Service("configLoader") @Profile("devel") public class DevelConfigLoader implements ConfigLoader { private ExternalUrls externalUrls; + private List rdaProperties; + private XWPFDocument document; + private ConfigurableProviders configurableProviders; @Autowired private Environment environment; @@ -31,9 +42,8 @@ public class DevelConfigLoader implements ConfigLoader { JAXBContext jaxbContext = JAXBContext.newInstance(ExternalUrls.class); Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller(); - is = new URL("file:///"+current+"/web/src/main/resources/ExternalUrls.xml").openStream(); + is = new URL("file:///" + current + fileUrl).openStream(); externalUrls = (ExternalUrls) jaxbUnmarshaller.unmarshal(is); - } catch (Exception ex) { ex.printStackTrace(); System.out.println("Cannot find in folder" + current); @@ -44,13 +54,85 @@ public class DevelConfigLoader implements ConfigLoader { System.out.println("Warning: Could not close a stream after reading from file: " + fileUrl); } } - } + private void setRdaProperties() { + String filePath = environment.getProperty("configuration.rda"); + String current = null; + BufferedReader reader; + List rdaList = new LinkedList<>(); + try { + current = new java.io.File(".").getCanonicalPath(); + reader = new BufferedReader(new FileReader(current + filePath)); + String line = reader.readLine(); + while (line != null) { + rdaList.add(line); + line = reader.readLine(); + } + reader.close(); + } catch (IOException e) { + e.printStackTrace(); + } + + rdaProperties = rdaList; + } + + private void setDocument() { + String filePath = environment.getProperty("configuration.h2020template"); + String current = null; + InputStream is = null; + try { + current = new java.io.File(".").getCanonicalPath(); + is = new URL("file:///" + current + filePath).openStream(); + this.document = new XWPFDocument(is); + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + if (is != null) is.close(); + } catch (IOException e) { + System.out.println("Warning: Could not close a stream after reading from file: " + filePath); + } + } + } + + public void setConfigurableProviders() { + String filePath = environment.getProperty("configuration.configurable_login_providers"); + String current = null; + InputStream is = null; + try { + current = new java.io.File(".").getCanonicalPath(); + is = new URL("file:///" + current + filePath).openStream(); + ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + this.configurableProviders = mapper.readValue(is, ConfigurableProviders.class); + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + if (is != null) is.close(); + } catch (IOException e) { + System.out.println("Warning: Could not close a stream after reading from file: " + filePath); + } + } + } public ExternalUrls getExternalUrls() { this.setExternalUrls(); return externalUrls; } + public List getRdaProperties() { + this.setRdaProperties(); + return rdaProperties; + } + + public XWPFDocument getDocument() { + this.setDocument(); + return document; + } + + public ConfigurableProviders getConfigurableProviders() { + this.setConfigurableProviders(); + return configurableProviders; + } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/configloaders/ProductionConfigLoader.java b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/configloaders/ProductionConfigLoader.java index 4acb43b97..57d16e2c0 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/configloaders/ProductionConfigLoader.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/configloaders/ProductionConfigLoader.java @@ -1,6 +1,9 @@ package eu.eudat.logic.proxy.config.configloaders; +import com.fasterxml.jackson.databind.ObjectMapper; import eu.eudat.logic.proxy.config.ExternalUrls; +import eu.eudat.logic.security.customproviders.ConfigurableProvider.entities.ConfigurableProviders; +import org.apache.poi.xwpf.usermodel.XWPFDocument; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Profile; import org.springframework.core.env.Environment; @@ -8,19 +11,23 @@ import org.springframework.stereotype.Service; import javax.xml.bind.JAXBContext; import javax.xml.bind.Unmarshaller; +import java.io.BufferedReader; +import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.nio.file.Paths; +import java.util.LinkedList; +import java.util.List; -/** - * Created by ikalyvas on 2/9/2018. - */ @Service("configLoader") @Profile({ "production", "staging" }) public class ProductionConfigLoader implements ConfigLoader { private ExternalUrls externalUrls; + private List rdaProperties; + private XWPFDocument document; + private ConfigurableProviders configurableProviders; @Autowired private Environment environment; @@ -48,13 +55,69 @@ public class ProductionConfigLoader implements ConfigLoader { System.out.println("Warning: Could not close a stream after reading from file: " + fileUrl); } } - } + private void setRdaProperties() { + String filePath = environment.getProperty("configuration.rda"); + BufferedReader reader; + List rdaList = new LinkedList<>(); + try { + reader = new BufferedReader(new FileReader(filePath)); + String line = reader.readLine(); + while (line != null) { + rdaList.add(line); + line = reader.readLine(); + } + reader.close(); + } catch (IOException e) { + e.printStackTrace(); + } + + rdaProperties = rdaList; + } + + private void setDocument() { + String filePath = environment.getProperty("configuration.h2020template"); + String current = null; + try { + current = new java.io.File(".").getCanonicalPath(); + InputStream is = new URL(Paths.get(filePath).toUri().toURL().toString()).openStream(); + this.document = new XWPFDocument(is); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public void setConfigurableProviders() { + String filePath = environment.getProperty("configuration.configurable_login_providers"); + String current = null; + try { + current = new java.io.File(".").getCanonicalPath(); + InputStream is = new URL(Paths.get(filePath).toUri().toURL().toString()).openStream(); + ObjectMapper objectMapper = new ObjectMapper(); + this.configurableProviders = objectMapper.readValue(is, ConfigurableProviders.class); + } catch (IOException e) { + e.printStackTrace(); + } + } public ExternalUrls getExternalUrls() { this.setExternalUrls(); return externalUrls; } + public List getRdaProperties() { + this.setRdaProperties(); + return rdaProperties; + } + + public XWPFDocument getDocument() { + this.setDocument(); + return document; + } + + public ConfigurableProviders getConfigurableProviders() { + this.setConfigurableProviders(); + return configurableProviders; + } } \ No newline at end of file diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/fetching/RemoteFetcher.java b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/fetching/RemoteFetcher.java index b627f8e74..efc0b1db4 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/fetching/RemoteFetcher.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/fetching/RemoteFetcher.java @@ -4,22 +4,22 @@ import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import com.jayway.jsonpath.DocumentContext; import com.jayway.jsonpath.JsonPath; -import eu.eudat.logic.proxy.config.DataUrlConfiguration; -import eu.eudat.logic.proxy.config.FetchStrategy; -import eu.eudat.logic.proxy.config.UrlConfiguration; +import eu.eudat.logic.proxy.config.*; import eu.eudat.logic.proxy.config.configloaders.ConfigLoader; import eu.eudat.logic.proxy.config.exceptions.HugeResultSet; import eu.eudat.logic.proxy.config.exceptions.NoURLFound; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; import java.io.File; import java.io.IOException; +import java.io.UnsupportedEncodingException; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; +import java.net.URLEncoder; +import java.nio.file.Paths; import java.util.*; import java.util.stream.Collectors; @@ -28,165 +28,200 @@ public class RemoteFetcher { private ConfigLoader configLoader; - @Value("${configuration.resources.path}") - private String resourcesPath; - @Autowired public RemoteFetcher(ConfigLoader configLoader) { this.configLoader = configLoader; } @Cacheable("repositories") - public List> getRepositories(String query, String key) throws NoURLFound, HugeResultSet { + public List> getRepositories(ExternalUrlCriteria externalUrlCriteria, String key) throws NoURLFound, HugeResultSet { List urlConfigs = key != null && !key.isEmpty() ? configLoader.getExternalUrls().getRepositories().getUrls().stream().filter(item -> item.getKey().equals(key)).collect(Collectors.toList()) : configLoader.getExternalUrls().getRepositories().getUrls(); FetchStrategy fetchStrategy = configLoader.getExternalUrls().getRepositories().getFetchMode(); - return getAll(urlConfigs, fetchStrategy, query); + return getAll(urlConfigs, fetchStrategy, externalUrlCriteria); } @Cacheable("grants") - public List> getGrants(String query) throws NoURLFound, HugeResultSet { + public List> getGrants(ExternalUrlCriteria externalUrlCriteria) throws NoURLFound, HugeResultSet { List urlConfigs = configLoader.getExternalUrls().getGrants().getUrls(); FetchStrategy fetchStrategy = configLoader.getExternalUrls().getGrants().getFetchMode(); - return getAll(urlConfigs, fetchStrategy, query); + return getAll(urlConfigs, fetchStrategy, externalUrlCriteria); } @Cacheable("projects") - public List> getProjects(String query) throws NoURLFound, HugeResultSet { + public List> getProjects(ExternalUrlCriteria externalUrlCriteria) throws NoURLFound, HugeResultSet { List urlConfigs = configLoader.getExternalUrls().getProjects().getUrls(); FetchStrategy fetchStrategy = configLoader.getExternalUrls().getProjects().getFetchMode(); - return getAll(urlConfigs, fetchStrategy, query); + return getAll(urlConfigs, fetchStrategy, externalUrlCriteria); } @Cacheable("funders") - public List> getFunders(String query) throws NoURLFound, HugeResultSet { + public List> getFunders(ExternalUrlCriteria externalUrlCriteria) throws NoURLFound, HugeResultSet { List urlConfigs = configLoader.getExternalUrls().getFunders().getUrls(); - FetchStrategy fetchStrategy = configLoader.getExternalUrls().getProjects().getFetchMode(); - return getAll(urlConfigs, fetchStrategy, query); + FetchStrategy fetchStrategy = configLoader.getExternalUrls().getFunders().getFetchMode(); + return getAll(urlConfigs, fetchStrategy, externalUrlCriteria); } @Cacheable("organisations") - public List> getOrganisations(String query, String key) throws NoURLFound, HugeResultSet { + public List> getOrganisations(ExternalUrlCriteria externalUrlCriteria, String key) throws NoURLFound, HugeResultSet { List urlConfigs = key != null && !key.isEmpty() ? configLoader.getExternalUrls().getOrganisations().getUrls().stream().filter(item -> item.getKey().equals(key)).collect(Collectors.toList()) : configLoader.getExternalUrls().getOrganisations().getUrls(); FetchStrategy fetchStrategy = configLoader.getExternalUrls().getOrganisations().getFetchMode(); - return getAll(urlConfigs, fetchStrategy, query); + return getAll(urlConfigs, fetchStrategy, externalUrlCriteria); } @Cacheable("registries") - public List> getRegistries(String query, String key) throws NoURLFound, HugeResultSet { + public List> getRegistries(ExternalUrlCriteria externalUrlCriteria, String key) throws NoURLFound, HugeResultSet { List urlConfigs = key != null && !key.isEmpty() ? configLoader.getExternalUrls().getRegistries().getUrls().stream().filter(item -> item.getKey().equals(key)).collect(Collectors.toList()) : configLoader.getExternalUrls().getRegistries().getUrls(); FetchStrategy fetchStrategy = configLoader.getExternalUrls().getRegistries().getFetchMode(); - return getAll(urlConfigs, fetchStrategy, query); + return getAll(urlConfigs, fetchStrategy, externalUrlCriteria); } @Cacheable("services") - public List> getServices(String query, String key) throws NoURLFound, HugeResultSet { + public List> getServices(ExternalUrlCriteria externalUrlCriteria, String key) throws NoURLFound, HugeResultSet { List urlConfigs = key != null && !key.isEmpty() ? configLoader.getExternalUrls().getServices().getUrls().stream().filter(item -> item.getKey().equals(key)).collect(Collectors.toList()) : configLoader.getExternalUrls().getServices().getUrls(); FetchStrategy fetchStrategy = configLoader.getExternalUrls().getServices().getFetchMode(); - return getAll(urlConfigs, fetchStrategy, query); + return getAll(urlConfigs, fetchStrategy, externalUrlCriteria); } @Cacheable("researchers") - public List> getResearchers(String query, String key) throws NoURLFound, HugeResultSet { + public List> getResearchers(ExternalUrlCriteria externalUrlCriteria, String key) throws NoURLFound, HugeResultSet { List urlConfigs = key != null && !key.isEmpty() ? configLoader.getExternalUrls().getResearchers().getUrls().stream().filter(item -> item.getKey().equals(key)).collect(Collectors.toList()) : configLoader.getExternalUrls().getResearchers().getUrls(); FetchStrategy fetchStrategy = configLoader.getExternalUrls().getResearchers().getFetchMode(); - return getAll(urlConfigs, fetchStrategy, query); + return getAll(urlConfigs, fetchStrategy, externalUrlCriteria); } @Cacheable("tags") - public List> getTags(String query, String key) throws NoURLFound, HugeResultSet { + public List> getTags(ExternalUrlCriteria externalUrlCriteria, String key) throws NoURLFound, HugeResultSet { List urlConfigs = key != null && !key.isEmpty() ? configLoader.getExternalUrls().getTags().getUrls().stream().filter(item -> item.getKey().equals(key)).collect(Collectors.toList()) : configLoader.getExternalUrls().getTags().getUrls(); FetchStrategy fetchStrategy = configLoader.getExternalUrls().getTags().getFetchMode(); - return getAll(urlConfigs, fetchStrategy, query); + return getAll(urlConfigs, fetchStrategy, externalUrlCriteria); } - @Cacheable("datasets") - public List> getDatasets(String query, String key) throws NoURLFound, HugeResultSet { + @Cacheable("externalDatasets") + public List> getDatasets(ExternalUrlCriteria externalUrlCriteria, String key) throws NoURLFound, HugeResultSet { List urlConfigs = key != null && !key.isEmpty() ? configLoader.getExternalUrls().getDatasets().getUrls().stream().filter(item -> item.getKey().equals(key)).collect(Collectors.toList()) : configLoader.getExternalUrls().getDatasets().getUrls(); FetchStrategy fetchStrategy = configLoader.getExternalUrls().getDatasets().getFetchMode(); - return getAll(urlConfigs, fetchStrategy, query); + return getAll(urlConfigs, fetchStrategy, externalUrlCriteria); } - private List> getAll(List urlConfigs, FetchStrategy fetchStrategy, String query) throws NoURLFound, HugeResultSet { + private List> getAll(List urlConfigs, FetchStrategy fetchStrategy, ExternalUrlCriteria externalUrlCriteria) throws NoURLFound, HugeResultSet { if (urlConfigs == null || urlConfigs.isEmpty()) throw new NoURLFound("No Repository urls found in configuration"); - Collections.sort(urlConfigs, Comparator.comparing(UrlConfiguration::getOrdinal)); + urlConfigs.sort(Comparator.comparing(UrlConfiguration::getOrdinal)); List> results = new LinkedList<>(); for (UrlConfiguration urlConfig : urlConfigs) { + ifFunderQueryExist(urlConfig, externalUrlCriteria); if (urlConfig.getType() == null || urlConfig.getType().equals("External")) { - results.addAll(getAllResultsFromUrl(urlConfig.getUrl(), fetchStrategy, urlConfig.getData(), urlConfig.getPaginationPath(), query, urlConfig.getLabel())); - } - else if (urlConfig.getType() != null && urlConfig.getType().equals("Internal")) { - results.addAll(getAllResultsFromMockUpJson(urlConfig.getUrl(), query)); + results.addAll(getAllResultsFromUrl(urlConfig.getUrl(), fetchStrategy, urlConfig.getData(), urlConfig.getPaginationPath(), externalUrlCriteria, urlConfig.getLabel(), urlConfig.getContentType(), urlConfig.getFirstpage())); + } else if (urlConfig.getType() != null && urlConfig.getType().equals("Internal")) { + results.addAll(getAllResultsFromMockUpJson(urlConfig.getUrl(), externalUrlCriteria.getLike())); } } return results; } + private void ifFunderQueryExist(UrlConfiguration urlConfiguration, ExternalUrlCriteria externalUrlCriteria) { + if (urlConfiguration.getFunderQuery() != null) { + if (externalUrlCriteria.getFunderId() != null && urlConfiguration.getFunderQuery().startsWith("dmp:")) { + urlConfiguration.setUrl(urlConfiguration.getUrl().replace("{funderQuery}", urlConfiguration.getFunderQuery())); + } + else { + urlConfiguration.setUrl(urlConfiguration.getUrl().replace("{funderQuery}", "")); + } + } + } - private List> getAllResultsFromUrl(String path, FetchStrategy fetchStrategy, final DataUrlConfiguration jsonDataPath, final String jsonPaginationPath, String query, String key) throws HugeResultSet { - Set pages = new HashSet(); + private String replaceCriteriaOnUrl(String path, ExternalUrlCriteria externalUrlCriteria, String firstPage) { + String completedPath = path; + if (externalUrlCriteria.getLike() != null) { + if (path.contains("openaire") && externalUrlCriteria.getLike().equals("")) + completedPath = completedPath.replaceAll("\\{like}", "*"); + else + completedPath = completedPath.replaceAll("\\{like}", externalUrlCriteria.getLike()); + } else { + completedPath = completedPath.replace("{like}", ""); + } + if (externalUrlCriteria.getFunderId() != null) { + String funderId = externalUrlCriteria.getFunderId(); + try { + funderId = URLEncoder.encode(externalUrlCriteria.getFunderId(), "UTF-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + completedPath = completedPath.replace("{funderId}", funderId); + } + if (externalUrlCriteria.getPage() != null) { + completedPath = completedPath.replace("{page}", externalUrlCriteria.getPage()); + } else { + if (firstPage != null) { + completedPath = completedPath.replace("{page}", firstPage); + } else { + completedPath = completedPath.replace("{page}", "1"); + } + } + if (externalUrlCriteria.getPageSize() != null) { + completedPath = completedPath.replace("{pageSize}", externalUrlCriteria.getPageSize()); + } else { + completedPath = completedPath.replace("{pageSize}", "10"); + } + return completedPath; + } - final String searchQuery = (query != null) && !query.isEmpty() ? "&search=" + query : ""; + private List> getAllResultsFromUrl(String path, FetchStrategy fetchStrategy, final DataUrlConfiguration jsonDataPath, final String jsonPaginationPath, ExternalUrlCriteria externalUrlCriteria, String key, String contentType, String firstPage) throws HugeResultSet { + Set pages = new HashSet<>(); - Results results = getResultsFromUrl(path + "?page=1" + searchQuery, jsonDataPath, jsonPaginationPath); + String replacedPath = replaceCriteriaOnUrl(path, externalUrlCriteria, firstPage); + Results results = getResultsFromUrl(replacedPath, jsonDataPath, jsonPaginationPath, contentType); if (fetchStrategy == FetchStrategy.FIRST) - return results == null ? new LinkedList<>() : results.getResults().stream().map(x -> { - x.put("tag", key); - return x; - }).collect(Collectors.toList()); + return results == null ? new LinkedList<>() : results.getResults().stream().peek(x -> x.put("tag", key)).collect(Collectors.toList()); - if (results.getPagination() != null && results.getPagination().get("pages") != null) //if has more pages, add them to the pages set + if (results != null && results.getPagination() != null && results.getPagination().get("pages") != null) //if has more pages, add them to the pages set for (int i = 2; i <= results.getPagination().get("pages"); i++) pages.add(i); Long maxResults = configLoader.getExternalUrls().getMaxresults(); - if ((maxResults > 0) && (results.getPagination().get("count") > maxResults)) - throw new HugeResultSet("The submitted search query " + query + " is about to return " + results.getPagination().get("count") + " results... Please submit a more detailed search query"); + if ((maxResults > 0 && results != null) && (results.getPagination().get("count") > maxResults)) + throw new HugeResultSet("The submitted search query " + externalUrlCriteria.getLike() + " is about to return " + results.getPagination().get("count") + " results... Please submit a more detailed search query"); Optional optionalResults = pages.parallelStream() - .map(page -> getResultsFromUrl(path + "?page=" + page + searchQuery, jsonDataPath, jsonPaginationPath)) + .map(page -> getResultsFromUrl(path + "&page=" + page, jsonDataPath, jsonPaginationPath, contentType)) .reduce((result1, result2) -> { result1.getResults().addAll(result2.getResults()); return result1; }); - Results remainingResults = optionalResults.isPresent() ? optionalResults.get() : new Results(); - + Results remainingResults = optionalResults.orElseGet(Results::new); remainingResults.getResults().addAll(results.getResults()); - return remainingResults.getResults().stream().map(x -> { - x.put("tag", key); - return x; - }).collect(Collectors.toList()); + return remainingResults.getResults().stream().peek(x -> x.put("tag", key)).collect(Collectors.toList()); } - private Results getResultsFromUrl(String urlString, DataUrlConfiguration jsonDataPath, String jsonPaginationPath) { + private Results getResultsFromUrl(String urlString, DataUrlConfiguration jsonDataPath, String jsonPaginationPath, String contentType) { try { - URL url = new URL(urlString); + URL url = new URL(urlString.replace(" ", "%20")); HttpURLConnection con = (HttpURLConnection) url.openConnection(); con.setRequestMethod("GET"); - con.setRequestProperty("Accept", "application/vnd.api+json; charset=utf-8"); + con.setRequestProperty("Accept", contentType); int responseCode = con.getResponseCode(); if (responseCode == HttpURLConnection.HTTP_OK) { // success @@ -198,9 +233,13 @@ public class RemoteFetcher { + "[" + jsonDataPath.getFieldsUrlConfiguration().getName() + "," + jsonDataPath.getFieldsUrlConfiguration().getDescription() + "," + jsonDataPath.getFieldsUrlConfiguration().getUri() + "," + jsonDataPath.getFieldsUrlConfiguration().getId() + "," + jsonDataPath.getFieldsUrlConfiguration().getSource() + "]"), - jsonContext.read(jsonPaginationPath)); - } - else { + new HashMap<>(1, 1)); + } else if (jsonDataPath.getFieldsUrlConfiguration().getCount() != null) { // parsing services.openaire.eu + results = new Results(jsonContext.read(jsonDataPath.getPath() + + "[" + jsonDataPath.getFieldsUrlConfiguration().getName() + + "," + jsonDataPath.getFieldsUrlConfiguration().getId() + "]"), + new HashMap<>(1, 1)); + } else { results = new Results(jsonContext.read(jsonDataPath.getPath() + "[" + jsonDataPath.getFieldsUrlConfiguration().getName() + "," + jsonDataPath.getFieldsUrlConfiguration().getDescription() + "," + jsonDataPath.getFieldsUrlConfiguration().getUri() + "," + jsonDataPath.getFieldsUrlConfiguration().getId() + "]"), @@ -226,9 +265,9 @@ public class RemoteFetcher { } private List> getAllResultsFromMockUpJson(String path, String query) { - String filePath = this.resourcesPath + path; List> internalResults; try { + String filePath = Paths.get(path).toUri().toURL().toString(); ObjectMapper mapper = new ObjectMapper(); internalResults = mapper.readValue(new File(filePath), new TypeReference>>(){}); searchListMap(internalResults, query); @@ -254,11 +293,12 @@ public class RemoteFetcher { } private String transformKey(DataUrlConfiguration dataUrlConfiguration, String key) { - if (key.equals(dataUrlConfiguration.getFieldsUrlConfiguration().getId().replace("'",""))) return "pid"; - if (key.equals(dataUrlConfiguration.getFieldsUrlConfiguration().getDescription().replace("'",""))) return "description"; - if (key.equals(dataUrlConfiguration.getFieldsUrlConfiguration().getUri().replace("'",""))) return "uri"; - if (key.equals(dataUrlConfiguration.getFieldsUrlConfiguration().getName().replace("'",""))) return "name"; - if (key.equals(dataUrlConfiguration.getFieldsUrlConfiguration().getSource().replace("'",""))) return "source"; + if (dataUrlConfiguration.getFieldsUrlConfiguration().getId() != null && key.equals(dataUrlConfiguration.getFieldsUrlConfiguration().getId().replace("'",""))) return "pid"; + if (dataUrlConfiguration.getFieldsUrlConfiguration().getDescription() != null && key.equals(dataUrlConfiguration.getFieldsUrlConfiguration().getDescription().replace("'",""))) return "description"; + if (dataUrlConfiguration.getFieldsUrlConfiguration().getUri() != null && key.equals(dataUrlConfiguration.getFieldsUrlConfiguration().getUri().replace("'",""))) return "uri"; + if (dataUrlConfiguration.getFieldsUrlConfiguration().getName() != null && key.equals(dataUrlConfiguration.getFieldsUrlConfiguration().getName().replace("'",""))) return "name"; + if (dataUrlConfiguration.getFieldsUrlConfiguration().getSource() != null && key.equals(dataUrlConfiguration.getFieldsUrlConfiguration().getSource().replace("'",""))) return "source"; + if (dataUrlConfiguration.getFieldsUrlConfiguration().getCount() != null && key.equals(dataUrlConfiguration.getFieldsUrlConfiguration().getCount().replace("'",""))) return "count"; return null; } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/B2Access/B2AccessCustomProviderImpl.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/B2Access/B2AccessCustomProviderImpl.java index 4a4066fb4..c986edb01 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/B2Access/B2AccessCustomProviderImpl.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/B2Access/B2AccessCustomProviderImpl.java @@ -16,9 +16,6 @@ import org.springframework.web.client.RestTemplate; import java.nio.charset.Charset; import java.util.Map; -/** - * Created by ikalyvas on 2/22/2018. - */ @Component("b2AccessCustomProvider") public class B2AccessCustomProviderImpl implements B2AccessCustomProvider { @@ -54,7 +51,6 @@ public class B2AccessCustomProviderImpl implements B2AccessCustomProvider { map.add("redirect_uri", redirectUri); HttpEntity> request = new HttpEntity>(map, headers); - Map values = template.postForObject(this.environment.getProperty("b2access.externallogin.access_token_url"), request, Map.class); B2AccessResponseToken b2AccessResponseToken = new B2AccessResponseToken(); b2AccessResponseToken.setAccessToken((String) values.get("access_token")); diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/ConfigurableProvider/ConfigurableProviderCustomProvider.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/ConfigurableProvider/ConfigurableProviderCustomProvider.java new file mode 100644 index 000000000..0f29de3fa --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/ConfigurableProvider/ConfigurableProviderCustomProvider.java @@ -0,0 +1,11 @@ +package eu.eudat.logic.security.customproviders.ConfigurableProvider; + +import eu.eudat.logic.security.customproviders.ConfigurableProvider.entities.ConfigurableProviderUserSettings; +import eu.eudat.logic.security.validators.configurableProvider.helpers.ConfigurableProviderResponseToken; + +public interface ConfigurableProviderCustomProvider { + + ConfigurableProviderResponseToken getAccessToken(String code, String redirectUri, String clientId, String clientSecret, String accessTokenUrl, String grantType, String access_token, String expires_in); + + ConfigurableProviderUser getUser(String accessToken, ConfigurableProviderUserSettings user); +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/ConfigurableProvider/ConfigurableProviderCustomProviderImpl.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/ConfigurableProvider/ConfigurableProviderCustomProviderImpl.java new file mode 100644 index 000000000..1ebf8c336 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/ConfigurableProvider/ConfigurableProviderCustomProviderImpl.java @@ -0,0 +1,61 @@ +package eu.eudat.logic.security.customproviders.ConfigurableProvider; + +import eu.eudat.logic.security.customproviders.ConfigurableProvider.entities.ConfigurableProviderUserSettings; +import eu.eudat.logic.security.validators.configurableProvider.helpers.ConfigurableProviderResponseToken; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Component; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.RestTemplate; + +import java.util.Map; + +@Component("configurableProviderCustomProvider") +public class ConfigurableProviderCustomProviderImpl implements ConfigurableProviderCustomProvider { + + @Override + public ConfigurableProviderResponseToken getAccessToken(String code, String redirectUri, String clientId, String clientSecret, String accessTokenUrl, + String grantType, String access_token, String expires_in) { + RestTemplate template = new RestTemplate(); + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); + + MultiValueMap map = new LinkedMultiValueMap(); + + map.add("grant_type", grantType); + map.add("code", code); + map.add("redirect_uri", redirectUri); + map.add("client_id", clientId); + map.add("client_secret", clientSecret); + HttpEntity> request = new HttpEntity<>(map, headers); + + Map values = template.postForObject(accessTokenUrl, request, Map.class); + ConfigurableProviderResponseToken responseToken = new ConfigurableProviderResponseToken(); + responseToken.setAccessToken((String) values.get(access_token)); + if (expires_in != null && !expires_in.isEmpty()) { + responseToken.setExpiresIn((Integer) values.get(expires_in)); + } + + return responseToken; + } + + @Override + public ConfigurableProviderUser getUser(String accessToken, ConfigurableProviderUserSettings user) { + RestTemplate restTemplate = new RestTemplate(); + HttpHeaders headers = this.createBearerAuthHeaders(accessToken); + HttpEntity entity = new HttpEntity<>(headers); + + Map values = restTemplate.exchange(user.getUser_info_url(), HttpMethod.GET, entity, Map.class).getBody(); + return new ConfigurableProviderUser().getConfigurableProviderUser(values, user); + } + + private HttpHeaders createBearerAuthHeaders(String accessToken) { + return new HttpHeaders() {{ + String authHeader = "Bearer " + accessToken; + set("Authorization", authHeader); + }}; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/ConfigurableProvider/ConfigurableProviderUser.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/ConfigurableProvider/ConfigurableProviderUser.java new file mode 100644 index 000000000..111abad14 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/ConfigurableProvider/ConfigurableProviderUser.java @@ -0,0 +1,42 @@ +package eu.eudat.logic.security.customproviders.ConfigurableProvider; + +import eu.eudat.logic.security.customproviders.ConfigurableProvider.entities.ConfigurableProviderUserSettings; + +import java.util.Map; + +public class ConfigurableProviderUser { + private String id; + private String name; + private String email; + + public String getId() { + return id; + } + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + + public String getEmail() { + return email; + } + public void setEmail(String email) { + this.email = email; + } + + ConfigurableProviderUser getConfigurableProviderUser(Map data, ConfigurableProviderUserSettings user) { + if (user.getId() != null && !user.getId().isEmpty()) + this.id = (String) data.get(user.getId()); + if (user.getName() != null && !user.getName().isEmpty()) + this.name = (String) data.get(user.getName()); + if (user.getEmail() != null && !user.getEmail().isEmpty()) + this.email = (String) data.get(user.getEmail()); + return this; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/ConfigurableProvider/entities/ConfigurableProvider.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/ConfigurableProvider/entities/ConfigurableProvider.java new file mode 100644 index 000000000..2e62f7007 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/ConfigurableProvider/entities/ConfigurableProvider.java @@ -0,0 +1,109 @@ +package eu.eudat.logic.security.customproviders.ConfigurableProvider.entities; + +public class ConfigurableProvider { + + private boolean enabled; + private String configurableLoginId; + private String name; + private String clientId; + private String clientSecret; + private String redirect_uri; + private String access_token_url; + private String grant_type; + private ConfigurableProviderToken token; + private ConfigurableProviderUserSettings user; + private String oauthUrl; + private String scope; + private String state; + + public boolean getEnabled() { + return enabled; + } + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + public String getConfigurableLoginId() { + return configurableLoginId; + } + public void setConfigurableLoginId(String configurableLoginId) { + this.configurableLoginId = configurableLoginId; + } + + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + + 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 getRedirect_uri() { + return redirect_uri; + } + public void setRedirect_uri(String redirect_uri) { + this.redirect_uri = redirect_uri; + } + + public String getAccess_token_url() { + return access_token_url; + } + public void setAccess_token_url(String access_token_url) { + this.access_token_url = access_token_url; + } + + public String getGrant_type() { + return grant_type; + } + public void setGrant_type(String grant_type) { + this.grant_type = grant_type; + } + + public ConfigurableProviderToken getToken() { + return token; + } + public void setToken(ConfigurableProviderToken token) { + this.token = token; + } + + public ConfigurableProviderUserSettings getUser() { + return user; + } + public void setUser(ConfigurableProviderUserSettings user) { + this.user = user; + } + + public String getOauthUrl() { + return oauthUrl; + } + public void setOauthUrl(String oauthUrl) { + this.oauthUrl = oauthUrl; + } + + public String getScope() { + return scope; + } + public void setScope(String scope) { + this.scope = scope; + } + + public String getState() { + return state; + } + public void setState(String state) { + this.state = state; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/ConfigurableProvider/entities/ConfigurableProviderToken.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/ConfigurableProvider/entities/ConfigurableProviderToken.java new file mode 100644 index 000000000..ac2021a82 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/ConfigurableProvider/entities/ConfigurableProviderToken.java @@ -0,0 +1,20 @@ +package eu.eudat.logic.security.customproviders.ConfigurableProvider.entities; + +public class ConfigurableProviderToken { + private String access_token; + private String expires_in; + + public String getAccess_token() { + return access_token; + } + public void setAccess_token(String access_token) { + this.access_token = access_token; + } + + public String getExpires_in() { + return expires_in; + } + public void setExpires_in(String expires_in) { + this.expires_in = expires_in; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/ConfigurableProvider/entities/ConfigurableProviderUserSettings.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/ConfigurableProvider/entities/ConfigurableProviderUserSettings.java new file mode 100644 index 000000000..693957ca3 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/ConfigurableProvider/entities/ConfigurableProviderUserSettings.java @@ -0,0 +1,36 @@ +package eu.eudat.logic.security.customproviders.ConfigurableProvider.entities; + +public class ConfigurableProviderUserSettings { + private String id; + private String name; + private String email; + private String user_info_url; + + public String getId() { + return id; + } + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + + public String getEmail() { + return email; + } + public void setEmail(String email) { + this.email = email; + } + + public String getUser_info_url() { + return user_info_url; + } + public void setUser_info_url(String user_info_url) { + this.user_info_url = user_info_url; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/ConfigurableProvider/entities/ConfigurableProviders.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/ConfigurableProvider/entities/ConfigurableProviders.java new file mode 100644 index 000000000..01967ce32 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/ConfigurableProvider/entities/ConfigurableProviders.java @@ -0,0 +1,15 @@ +package eu.eudat.logic.security.customproviders.ConfigurableProvider.entities; + +import java.util.ArrayList; +import java.util.List; + +public class ConfigurableProviders { + private List providers = new ArrayList<>(); + + public List getProviders() { + return providers; + } + public void setProviders(List providers) { + this.providers = providers; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/ConfigurableProvider/models/ConfigurableProviderModel.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/ConfigurableProvider/models/ConfigurableProviderModel.java new file mode 100644 index 000000000..b09b002d2 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/ConfigurableProvider/models/ConfigurableProviderModel.java @@ -0,0 +1,76 @@ +package eu.eudat.logic.security.customproviders.ConfigurableProvider.models; + +import eu.eudat.logic.security.customproviders.ConfigurableProvider.entities.ConfigurableProvider; + +public class ConfigurableProviderModel { + + private String configurableLoginId; + private String name; + private String clientId; + private String redirect_uri; + private String oauthUrl; + private String scope; + private String state; + + public String getConfigurableLoginId() { + return configurableLoginId; + } + public void setConfigurableLoginId(String configurableLoginId) { + this.configurableLoginId = configurableLoginId; + } + + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + + public String getClientId() { + return clientId; + } + public void setClientId(String clientId) { + this.clientId = clientId; + } + + public String getRedirect_uri() { + return redirect_uri; + } + public void setRedirect_uri(String redirect_uri) { + this.redirect_uri = redirect_uri; + } + + public String getOauthUrl() { + return oauthUrl; + } + public void setOauthUrl(String oauthUrl) { + this.oauthUrl = oauthUrl; + } + + public String getScope() { + return scope; + } + public void setScope(String scope) { + this.scope = scope; + } + + public String getState() { + return state; + } + public void setState(String state) { + this.state = state; + } + + public ConfigurableProviderModel fromDataModel(ConfigurableProvider entity) { + ConfigurableProviderModel model = new ConfigurableProviderModel(); + model.setConfigurableLoginId(entity.getConfigurableLoginId()); + model.setName(entity.getName()); + model.setClientId(entity.getClientId()); + model.setRedirect_uri(entity.getRedirect_uri()); + model.setOauthUrl(entity.getOauthUrl()); + model.setScope(entity.getScope()); + model.setState(entity.getState()); + + return model; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/ConfigurableProvider/models/ConfigurableProvidersModel.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/ConfigurableProvider/models/ConfigurableProvidersModel.java new file mode 100644 index 000000000..28514d6d4 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/ConfigurableProvider/models/ConfigurableProvidersModel.java @@ -0,0 +1,31 @@ +package eu.eudat.logic.security.customproviders.ConfigurableProvider.models; + +import eu.eudat.logic.security.customproviders.ConfigurableProvider.entities.ConfigurableProvider; +import eu.eudat.logic.security.customproviders.ConfigurableProvider.entities.ConfigurableProviders; + +import java.util.LinkedList; +import java.util.List; + +public class ConfigurableProvidersModel { + private List providers; + + public List getProviders() { + return providers; + } + public void setProviders(List providers) { + this.providers = providers; + } + + public ConfigurableProvidersModel fromDataModel(ConfigurableProviders entity) { + ConfigurableProvidersModel model = new ConfigurableProvidersModel(); + List providerModelList = new LinkedList<>(); + if (entity != null) { + for (ConfigurableProvider entityProvider : entity.getProviders()) { + if (entityProvider.getEnabled()) + providerModelList.add(new ConfigurableProviderModel().fromDataModel(entityProvider)); + } + } + model.setProviders(providerModelList); + return model; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/LinkedIn/LinkedInCustomProvider.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/LinkedIn/LinkedInCustomProvider.java new file mode 100644 index 000000000..2d8c481ce --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/LinkedIn/LinkedInCustomProvider.java @@ -0,0 +1,10 @@ +package eu.eudat.logic.security.customproviders.LinkedIn; + +import eu.eudat.logic.security.validators.linkedin.helpers.LinkedInResponseToken; + +public interface LinkedInCustomProvider { + + LinkedInUser getUser(String accessToken); + + LinkedInResponseToken getAccessToken(String code, String redirectUri, String clientId, String clientSecret); +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/LinkedIn/LinkedInCustomProviderImpl.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/LinkedIn/LinkedInCustomProviderImpl.java new file mode 100644 index 000000000..ed09ceee8 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/LinkedIn/LinkedInCustomProviderImpl.java @@ -0,0 +1,67 @@ +package eu.eudat.logic.security.customproviders.LinkedIn; + +import eu.eudat.logic.security.validators.linkedin.helpers.LinkedInResponseToken; +import org.springframework.core.env.Environment; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Component; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.RestTemplate; + +import java.util.Map; + +@Component("LinkedInCustomProvider") +public class LinkedInCustomProviderImpl implements LinkedInCustomProvider { + + private Environment environment; + + public LinkedInCustomProviderImpl(Environment environment) { + this.environment = environment; + } + + public LinkedInUser getUser(String accessToken) { + RestTemplate restTemplate = new RestTemplate(); + HttpHeaders headers = this.createBearerAuthHeaders(accessToken); + HttpEntity entity = new HttpEntity<>(headers); + + Map profileValues = restTemplate.exchange(this.environment.getProperty("linkedin.login.user_info_url"), HttpMethod.GET, entity, Map.class).getBody(); + Map emailValues = restTemplate.exchange(this.environment.getProperty("linkedin.login.user_email"), HttpMethod.GET, entity, Map.class).getBody(); + LinkedInUser linkedInUser = new LinkedInUser(); + linkedInUser.setEmail((String)emailValues.get("email")); + linkedInUser.setName((String)profileValues.get("localizedFirstName")); + linkedInUser.setId((String)profileValues.get("id")); + return linkedInUser; + } + + public LinkedInResponseToken getAccessToken(String code, String redirectUri, String clientId, String clientSecret) { + RestTemplate template = new RestTemplate(); + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); + + MultiValueMap map = new LinkedMultiValueMap(); + + map.add("grant_type", "authorization_code"); + map.add("code", code); + map.add("redirect_uri", redirectUri); + map.add("client_id", clientId); + map.add("client_secret", clientSecret); + HttpEntity> request = new HttpEntity>(map, headers); + + Map values = template.postForObject(this.environment.getProperty("linkedin.login.access_token_url"), request, Map.class); + LinkedInResponseToken linkedInResponseToken = new LinkedInResponseToken(); + linkedInResponseToken.setAccessToken((String) values.get("access_token")); + linkedInResponseToken.setExpiresIn((Integer) values.get("expires_in")); + + return linkedInResponseToken; + } + + private HttpHeaders createBearerAuthHeaders(String accessToken) { + return new HttpHeaders() {{ + String authHeader = "Bearer " + new String(accessToken); + set("Authorization", authHeader); + }}; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/LinkedIn/LinkedInUser.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/LinkedIn/LinkedInUser.java new file mode 100644 index 000000000..0cbe2d7df --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/LinkedIn/LinkedInUser.java @@ -0,0 +1,29 @@ +package eu.eudat.logic.security.customproviders.LinkedIn; + +public class LinkedInUser { + private String id; + private String name; + private String email; + + + public String getId() { + return id; + } + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + + public String getEmail() { + return email; + } + public void setEmail(String email) { + this.email = email; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/OpenAIRE/OpenAIRECustomProvider.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/OpenAIRE/OpenAIRECustomProvider.java new file mode 100644 index 000000000..3b7855e08 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/OpenAIRE/OpenAIRECustomProvider.java @@ -0,0 +1,10 @@ +package eu.eudat.logic.security.customproviders.OpenAIRE; + +import eu.eudat.logic.security.validators.openaire.helpers.OpenAIREResponseToken; + +public interface OpenAIRECustomProvider { + + OpenAIREResponseToken getAccessToken(String code, String redirectUri, String clientId, String clientSecret); + + OpenAIREUser getUser(String accessToken); +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/OpenAIRE/OpenAIRECustomProviderImpl.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/OpenAIRE/OpenAIRECustomProviderImpl.java new file mode 100644 index 000000000..cd465142f --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/OpenAIRE/OpenAIRECustomProviderImpl.java @@ -0,0 +1,62 @@ +package eu.eudat.logic.security.customproviders.OpenAIRE; + +import eu.eudat.logic.security.validators.openaire.helpers.OpenAIREResponseToken; +import org.springframework.core.env.Environment; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Component; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.RestTemplate; + +import java.util.Map; + +@Component("openAIRECustomProvider") +public class OpenAIRECustomProviderImpl implements OpenAIRECustomProvider { + + private Environment environment; + + public OpenAIRECustomProviderImpl(Environment environment) { + this.environment = environment; + } + + public OpenAIREUser getUser(String accessToken) { + RestTemplate restTemplate = new RestTemplate(); + HttpHeaders headers = this.createBearerAuthHeaders(accessToken); + HttpEntity entity = new HttpEntity<>(headers); + + Map values = restTemplate.exchange(this.environment.getProperty("openaire.login.user_info_url"), HttpMethod.GET, entity, Map.class).getBody(); + return new OpenAIREUser().getOpenAIREUser(values); + } + + public OpenAIREResponseToken getAccessToken(String code, String redirectUri, String clientId, String clientSecret) { + RestTemplate template = new RestTemplate(); + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); + + MultiValueMap map = new LinkedMultiValueMap(); + + map.add("grant_type", "authorization_code"); + map.add("code", code); + map.add("redirect_uri", redirectUri); + map.add("client_id", clientId); + map.add("client_secret", clientSecret); + HttpEntity> request = new HttpEntity>(map, headers); + + Map values = template.postForObject(this.environment.getProperty("openaire.login.access_token_url"), request, Map.class); + OpenAIREResponseToken openAIREResponseToken = new OpenAIREResponseToken(); + openAIREResponseToken.setAccessToken((String) values.get("access_token")); + openAIREResponseToken.setExpiresIn((Integer) values.get("expires_in")); + + return openAIREResponseToken; + } + + private HttpHeaders createBearerAuthHeaders(String accessToken) { + return new HttpHeaders() {{ + String authHeader = "Bearer " + accessToken; + set("Authorization", authHeader); + }}; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/OpenAIRE/OpenAIREUser.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/OpenAIRE/OpenAIREUser.java new file mode 100644 index 000000000..e20b65132 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/OpenAIRE/OpenAIREUser.java @@ -0,0 +1,37 @@ +package eu.eudat.logic.security.customproviders.OpenAIRE; + +import java.util.Map; + +public class OpenAIREUser { + private String id; + private String name; + private String email; + + public String getId() { + return id; + } + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + + public String getEmail() { + return email; + } + public void setEmail(String email) { + this.email = email; + } + + public OpenAIREUser getOpenAIREUser(Object data) { + this.id = (String) ((Map) data).get("sub"); + this.name = (String) ((Map) data).get("name"); + this.email = (String) ((Map) data).get("email"); + return this; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/TokenValidatorFactoryImpl.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/TokenValidatorFactoryImpl.java index 404de9b55..9b594c96e 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/TokenValidatorFactoryImpl.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/TokenValidatorFactoryImpl.java @@ -1,14 +1,19 @@ package eu.eudat.logic.security.validators; +import eu.eudat.logic.proxy.config.configloaders.ConfigLoader; import eu.eudat.logic.security.customproviders.B2Access.B2AccessCustomProvider; +import eu.eudat.logic.security.customproviders.ConfigurableProvider.ConfigurableProviderCustomProvider; +import eu.eudat.logic.security.customproviders.LinkedIn.LinkedInCustomProvider; import eu.eudat.logic.security.customproviders.ORCID.ORCIDCustomProvider; +import eu.eudat.logic.security.customproviders.OpenAIRE.OpenAIRECustomProvider; import eu.eudat.logic.security.validators.b2access.B2AccessTokenValidator; +import eu.eudat.logic.security.validators.configurableProvider.ConfigurableProviderTokenValidator; import eu.eudat.logic.security.validators.facebook.FacebookTokenValidator; import eu.eudat.logic.security.validators.google.GoogleTokenValidator; import eu.eudat.logic.security.validators.linkedin.LinkedInTokenValidator; +import eu.eudat.logic.security.validators.openaire.OpenAIRETokenValidator; import eu.eudat.logic.security.validators.orcid.ORCIDTokenValidator; import eu.eudat.logic.security.validators.twitter.TwitterTokenValidator; -import eu.eudat.logic.services.ApiContext; import eu.eudat.logic.services.operations.authentication.AuthenticationService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.env.Environment; @@ -18,7 +23,7 @@ import org.springframework.stereotype.Service; @Service("tokenValidatorFactory") public class TokenValidatorFactoryImpl implements TokenValidatorFactory { public enum LoginProvider { - GOOGLE(1), FACEBOOK(2), TWITTER(3), LINKEDIN(4), NATIVELOGIN(5), B2_ACCESS(6), ORCID(7); + GOOGLE(1), FACEBOOK(2), TWITTER(3), LINKEDIN(4), NATIVELOGIN(5), B2_ACCESS(6), ORCID(7), OPENAIRE(8), CONFIGURABLE(9); private int value; @@ -46,41 +51,58 @@ public class TokenValidatorFactoryImpl implements TokenValidatorFactory { return B2_ACCESS; case 7: return ORCID; + case 8: + return OPENAIRE; + case 9: + return CONFIGURABLE; default: throw new RuntimeException("Unsupported LoginProvider"); } } } - private ApiContext apiContext; private Environment environment; private AuthenticationService nonVerifiedUserAuthenticationService; private B2AccessCustomProvider b2AccessCustomProvider; private ORCIDCustomProvider orcidCustomProvider; + private LinkedInCustomProvider linkedInCustomProvider; + private OpenAIRECustomProvider openAIRECustomProvider; + private ConfigurableProviderCustomProvider configurableProviderCustomProvider; + private ConfigLoader configLoader; @Autowired - public TokenValidatorFactoryImpl(ApiContext apiContext, Environment environment, AuthenticationService nonVerifiedUserAuthenticationService, B2AccessCustomProvider b2AccessCustomProvider, ORCIDCustomProvider orcidCustomProvider) { - this.apiContext = apiContext; + public TokenValidatorFactoryImpl( + Environment environment, + AuthenticationService nonVerifiedUserAuthenticationService, B2AccessCustomProvider b2AccessCustomProvider, + ORCIDCustomProvider orcidCustomProvider, LinkedInCustomProvider linkedInCustomProvider, OpenAIRECustomProvider openAIRECustomProvider, ConfigurableProviderCustomProvider configurableProviderCustomProvider, ConfigLoader configLoader) { this.environment = environment; this.nonVerifiedUserAuthenticationService = nonVerifiedUserAuthenticationService; this.b2AccessCustomProvider = b2AccessCustomProvider; this.orcidCustomProvider = orcidCustomProvider; + this.linkedInCustomProvider = linkedInCustomProvider; + this.openAIRECustomProvider = openAIRECustomProvider; + this.configurableProviderCustomProvider = configurableProviderCustomProvider; + this.configLoader = configLoader; } public TokenValidator getProvider(LoginProvider provider) { switch (provider) { case GOOGLE: - return new GoogleTokenValidator(this.apiContext, this.environment, this.nonVerifiedUserAuthenticationService); + return new GoogleTokenValidator(this.environment, this.nonVerifiedUserAuthenticationService); case FACEBOOK: - return new FacebookTokenValidator(this.apiContext, this.environment, this.nonVerifiedUserAuthenticationService); + return new FacebookTokenValidator(this.environment, this.nonVerifiedUserAuthenticationService); case LINKEDIN: - return new LinkedInTokenValidator(this.apiContext, this.environment, this.nonVerifiedUserAuthenticationService); + return new LinkedInTokenValidator(this.environment, this.nonVerifiedUserAuthenticationService, linkedInCustomProvider); case TWITTER: - return new TwitterTokenValidator(this.apiContext, this.environment, this.nonVerifiedUserAuthenticationService); + return new TwitterTokenValidator(this.environment, this.nonVerifiedUserAuthenticationService); case B2_ACCESS: return new B2AccessTokenValidator(this.environment, this.nonVerifiedUserAuthenticationService, this.b2AccessCustomProvider); case ORCID: - return new ORCIDTokenValidator(this.environment, this.nonVerifiedUserAuthenticationService, this.orcidCustomProvider, this.apiContext); + return new ORCIDTokenValidator(this.environment, this.nonVerifiedUserAuthenticationService, this.orcidCustomProvider); + case OPENAIRE: + return new OpenAIRETokenValidator(this.environment, this.nonVerifiedUserAuthenticationService, this.openAIRECustomProvider); + case CONFIGURABLE: + return new ConfigurableProviderTokenValidator(this.configurableProviderCustomProvider, this.nonVerifiedUserAuthenticationService, this.configLoader); default: throw new RuntimeException("Login Provider Not Implemented"); } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/b2access/B2AccessTokenValidator.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/b2access/B2AccessTokenValidator.java index a1057377b..a5adf52fa 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/b2access/B2AccessTokenValidator.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/b2access/B2AccessTokenValidator.java @@ -18,9 +18,6 @@ import org.springframework.stereotype.Component; import java.io.IOException; import java.security.GeneralSecurityException; -/** - * Created by ikalyvas on 2/22/2018. - */ @Component("b2AccessTokenValidator ") public class B2AccessTokenValidator implements TokenValidator { diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/configurableProvider/ConfigurableProviderTokenValidator.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/configurableProvider/ConfigurableProviderTokenValidator.java new file mode 100644 index 000000000..bf426f96e --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/configurableProvider/ConfigurableProviderTokenValidator.java @@ -0,0 +1,61 @@ +package eu.eudat.logic.security.validators.configurableProvider; + +import eu.eudat.exceptions.security.NullEmailException; +import eu.eudat.logic.proxy.config.configloaders.ConfigLoader; + +import eu.eudat.logic.security.customproviders.ConfigurableProvider.ConfigurableProviderCustomProvider; +import eu.eudat.logic.security.customproviders.ConfigurableProvider.ConfigurableProviderUser; +import eu.eudat.logic.security.customproviders.ConfigurableProvider.entities.ConfigurableProvider; +import eu.eudat.logic.security.validators.TokenValidator; +import eu.eudat.logic.security.validators.configurableProvider.helpers.ConfigurableProviderRequest; +import eu.eudat.logic.security.validators.configurableProvider.helpers.ConfigurableProviderResponseToken; +import eu.eudat.logic.services.operations.authentication.AuthenticationService; +import eu.eudat.models.data.login.LoginInfo; +import eu.eudat.models.data.loginprovider.LoginProviderUser; +import eu.eudat.models.data.security.Principal; +import org.springframework.stereotype.Component; + +import java.util.Map; +import java.util.stream.Collectors; + +@Component("configurableProviderTokenValidator") +public class ConfigurableProviderTokenValidator implements TokenValidator { + + private ConfigurableProviderCustomProvider configurableProvider; + private AuthenticationService nonVerifiedUserAuthenticationService; + private ConfigLoader configLoader; + + public ConfigurableProviderTokenValidator(ConfigurableProviderCustomProvider configurableProvider, AuthenticationService nonVerifiedUserAuthenticationService, ConfigLoader configLoader) { + this.configurableProvider = configurableProvider; + this.nonVerifiedUserAuthenticationService = nonVerifiedUserAuthenticationService; + this.configLoader = configLoader; + } + + public ConfigurableProviderResponseToken getAccessToken(ConfigurableProviderRequest configurableProviderRequest) { + ConfigurableProvider provider = getConfigurableProviderFromId(configurableProviderRequest.getConfigurableLoginId()); + return this.configurableProvider.getAccessToken(configurableProviderRequest.getCode(), + provider.getRedirect_uri(), provider.getClientId(), provider.getClientSecret(), + provider.getAccess_token_url(), provider.getGrant_type(), provider.getToken().getAccess_token(), provider.getToken().getExpires_in()); + } + @Override + public Principal validateToken(LoginInfo credentials) throws NullEmailException { + String configurableLoginId = ((Map) credentials.getData()).get("configurableLoginId").toString(); + ConfigurableProvider configurableProvider = getConfigurableProviderFromId(configurableLoginId); + ConfigurableProviderUser configurableUser = this.configurableProvider.getUser(credentials.getTicket(), configurableProvider.getUser()); + LoginProviderUser user = new LoginProviderUser(); + user.setId(configurableUser.getId()); + user.setEmail(configurableUser.getEmail()); + user.setName(configurableUser.getName()); + user.setProvider(credentials.getProvider()); + user.setSecret(credentials.getTicket()); + + return this.nonVerifiedUserAuthenticationService.Touch(user); + } + + private ConfigurableProvider getConfigurableProviderFromId(String configurableId) { + return this.configLoader.getConfigurableProviders().getProviders().stream() + .filter(prov -> prov.getConfigurableLoginId().equals(configurableId)) + .collect(Collectors.toList()) + .get(0); + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/configurableProvider/helpers/ConfigurableProviderRequest.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/configurableProvider/helpers/ConfigurableProviderRequest.java new file mode 100644 index 000000000..7877c88c3 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/configurableProvider/helpers/ConfigurableProviderRequest.java @@ -0,0 +1,20 @@ +package eu.eudat.logic.security.validators.configurableProvider.helpers; + +public class ConfigurableProviderRequest { + private String code; + private String configurableLoginId; + + public String getCode() { + return code; + } + public void setCode(String code) { + this.code = code; + } + + public String getConfigurableLoginId() { + return configurableLoginId; + } + public void setConfigurableLoginId(String configurableLoginId) { + this.configurableLoginId = configurableLoginId; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/configurableProvider/helpers/ConfigurableProviderResponseToken.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/configurableProvider/helpers/ConfigurableProviderResponseToken.java new file mode 100644 index 000000000..743dc376b --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/configurableProvider/helpers/ConfigurableProviderResponseToken.java @@ -0,0 +1,20 @@ +package eu.eudat.logic.security.validators.configurableProvider.helpers; + +public class ConfigurableProviderResponseToken { + private String accessToken; + private Integer expiresIn; + + public String getAccessToken() { + return accessToken; + } + public void setAccessToken(String accessToken) { + this.accessToken = accessToken; + } + + public Integer getExpiresIn() { + return expiresIn; + } + public void setExpiresIn(Integer expiresIn) { + this.expiresIn = expiresIn; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/facebook/FacebookTokenValidator.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/facebook/FacebookTokenValidator.java index 92715c5fb..ed87b867f 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/facebook/FacebookTokenValidator.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/facebook/FacebookTokenValidator.java @@ -3,7 +3,6 @@ package eu.eudat.logic.security.validators.facebook; import eu.eudat.exceptions.security.UnauthorisedException; import eu.eudat.logic.security.validators.TokenValidator; import eu.eudat.logic.security.validators.TokenValidatorFactoryImpl; -import eu.eudat.logic.services.ApiContext; import eu.eudat.logic.services.operations.authentication.AuthenticationService; import eu.eudat.models.data.login.LoginInfo; import eu.eudat.models.data.loginprovider.LoginProviderUser; @@ -22,17 +21,13 @@ import java.util.Map; @Component("facebookTokenValidator") public class FacebookTokenValidator implements TokenValidator { - private Environment environment; - private ApiContext apiContext; private AuthenticationService nonVerifiedUserAuthenticationService; private FacebookServiceProvider facebookServiceProvider; @Autowired - public FacebookTokenValidator(ApiContext apiContext, Environment environment, AuthenticationService nonVerifiedUserAuthenticationService) { - this.environment = environment; - this.apiContext = apiContext; + public FacebookTokenValidator(Environment environment, AuthenticationService nonVerifiedUserAuthenticationService) { this.nonVerifiedUserAuthenticationService = nonVerifiedUserAuthenticationService; - this.facebookServiceProvider = new FacebookServiceProvider(this.environment.getProperty("facebook.login.clientId"), this.environment.getProperty("facebook.login.clientSecret"), this.environment.getProperty("facebook.login.namespace")); + this.facebookServiceProvider = new FacebookServiceProvider(environment.getProperty("facebook.login.clientId"), environment.getProperty("facebook.login.clientSecret"), environment.getProperty("facebook.login.namespace")); } @Override @@ -56,8 +51,7 @@ public class FacebookTokenValidator implements TokenValidator { private User getFacebookUser(String accessToken) { String[] fields = {"id", "email", "first_name", "last_name", "name", "verified", "picture"}; - User profile = this.facebookServiceProvider.getApi(accessToken).fetchObject("me", User.class, fields); - return profile; + return this.facebookServiceProvider.getApi(accessToken).fetchObject("me", User.class, fields); } private Date addADay(Date date) { diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/google/GoogleTokenValidator.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/google/GoogleTokenValidator.java index 03e5166cb..add180486 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/google/GoogleTokenValidator.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/google/GoogleTokenValidator.java @@ -8,7 +8,6 @@ import com.google.api.client.http.javanet.NetHttpTransport; import com.google.api.client.json.jackson2.JacksonFactory; import eu.eudat.logic.security.validators.TokenValidator; import eu.eudat.logic.security.validators.TokenValidatorFactoryImpl; -import eu.eudat.logic.services.ApiContext; import eu.eudat.logic.services.operations.authentication.AuthenticationService; import eu.eudat.models.data.login.LoginInfo; import eu.eudat.models.data.loginprovider.LoginProviderUser; @@ -24,24 +23,19 @@ import java.util.Collections; public class GoogleTokenValidator implements TokenValidator { private static final HttpTransport transport = new NetHttpTransport(); - private ApiContext apiContext; private AuthenticationService nonVerifiedUserAuthenticationService; private GoogleIdTokenVerifier verifier; - private Environment environment; @Autowired - public GoogleTokenValidator(ApiContext apiContext, Environment environment, AuthenticationService nonVerifiedUserAuthenticationService) { - this.apiContext = apiContext; - this.environment = environment; + public GoogleTokenValidator(Environment environment, AuthenticationService nonVerifiedUserAuthenticationService) { this.nonVerifiedUserAuthenticationService = nonVerifiedUserAuthenticationService; verifier = new GoogleIdTokenVerifier.Builder(transport, JacksonFactory.getDefaultInstance()) - .setAudience(Collections.singletonList(this.environment.getProperty("google.login.clientId"))) + .setAudience(Collections.singletonList(environment.getProperty("google.login.clientId"))) .build(); } private GoogleIdToken verifyUserAndGetUser(String idTokenString) throws IOException, GeneralSecurityException { - GoogleIdToken idToken = verifier.verify(idTokenString); - return idToken; + return verifier.verify(idTokenString); } @Override @@ -58,5 +52,4 @@ public class GoogleTokenValidator implements TokenValidator { user.setIsVerified(payload.getEmailVerified()); return this.nonVerifiedUserAuthenticationService.Touch(user); } - } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/linkedin/LinkedInTokenValidator.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/linkedin/LinkedInTokenValidator.java index f89c82317..c49c628df 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/linkedin/LinkedInTokenValidator.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/linkedin/LinkedInTokenValidator.java @@ -1,19 +1,17 @@ package eu.eudat.logic.security.validators.linkedin; import eu.eudat.exceptions.security.UnauthorisedException; +import eu.eudat.logic.security.customproviders.LinkedIn.LinkedInCustomProvider; +import eu.eudat.logic.security.customproviders.LinkedIn.LinkedInUser; import eu.eudat.logic.security.validators.TokenValidator; -import eu.eudat.logic.security.validators.TokenValidatorFactoryImpl; -import eu.eudat.logic.services.ApiContext; +import eu.eudat.logic.security.validators.linkedin.helpers.LinkedInRequest; +import eu.eudat.logic.security.validators.linkedin.helpers.LinkedInResponseToken; import eu.eudat.logic.services.operations.authentication.AuthenticationService; import eu.eudat.models.data.login.LoginInfo; import eu.eudat.models.data.loginprovider.LoginProviderUser; import eu.eudat.models.data.security.Principal; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.env.Environment; -import org.springframework.social.linkedin.api.LinkedIn; -import org.springframework.social.linkedin.api.LinkedInProfile; -import org.springframework.social.linkedin.connect.LinkedInServiceProvider; -import org.springframework.social.oauth2.AccessGrant; import org.springframework.stereotype.Component; @@ -21,21 +19,19 @@ import org.springframework.stereotype.Component; public class LinkedInTokenValidator implements TokenValidator { private Environment environment; - private ApiContext apiContext; private AuthenticationService nonVerifiedUserAuthenticationService; - private LinkedInServiceProvider linkedInServiceProvider; + private LinkedInCustomProvider linkedInCustomProvider; @Autowired - public LinkedInTokenValidator(ApiContext apiContext, Environment environment, AuthenticationService nonVerifiedUserAuthenticationService) { + public LinkedInTokenValidator(Environment environment, AuthenticationService nonVerifiedUserAuthenticationService, LinkedInCustomProvider linkedInCustomProvider) { this.environment = environment; - this.apiContext = apiContext; this.nonVerifiedUserAuthenticationService = nonVerifiedUserAuthenticationService; - this.linkedInServiceProvider = new LinkedInServiceProvider(this.environment.getProperty("linkedin.login.clientId"), this.environment.getProperty("linkedin.login.clientSecret")); + this.linkedInCustomProvider = linkedInCustomProvider; } @Override public Principal validateToken(LoginInfo credentials) { - AccessGrant accessGrant = this.linkedInServiceProvider.getOAuthOperations().exchangeForAccess(credentials.getTicket(), this.environment.getProperty("linkedin.login.redirect_uri"), null); + /*AccessGrant accessGrant = this.linkedInServiceProvider.getOAuthOperations().exchangeForAccess(credentials.getTicket(), this.environment.getProperty("linkedin.login.redirect_uri"), null); LinkedIn linkedInService = this.linkedInServiceProvider.getApi(accessGrant.getAccessToken()); LinkedInProfile linkedInProfile = linkedInService.profileOperations().getUserProfile(); LoginProviderUser user = new LoginProviderUser(); @@ -48,7 +44,24 @@ public class LinkedInTokenValidator implements TokenValidator { user.setAvatarUrl(linkedInProfile.getProfilePictureUrl()); user.setName(linkedInProfile.getFirstName() + " " + linkedInProfile.getLastName()); user.setProvider(TokenValidatorFactoryImpl.LoginProvider.LINKEDIN); - user.setSecret(accessGrant.getAccessToken()); + user.setSecret(accessGrant.getAccessToken());*/ + + LinkedInUser linkedInUser = this.linkedInCustomProvider.getUser(credentials.getTicket()); + if (linkedInUser.getEmail() == null) + throw new UnauthorisedException("Cannot login user.LinkedIn account did not provide email"); + LoginProviderUser user = new LoginProviderUser(); + user.setId(linkedInUser.getId()); + user.setName(linkedInUser.getName()); + user.setEmail(linkedInUser.getEmail()); + user.setProvider(credentials.getProvider()); + user.setSecret(credentials.getTicket()); + return this.nonVerifiedUserAuthenticationService.Touch(user); } + + public LinkedInResponseToken getAccessToken(LinkedInRequest linkedInRequest) { + return this.linkedInCustomProvider.getAccessToken( + linkedInRequest.getCode(), this.environment.getProperty("linkedin.login.redirect_uri"), + this.environment.getProperty("linkedin.login.clientId"), this.environment.getProperty("linkedin.login.clientSecret")); + } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/linkedin/helpers/LinkedInRequest.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/linkedin/helpers/LinkedInRequest.java new file mode 100644 index 000000000..a03bb9fe1 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/linkedin/helpers/LinkedInRequest.java @@ -0,0 +1,12 @@ +package eu.eudat.logic.security.validators.linkedin.helpers; + +public class LinkedInRequest { + private String code; + + public String getCode() { + return code; + } + public void setCode(String code) { + this.code = code; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/linkedin/helpers/LinkedInResponseToken.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/linkedin/helpers/LinkedInResponseToken.java new file mode 100644 index 000000000..f39776e48 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/linkedin/helpers/LinkedInResponseToken.java @@ -0,0 +1,21 @@ +package eu.eudat.logic.security.validators.linkedin.helpers; + +public class LinkedInResponseToken { + + private String accessToken; + private Integer expiresIn; + + public String getAccessToken() { + return accessToken; + } + public void setAccessToken(String accessToken) { + this.accessToken = accessToken; + } + + public Integer getExpiresIn() { + return expiresIn; + } + public void setExpiresIn(Integer expiresIn) { + this.expiresIn = expiresIn; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/openaire/OpenAIRETokenValidator.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/openaire/OpenAIRETokenValidator.java new file mode 100644 index 000000000..74981af98 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/openaire/OpenAIRETokenValidator.java @@ -0,0 +1,52 @@ +package eu.eudat.logic.security.validators.openaire; + +import eu.eudat.exceptions.security.NonValidTokenException; +import eu.eudat.exceptions.security.NullEmailException; +import eu.eudat.logic.security.customproviders.OpenAIRE.OpenAIRECustomProvider; +import eu.eudat.logic.security.customproviders.OpenAIRE.OpenAIREUser; +import eu.eudat.logic.security.validators.TokenValidator; +import eu.eudat.logic.security.validators.openaire.helpers.OpenAIRERequest; +import eu.eudat.logic.security.validators.openaire.helpers.OpenAIREResponseToken; +import eu.eudat.logic.services.operations.authentication.AuthenticationService; +import eu.eudat.models.data.login.LoginInfo; +import eu.eudat.models.data.loginprovider.LoginProviderUser; +import eu.eudat.models.data.security.Principal; +import org.springframework.core.env.Environment; +import org.springframework.stereotype.Component; + +import java.io.IOException; +import java.security.GeneralSecurityException; + +@Component("openAIRETokenValidator") +public class OpenAIRETokenValidator implements TokenValidator { + + private Environment environment; + private AuthenticationService nonVerifiedUserAuthenticationService; + private OpenAIRECustomProvider openAIRECustomProvider; + + public OpenAIRETokenValidator(Environment environment, AuthenticationService nonVerifiedUserAuthenticationService, OpenAIRECustomProvider openAIRECustomProvider) { + this.environment = environment; + this.nonVerifiedUserAuthenticationService = nonVerifiedUserAuthenticationService; + this.openAIRECustomProvider = openAIRECustomProvider; + } + + public OpenAIREResponseToken getAccessToken(OpenAIRERequest openAIRERequest) { + return this.openAIRECustomProvider.getAccessToken( + openAIRERequest.getCode(), this.environment.getProperty("openaire.login.redirect_uri"), + this.environment.getProperty("openaire.login.client_id"), this.environment.getProperty("openaire.login.client_secret") + ); + } + + @Override + public Principal validateToken(LoginInfo credentials) throws NonValidTokenException, IOException, GeneralSecurityException, NullEmailException { + OpenAIREUser openAIREUser = this.openAIRECustomProvider.getUser(credentials.getTicket()); + LoginProviderUser user = new LoginProviderUser(); + user.setId(openAIREUser.getId()); + user.setEmail(openAIREUser.getEmail()); + user.setName(openAIREUser.getName()); + user.setProvider(credentials.getProvider()); + user.setSecret(credentials.getTicket()); + + return this.nonVerifiedUserAuthenticationService.Touch(user); + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/openaire/helpers/OpenAIRERequest.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/openaire/helpers/OpenAIRERequest.java new file mode 100644 index 000000000..928ef2b55 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/openaire/helpers/OpenAIRERequest.java @@ -0,0 +1,12 @@ +package eu.eudat.logic.security.validators.openaire.helpers; + +public class OpenAIRERequest { + private String code; + + public String getCode() { + return code; + } + public void setCode(String code) { + this.code = code; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/openaire/helpers/OpenAIREResponseToken.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/openaire/helpers/OpenAIREResponseToken.java new file mode 100644 index 000000000..372a3482e --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/openaire/helpers/OpenAIREResponseToken.java @@ -0,0 +1,20 @@ +package eu.eudat.logic.security.validators.openaire.helpers; + +public class OpenAIREResponseToken { + private String accessToken; + private Integer expiresIn; + + public String getAccessToken() { + return accessToken; + } + public void setAccessToken(String accessToken) { + this.accessToken = accessToken; + } + + public Integer getExpiresIn() { + return expiresIn; + } + public void setExpiresIn(Integer expiresIn) { + this.expiresIn = expiresIn; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/orcid/ORCIDTokenValidator.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/orcid/ORCIDTokenValidator.java index 8d365a052..b87ac2cbd 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/orcid/ORCIDTokenValidator.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/orcid/ORCIDTokenValidator.java @@ -7,7 +7,6 @@ import eu.eudat.logic.security.customproviders.ORCID.ORCIDUser; import eu.eudat.logic.security.validators.TokenValidator; import eu.eudat.logic.security.validators.orcid.helpers.ORCIDRequest; import eu.eudat.logic.security.validators.orcid.helpers.ORCIDResponseToken; -import eu.eudat.logic.services.ApiContext; import eu.eudat.logic.services.operations.authentication.AuthenticationService; import eu.eudat.models.data.login.LoginInfo; import eu.eudat.models.data.loginprovider.LoginProviderUser; @@ -25,14 +24,12 @@ public class ORCIDTokenValidator implements TokenValidator { private ORCIDCustomProvider orcidCustomProvider; private Environment environment; private AuthenticationService nonVerifiedUserAuthenticationService; - private ApiContext apiContext; @Autowired - public ORCIDTokenValidator(Environment environment, AuthenticationService nonVerifiedUserAuthenticationService, ORCIDCustomProvider orcidCustomProvider, ApiContext apiContext) { + public ORCIDTokenValidator(Environment environment, AuthenticationService nonVerifiedUserAuthenticationService, ORCIDCustomProvider orcidCustomProvider) { this.environment = environment; this.nonVerifiedUserAuthenticationService = nonVerifiedUserAuthenticationService; this.orcidCustomProvider = orcidCustomProvider; - this.apiContext = apiContext; } @Override diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/twitter/TwitterTokenValidator.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/twitter/TwitterTokenValidator.java index edd24cae1..88aba641f 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/twitter/TwitterTokenValidator.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/twitter/TwitterTokenValidator.java @@ -5,7 +5,6 @@ import eu.eudat.exceptions.security.NullEmailException; import eu.eudat.exceptions.security.UnauthorisedException; import eu.eudat.logic.security.validators.TokenValidator; import eu.eudat.logic.security.validators.TokenValidatorFactoryImpl; -import eu.eudat.logic.services.ApiContext; import eu.eudat.logic.services.operations.authentication.AuthenticationService; import eu.eudat.models.data.login.LoginInfo; import eu.eudat.models.data.loginprovider.LoginProviderUser; @@ -28,14 +27,12 @@ import java.util.Map; public class TwitterTokenValidator implements TokenValidator { private Environment environment; - private ApiContext apiContext; private AuthenticationService nonVerifiedUserAuthenticationService; private TwitterServiceProvider twitterServiceProvider; @Autowired - public TwitterTokenValidator(ApiContext apiContext, Environment environment, AuthenticationService nonVerifiedUserAuthenticationService) { + public TwitterTokenValidator(Environment environment, AuthenticationService nonVerifiedUserAuthenticationService) { this.environment = environment; - this.apiContext = apiContext; this.nonVerifiedUserAuthenticationService = nonVerifiedUserAuthenticationService; this.twitterServiceProvider = new TwitterServiceProvider(this.environment.getProperty("twitter.login.clientId"), this.environment.getProperty("twitter.login.clientSecret")); } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/types/ParagraphStyle.java b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/types/ParagraphStyle.java index c908ca0b1..ba104013d 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/types/ParagraphStyle.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/types/ParagraphStyle.java @@ -4,7 +4,7 @@ package eu.eudat.logic.utilities.documents.types; * Created by ikalyvas on 2/26/2018. */ public enum ParagraphStyle { - TEXT(0), HEADER1(1), HEADER2(2), HEADER3(3), HEADER4(4), TITLE(5), FOOTER(6), COMMENT(7); + TEXT(0), HEADER1(1), HEADER2(2), HEADER3(3), HEADER4(4), TITLE(5), FOOTER(6), COMMENT(7), HEADER5(8), HEADER6(9); private Integer value; @@ -34,6 +34,10 @@ public enum ParagraphStyle { return FOOTER; case 7: return COMMENT; + case 8: + return HEADER5; + case 9: + return HEADER6; default: throw new RuntimeException("Unsupported ParagraphStyle Code"); } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/word/WordBuilder.java b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/word/WordBuilder.java index 657946e0a..f8733633a 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/word/WordBuilder.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/word/WordBuilder.java @@ -25,10 +25,8 @@ import java.math.BigInteger; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; -/** - * Created by ikalyvas on 2/26/2018. - */ public class WordBuilder { private Map> options = new HashMap<>(); @@ -46,7 +44,7 @@ public class WordBuilder { XWPFParagraph paragraph = mainDocumentPart.createParagraph(); XWPFRun run = paragraph.createRun(); if (item != null) - run.setText(" " + item); + run.setText(" " + item); run.setFontSize(11); return paragraph; }); @@ -65,8 +63,9 @@ public class WordBuilder { paragraph.setStyle("Heading1"); XWPFRun run = paragraph.createRun(); run.setText(item); - run.setBold(true); - run.setFontSize(12); +// run.setBold(true); +// run.setFontSize(12); +// run.setStyle("0"); return paragraph; }); this.options.put(ParagraphStyle.HEADER2, (mainDocumentPart, item) -> { @@ -74,8 +73,8 @@ public class WordBuilder { paragraph.setStyle("Heading2"); XWPFRun run = paragraph.createRun(); run.setText(" " + item); - run.setBold(true); - run.setFontSize(12); +// run.setBold(true); +// run.setFontSize(12); return paragraph; }); this.options.put(ParagraphStyle.HEADER3, (mainDocumentPart, item) -> { @@ -83,8 +82,29 @@ public class WordBuilder { paragraph.setStyle("Heading3"); XWPFRun run = paragraph.createRun(); run.setText(" " + item); - run.setBold(true); - run.setFontSize(11); +// run.setBold(true); +// run.setFontSize(11); + return paragraph; + }); + this.options.put(ParagraphStyle.HEADER4, (mainDocumentPart, item) -> { + XWPFParagraph paragraph = mainDocumentPart.createParagraph(); + paragraph.setStyle("Heading4"); + XWPFRun run = paragraph.createRun(); + run.setText(item); + return paragraph; + }); + this.options.put(ParagraphStyle.HEADER5, (mainDocumentPart, item) -> { + XWPFParagraph paragraph = mainDocumentPart.createParagraph(); + paragraph.setStyle("Heading5"); + XWPFRun run = paragraph.createRun(); + run.setText(" " + item); + return paragraph; + }); + this.options.put(ParagraphStyle.HEADER6, (mainDocumentPart, item) -> { + XWPFParagraph paragraph = mainDocumentPart.createParagraph(); + paragraph.setStyle("Heading6"); + XWPFRun run = paragraph.createRun(); + run.setText(" " + item); return paragraph; }); this.options.put(ParagraphStyle.FOOTER, (mainDocumentPart, item) -> { @@ -96,7 +116,7 @@ public class WordBuilder { this.options.put(ParagraphStyle.COMMENT, (mainDocumentPart, item) -> { XWPFParagraph paragraph = mainDocumentPart.createParagraph(); XWPFRun run = paragraph.createRun(); - run.setText(" " + item); + run.setText(item); run.setItalic(true); return paragraph; }); @@ -114,7 +134,7 @@ public class WordBuilder { public void createPages(List datasetProfilePages, XWPFDocument mainDocumentPart, Boolean createListing, VisibilityRuleService visibilityRuleService) { datasetProfilePages.forEach(item -> { - createSections(item.getSections(), mainDocumentPart, ParagraphStyle.HEADER1, 0, createListing, visibilityRuleService); + createSections(item.getSections(), mainDocumentPart, ParagraphStyle.HEADER4, 0, createListing, visibilityRuleService); }); } @@ -127,7 +147,7 @@ public class WordBuilder { CTDecimalNumber number = paragraph.getCTP().getPPr().getNumPr().addNewIlvl(); number.setVal(BigInteger.valueOf(indent)); } - createSections(section.getSections(), mainDocumentPart, ParagraphStyle.HEADER2, 1, createListing, visibilityRuleService); + createSections(section.getSections(), mainDocumentPart, ParagraphStyle.HEADER5, 1, createListing, visibilityRuleService); createCompositeFields(section.getCompositeFields(), mainDocumentPart, 2, createListing, visibilityRuleService); } }); @@ -138,12 +158,12 @@ public class WordBuilder { compositeFields.forEach(compositeField -> { if (visibilityRuleService.isElementVisible(compositeField.getId()) && hasVisibleFields(compositeField, visibilityRuleService)) { if (compositeField.getTitle() != null && !compositeField.getTitle().isEmpty() && !createListing) { - XWPFParagraph paragraph = addParagraphContent(compositeField.getNumbering() + " " + compositeField.getTitle(), mainDocumentPart, ParagraphStyle.HEADER3, numId); + XWPFParagraph paragraph = addParagraphContent(compositeField.getNumbering() + " " + compositeField.getTitle(), mainDocumentPart, ParagraphStyle.HEADER6, numId); CTDecimalNumber number = paragraph.getCTP().getPPr().getNumPr().addNewIlvl(); number.setVal(BigInteger.valueOf(indent)); } createFields(compositeField.getFields(), mainDocumentPart, 3, createListing, visibilityRuleService); - if (!compositeField.getMultiplicityItems().isEmpty()) { + if (compositeField.getMultiplicityItems() != null && !compositeField.getMultiplicityItems().isEmpty()) { for (FieldSet multiplicityFieldset : compositeField.getMultiplicityItems()) { createFields(multiplicityFieldset.getFields(), mainDocumentPart, 3, createListing, visibilityRuleService); } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/helpers/ListHelper.java b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/helpers/ListHelper.java new file mode 100644 index 000000000..8857e4481 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/helpers/ListHelper.java @@ -0,0 +1,17 @@ +package eu.eudat.logic.utilities.helpers; + +import org.springframework.stereotype.Component; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Function; +import java.util.function.Predicate; + +@Component +public class ListHelper { + + public Predicate distinctByKey(Function keyExtractor) { + Map seen = new ConcurrentHashMap<>(); + return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/admin/components/datasetprofile/Field.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/admin/components/datasetprofile/Field.java index 5e96bf6f6..7903a4ddc 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/admin/components/datasetprofile/Field.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/admin/components/datasetprofile/Field.java @@ -43,6 +43,7 @@ public class Field implements ViewStyleDefinition getValidations() { return this.validations.stream().map(item -> (int) item.getValue()).collect(Collectors.toList()); } - public void setValidations(List validations) { this.validations = ValidationType.fromIntegers(validations); } @@ -145,6 +141,7 @@ public class Field implements ViewStyleDefinition getFields() { return fields; } - public void setFields(List fields) { this.fields = fields; } @@ -30,7 +29,6 @@ public class FieldSet implements Comparable, ViewStyleDefinition viewStylefields = new ModelBuilder().toViewStyleDefinition(this.fields, eu.eudat.models.data.entities.xmlmodels.datasetprofiledefinition.Field.class); - item.setFields(viewStylefields); + List viewStyleFields = new ModelBuilder().toViewStyleDefinition(this.fields, eu.eudat.models.data.entities.xmlmodels.datasetprofiledefinition.Field.class); + item.setFields(viewStyleFields); item.setId(this.id); item.setDescription(this.description); item.setTitle(this.title); @@ -108,6 +98,7 @@ public class FieldSet implements Comparable, ViewStyleDefinition { root.setAttribute("url", this.url); root.setAttribute("optionsRoot", this.optionsRoot); - root.setAttribute("multiAutoComplete", this.multiAutoComplete.toString()); + if (this.multiAutoComplete != null) + root.setAttribute("multiAutoComplete", this.multiAutoComplete.toString()); Element element = doc.createElement("option"); element.setAttribute("label", this.autoCompleteOptions.getLabel()); element.setAttribute("value", autoCompleteOptions.getValue()); diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/datarepository/DataRepositoryModel.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/datarepository/DataRepositoryModel.java index 6a5984ed9..200bf2d78 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/datarepository/DataRepositoryModel.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/datarepository/DataRepositoryModel.java @@ -1,6 +1,8 @@ package eu.eudat.models.data.datarepository; +import com.fasterxml.jackson.annotation.JsonProperty; import eu.eudat.data.entities.DataRepository; +import eu.eudat.data.entities.UserInfo; import eu.eudat.models.DataModel; import java.util.Date; @@ -10,17 +12,20 @@ import java.util.UUID; * Created by ikalyvas on 9/3/2018. */ public class DataRepositoryModel implements DataModel { - public UUID id; - public String label; - public String abbreviation; - public String uri; - public Date created; - public Date modified; + private UUID id; + @JsonProperty("name") + private String label; + private String pid; + private String abbreviation; + private String uri; + private Date created; + private Date modified; + private String tag; // Api fetching the data + private String source; // Actual harvested source public UUID getId() { return id; } - public void setId(UUID id) { this.id = id; } @@ -28,15 +33,20 @@ public class DataRepositoryModel implements DataModel()); + entity.setRegistries(new HashSet<>()); for (Registry registry : this.registries) { entity.getRegistries().add(registry.toDataModel()); } } if (this.dataRepositories != null && !this.dataRepositories.isEmpty()) { - entity.setDatasetDataRepositories(new HashSet()); + entity.setDatasetDataRepositories(new HashSet<>()); for (DataRepository dataRepositoryModel : this.dataRepositories) { eu.eudat.data.entities.DataRepository dataRepository = dataRepositoryModel.toDataModel(); DatasetDataRepository datasetDataRepository = new DatasetDataRepository(); @@ -224,7 +224,7 @@ public class DatasetWizardModel implements DataModel()); + entity.setServices(new HashSet<>()); for (Service serviceModel : this.services) { eu.eudat.data.entities.Service service = serviceModel.toDataModel(); DatasetService datasetService = new DatasetService(); @@ -234,7 +234,7 @@ public class DatasetWizardModel implements DataModel()); + entity.setDatasetExternalDatasets(new HashSet<>()); for (ExternalDatasetListingModel externalDataset : this.externalDatasets) { ExternalDataset externalDatasetEntity = externalDataset.toDataModel(); DatasetExternalDataset datasetExternalDataset = new DatasetExternalDataset(); diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/DataManagementPlanEditorModel.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/DataManagementPlanEditorModel.java index 86ed120b7..8a9d283e9 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/DataManagementPlanEditorModel.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/DataManagementPlanEditorModel.java @@ -268,9 +268,9 @@ public class DataManagementPlanEditorModel implements DataModel(this.organisations.stream().map(item -> item.toDataModel()).collect(Collectors.toList()))); + dataManagementPlanEntity.setOrganisations(new HashSet<>(this.organisations.stream().map(Organisation::toDataModel).collect(Collectors.toList()))); if (this.researchers != null && !this.researchers.isEmpty()) - dataManagementPlanEntity.setResearchers(new HashSet<>(this.researchers.stream().map(item -> item.toDataModel()).collect(Collectors.toList()))); + dataManagementPlanEntity.setResearchers(new HashSet<>(this.researchers.stream().map(Researcher::toDataModel).collect(Collectors.toList()))); dataManagementPlanEntity.setVersion(this.version); dataManagementPlanEntity.setLabel(this.label); if (this.grant != null) { @@ -293,13 +293,13 @@ public class DataManagementPlanEditorModel implements DataModel { private String id; private int ordinal; + private String rdaCommonStandard; private String numbering; private ViewStyle viewStyle; private DefaultValue defaultValue; @@ -28,7 +29,6 @@ public class Field implements DatabaseViewStyleDefinition, XmlSerializable getValidations() { return validations; } - public void setValidations(List validations) { this.validations = validations; } @@ -84,7 +85,6 @@ public class Field implements DatabaseViewStyleDefinition, XmlSerializable getFields() { return fields; } - public void setFields(List fields) { this.fields = fields; } @@ -35,7 +34,6 @@ public class FieldSet implements DatabaseViewStyleDefinition, XmlSerializable { +public class ExternalDatasetSourcesModel extends ExternalListingItem { @Override - public ExternalDatasetModel fromExternalItem(List> values) { + public ExternalDatasetSourcesModel fromExternalItem(List> values) { for (Map item : values) { ExternalSourcesItemModel model = new ExternalSourcesItemModel(); model.setId(item.get("pid")); model.setUri(item.get("uri")); model.setName(item.get("name")); + model.setSource(item.get("source")); this.add(model); } return this; diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/external/ExternalSourcesItemModel.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/external/ExternalSourcesItemModel.java index 521563627..cc35ff289 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/external/ExternalSourcesItemModel.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/external/ExternalSourcesItemModel.java @@ -3,6 +3,7 @@ package eu.eudat.models.data.external; public class ExternalSourcesItemModel { private String id; + private String pid; private String name; private String description; private String uri; @@ -14,15 +15,20 @@ public class ExternalSourcesItemModel { public String getId() { return id; } - public void setId(String id) { this.id = id; } + public String getPid() { + return pid; + } + public void setPid(String pid) { + this.pid = pid; + } + public String getName() { return name; } - public void setName(String name) { this.name = name; } @@ -30,7 +36,6 @@ public class ExternalSourcesItemModel { public String getDescription() { return description; } - public void setDescription(String description) { this.description = description; } @@ -38,7 +43,6 @@ public class ExternalSourcesItemModel { public String getUri() { return uri; } - public void setUri(String uri) { this.uri = uri; } @@ -46,7 +50,6 @@ public class ExternalSourcesItemModel { public String getRemoteId() { return remoteId; } - public void setRemoteId(String remoteId) { this.remoteId = remoteId; } @@ -54,7 +57,6 @@ public class ExternalSourcesItemModel { public String getAbbreviation() { return abbreviation; } - public void setAbbreviation(String abbreviation) { this.abbreviation = abbreviation; } @@ -62,7 +64,6 @@ public class ExternalSourcesItemModel { public String getTag() { return tag; } - public void setTag(String tag) { this.tag = tag; } @@ -70,7 +71,6 @@ public class ExternalSourcesItemModel { public String getSource() { return source; } - public void setSource(String source) { this.source = source; } diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/external/FundersExternalSourcesModel.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/external/FundersExternalSourcesModel.java index 794d5c2dd..5526a5552 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/external/FundersExternalSourcesModel.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/external/FundersExternalSourcesModel.java @@ -13,6 +13,7 @@ public class FundersExternalSourcesModel extends ExternalListingItem{ +public class ProjectsExternalSourcesModel extends ExternalListingItem { + private static final ObjectMapper mapper = new ObjectMapper(); + @Override public ProjectsExternalSourcesModel fromExternalItem(List> values) { for (Map item : values) { ExternalSourcesItemModel model = new ExternalSourcesItemModel(); - model.setRemoteId(item.get("pid")); - model.setUri(item.get("uri")); - model.setName(item.get("name")); - model.setDescription(item.get("description")); - model.setTag(item.get("tag")); - this.add(model); + try { + JsonNode node = mapper.readTree(mapper.writeValueAsBytes(item)); + JsonNode name = node.get("name"); + if (name != null && !name.isNull() && name.isObject()) { + model.setName(node.get("name").get("$").asText()); + } else { + model.setName(item.get("name")); + } + + JsonNode pid = node.get("pid"); + if (pid != null && !pid.isNull() && pid.isObject()) { + model.setRemoteId(node.get("pid").get("$").asText()); + } else { + model.setRemoteId(item.get("pid")); + } + + JsonNode uri = node.get("uri"); + if (uri != null && !uri.isNull() && uri.isObject()) { + model.setUri(node.get("uri").get("$").asText()); + } else { + model.setUri(item.get("uri")); + } + + JsonNode description = node.get("description"); + if (description != null && !description.isNull() && description.isObject()) { + model.setDescription(node.get("description").get("$").asText()); + } else { + model.setDescription(item.get("description")); + } + + JsonNode tag = node.get("tag"); + if (tag != null && !tag.isNull() && tag.isObject()) { + model.setTag(node.get("tag").get("$").asText()); + } else { + model.setTag(item.get("tag")); + } + + this.add(model); + + } catch (IOException e) { + e.printStackTrace(); + } } return this; } diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/externaldataset/ExternalDatasetListingModel.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/externaldataset/ExternalDatasetListingModel.java index 5b5472ced..2ffc2c525 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/externaldataset/ExternalDatasetListingModel.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/externaldataset/ExternalDatasetListingModel.java @@ -10,34 +10,35 @@ import java.util.UUID; public class ExternalDatasetListingModel implements DataModel { private UUID id; - private String label; + private String name; private String abbreviation; private String reference; private Date created; private Date modified; private String info; private ExternalDatasetType type; + private String pid; + private String uri; + private String tag; // Api fetching the data + private String source; // Actual harvested source public UUID getId() { return id; } - public void setId(UUID id) { this.id = id; } - public String getLabel() { - return label; + public String getName() { + return name; } - - public void setLabel(String label) { - this.label = label; + public void setName(String name) { + this.name = name; } public String getAbbreviation() { return abbreviation; } - public void setAbbreviation(String abbreviation) { this.abbreviation = abbreviation; } @@ -45,7 +46,6 @@ public class ExternalDatasetListingModel implements DataModel { public UUID id; public String label; public String abbreviation; public Date created; public Date modified; + private String source; public UUID getId() { return id; } - public void setId(UUID id) { this.id = id; } @@ -27,7 +25,6 @@ public class ExternalDatasetModel implements DataModel entity.setId(this.id); entity.setLabel(this.label); entity.setType(this.type); - entity.setReference(this.reference == null ? "dmp:" + this.label : this.reference); + entity.setReference(this.reference == null ? "dmp:" + this.label : this.source.toLowerCase() + ":" + this.reference); entity.setDefinition(this.definition); entity.setCreated(this.created == null ? new Date() : this.created); entity.setStatus(this.status != null ? this.getStatus() : eu.eudat.data.entities.Grant.Status.ACTIVE.getValue()); diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/grant/Grant.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/grant/Grant.java index 2cb1d6b0c..f8cde3ca3 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/grant/Grant.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/grant/Grant.java @@ -189,7 +189,7 @@ public class Grant implements DataModel { entity.setAbbreviation(this.abbreviation); entity.setLabel(this.label); entity.setType(this.type); - entity.setReference(this.reference == null ? "dmp:" + this.label : this.reference); + entity.setReference(this.reference == null ? "dmp:" + this.label : this.source.toLowerCase() + ":" + this.reference); entity.setUri(this.uri); entity.setDefinition(this.definition); entity.setStartdate(this.startDate); diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/listingmodels/DataManagementPlanListingModel.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/listingmodels/DataManagementPlanListingModel.java index 8cc675975..bfb8bf1cc 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/listingmodels/DataManagementPlanListingModel.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/listingmodels/DataManagementPlanListingModel.java @@ -183,6 +183,14 @@ public class DataManagementPlanListingModel implements DataModel new AssociatedProfile().fromData(item)).collect(Collectors.toList()); + return this; + } + public DataManagementPlanListingModel fromDataModelDatasets(DMP entity) { this.fromDataModel(entity); this.status = entity.getStatus(); diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/listingmodels/DatasetListingModel.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/listingmodels/DatasetListingModel.java index 6aac4b997..d1cd16647 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/listingmodels/DatasetListingModel.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/listingmodels/DatasetListingModel.java @@ -27,6 +27,7 @@ public class DatasetListingModel implements DataModel new DataRepository().fromDataModel(item.getDataRepository())).collect(Collectors.toList())); this.services = LabelBuilder.getLabel(entity.getServices().stream().map(item -> new Service().fromDataModel(item.getService())).collect(Collectors.toList())); this.finalizedAt = entity.getFinalizedAt(); + this.dmpPublishedAt = entity.getDmp().getPublishedAt(); return this; } diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/project/Project.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/project/Project.java index 098f27875..fe9da0885 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/project/Project.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/project/Project.java @@ -176,7 +176,7 @@ public class Project implements DataModel metadata; + + public DatasetIdRDAExportModel getDataset_id() { + return dataset_id; + } + public void setDataset_id(DatasetIdRDAExportModel dataset_id) { + this.dataset_id = dataset_id; + } + + public String getDescription() { + return description; + } + public void setDescription(String description) { + this.description = description; + } + + public Date getIssued() { + return issued; + } + public void setIssued(Date issued) { + this.issued = issued; + } + + public String getLanguage() { + return language; + } + public void setLanguage(String language) { + this.language = language; + } + + public String getTitle() { + return title; + } + public void setTitle(String title) { + this.title = title; + } + + public String getSensitive_data() { + return sensitive_data; + } + public void setSensitive_data(String sensitive_data) { + this.sensitive_data = sensitive_data; + } + + public String getData_quality_assurance() { + return data_quality_assurance; + } + public void setData_quality_assurance(String data_quality_assurance) { + this.data_quality_assurance = data_quality_assurance; + } + + public List getMetadata() { + return metadata; + } + public void setMetadata(List metadata) { + this.metadata = metadata; + } + + + public DatasetRDAExportModel fromDataModel(Dataset dataset) { + // Parsing dataset template definition to create a map of which question of the template corresponds to the RDA common standard. Map: TemplateId -> rdaProperty + List rdaPropertiesThatExistOnDatasetTemplate = xmlNodeListFromExpression(dataset.getProfile().getDefinition(), "//rdaCommonStandard/text()"); + List rdaProperties = new LinkedList<>(); + for (String item : rdaPropertiesThatExistOnDatasetTemplate) { + item = item.replace("dataset.", ""); + rdaProperties.add(item); + } + List datasetTemplateIdsWithRdaProperties = xmlNodeListFromExpression(dataset.getProfile().getDefinition(), "//rdaCommonStandard/text()/ancestor::field/@id"); + Map templateIdsToRDAProperties = combineListsIntoOrderedMap(datasetTemplateIdsWithRdaProperties, rdaProperties); + + // Parsing dataset answers from json to map. Map: TemplateId -> datasetValue + JSONObject jObject = new JSONObject(dataset.getProperties()); + Map templateIdsToValues = jObject.toMap(); + + // Map: rdaProperty -> datasetValue + MultiValuedMap rdaToValueMap = new ArrayListValuedHashMap<>(); + for (String templateId : templateIdsToRDAProperties.keySet()) { + if (templateIdsToValues.containsKey(templateId)) { + rdaToValueMap.put(templateIdsToRDAProperties.get(templateId), templateIdsToValues.get(templateId).toString()); + } + } + + // Creates and fills a map to include metadata keys and values. + MultiValuedMap metadataJsonMap = new ArrayListValuedHashMap<>(); + for (String key : rdaToValueMap.keySet()) { + if (key.startsWith("metadata.")) { + metadataJsonMap.putAll(key.replace("metadata.", ""), rdaToValueMap.get(key)); + } + } + // Removes metadata keys from rdaToValueMap. + for (String metadataKey : metadataJsonMap.keySet()) rdaToValueMap.remove(metadataKey); + + DatasetRDAExportModel datasetRDAExportModel = mapper.convertValue(rdaToValueMap, DatasetRDAExportModel.class); + datasetRDAExportModel.setTitle(dataset.getLabel()); + datasetRDAExportModel.setIssued(dataset.getCreated()); + datasetRDAExportModel.setLanguage("en"); // mock data; + datasetRDAExportModel.setDataset_id(new DatasetIdRDAExportModel(dataset.getId().toString(), "argos_internal")); + + List datasetMetadataRDAExportModels = new LinkedList<>(); + for (String key : metadataJsonMap.keySet()) { + for (String value : metadataJsonMap.get(key)) { + datasetMetadataRDAExportModels.add(new DatasetMetadataRDAExportModel().fromDataModel(key,value)); + } + } + datasetRDAExportModel.setMetadata(datasetMetadataRDAExportModels); + + return datasetRDAExportModel; + } + + private List xmlNodeListFromExpression(String xml, String expression) { + List valuesList = new LinkedList<>(); + Document document = XmlBuilder.fromXml(xml); + XPathFactory xpathFactory = XPathFactory.newInstance(); + XPath xpath = xpathFactory.newXPath(); + try { + XPathExpression expr = xpath.compile(expression); + NodeList nodeList = (NodeList) expr.evaluate(document, XPathConstants.NODESET); + for (int i = 0; i < nodeList.getLength(); i++) { + Node node = nodeList.item(i); + valuesList.add(node.getNodeValue()); + } + } catch (XPathExpressionException e) { + e.printStackTrace(); + } + + return valuesList; + } + + private Map combineListsIntoOrderedMap (List keys, List values) { + if (keys.size() != values.size()) + throw new IllegalArgumentException ("Cannot combine lists with dissimilar sizes"); + Map map = new LinkedHashMap<>(); + for (int i=0; i x.getRole().equals(UserDMP.UserDMPRoles.OWNER.getValue())).findFirst().get().getUser()); + // Mock up data on "language" and "ethical_issues" for now. this.language = "en"; - this.ethical_issues_exist = "no"; + this.ethical_issues_exist = "unknown"; + + this.project = new ProjectRDAExportModel().fromDataModel(entity.getGrant()); return this; } diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/rda/FunderIdRDAExportModel.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/rda/FunderIdRDAExportModel.java new file mode 100644 index 000000000..d58abeb5f --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/rda/FunderIdRDAExportModel.java @@ -0,0 +1,25 @@ +package eu.eudat.models.data.rda; + +public class FunderIdRDAExportModel { + private String funder_id; + private String funder_id_type; + + public String getFunder_id() { + return funder_id; + } + public void setFunder_id(String funder_id) { + this.funder_id = funder_id; + } + + public String getFunder_id_type() { + return funder_id_type; + } + public void setFunder_id_type(String funder_id_type) { + this.funder_id_type = funder_id_type; + } + + FunderIdRDAExportModel(String funder_id, String funder_id_type) { + this.funder_id = funder_id; + this.funder_id_type = funder_id_type; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/rda/FundingRDAExportModel.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/rda/FundingRDAExportModel.java new file mode 100644 index 000000000..0739b7766 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/rda/FundingRDAExportModel.java @@ -0,0 +1,42 @@ +package eu.eudat.models.data.rda; + +import eu.eudat.data.entities.Funder; +import eu.eudat.data.entities.Grant; + +public class FundingRDAExportModel { + private FunderIdRDAExportModel funder_id; + private GrantIdRDAExportModel grant_id; + private String funding_status; + + public FunderIdRDAExportModel getFunder_id() { + return funder_id; + } + public void setFunder_id(FunderIdRDAExportModel funder_id) { + this.funder_id = funder_id; + } + + public GrantIdRDAExportModel getGrant_id() { + return grant_id; + } + public void setGrant_id(GrantIdRDAExportModel grant_id) { + this.grant_id = grant_id; + } + + public String getFunding_status() { + return funding_status; + } + public void setFunding_status(String funding_status) { + this.funding_status = funding_status; + } + + public FundingRDAExportModel fromDataModel(Funder funder, Grant grant) { + this.funding_status = "planned"; // mock data + if (funder != null) { + this.funder_id = new FunderIdRDAExportModel(funder.getReference(), "argos_internal"); + } + if (grant != null) { + this.grant_id = new GrantIdRDAExportModel(grant.getReference(), "argos_internal"); + } + return this; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/rda/GrantIdRDAExportModel.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/rda/GrantIdRDAExportModel.java new file mode 100644 index 000000000..8bcac2735 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/rda/GrantIdRDAExportModel.java @@ -0,0 +1,25 @@ +package eu.eudat.models.data.rda; + +public class GrantIdRDAExportModel { + private String grant_id; + private String grant_id_type; + + public String getGrant_id() { + return grant_id; + } + public void setGrant_id(String grant_id) { + this.grant_id = grant_id; + } + + public String getGrant_id_type() { + return grant_id_type; + } + public void setGrant_id_type(String grant_id_type) { + this.grant_id_type = grant_id_type; + } + + GrantIdRDAExportModel(String grant_id, String grant_id_type) { + this.grant_id = grant_id; + this.grant_id_type = grant_id_type; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/rda/ProjectRDAExportModel.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/rda/ProjectRDAExportModel.java new file mode 100644 index 000000000..2d5b1912a --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/rda/ProjectRDAExportModel.java @@ -0,0 +1,54 @@ +package eu.eudat.models.data.rda; + +import eu.eudat.data.entities.Grant; + +import java.util.Date; + +public class ProjectRDAExportModel { + private String title; + private String description; + private Date project_start; + private Date project_end; + private FundingRDAExportModel funding; + + 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 Date getProject_start() { + return project_start; + } + public void setProject_start(Date project_start) { + this.project_start = project_start; + } + + public Date getProject_end() { + return project_end; + } + public void setProject_end(Date project_end) { + this.project_end = project_end; + } + + public FundingRDAExportModel getFunding() { + return funding; + } + public void setFunding(FundingRDAExportModel funding) { + this.funding = funding; + } + + + public ProjectRDAExportModel fromDataModel(Grant grant) { + this.funding = new FundingRDAExportModel().fromDataModel(grant.getFunder(), grant); + return this; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/rda/RDAExportModel.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/rda/RDAExportModel.java new file mode 100644 index 000000000..b4720d350 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/rda/RDAExportModel.java @@ -0,0 +1,36 @@ +package eu.eudat.models.data.rda; + +import eu.eudat.data.entities.DMP; +import eu.eudat.data.entities.Dataset; + +import java.util.LinkedList; +import java.util.List; + +public class RDAExportModel { + private DmpRDAExportModel dmp; + private List datasets; + + public DmpRDAExportModel getDmp() { + return dmp; + } + public void setDmp(DmpRDAExportModel dmp) { + this.dmp = dmp; + } + + public List getDatasets() { + return datasets; + } + public void setDatasets(List datasets) { + this.datasets = datasets; + } + + public RDAExportModel fromDataModel(DMP dmp) { + this.dmp = new DmpRDAExportModel().fromDataModel(dmp); + this.datasets = new LinkedList<>(); + for (Dataset dataset : dmp.getDataset()) { + if (dataset.getStatus() != Dataset.Status.DELETED.getValue() && dataset.getStatus() != Dataset.Status.CANCELED.getValue()) + this.datasets.add(new DatasetRDAExportModel().fromDataModel(dataset)); + } + return this; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/registries/RegistryModel.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/registries/RegistryModel.java index ec33afb13..89906eb03 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/registries/RegistryModel.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/registries/RegistryModel.java @@ -1,34 +1,43 @@ package eu.eudat.models.data.registries; +import com.fasterxml.jackson.annotation.JsonProperty; import eu.eudat.data.entities.Registry; +import eu.eudat.data.entities.UserInfo; import eu.eudat.models.DataModel; import java.util.Date; +import java.util.Map; import java.util.UUID; -/** - * Created by ikalyvas on 9/3/2018. - */ public class RegistryModel implements DataModel { - public UUID id; - public String label; - public String abbreviation; - public String uri; - public Date created; - public Date modified; + private UUID id; + private String name; + private String label; + private String pid; + private String abbreviation; + private String uri; + private Date created; + private Date modified; + private String tag; // Api fetching the data + private String source; // Actual harvested source public UUID getId() { return id; } - public void setId(UUID id) { this.id = id; } + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + public String getLabel() { return label; } - public void setLabel(String label) { this.label = label; } @@ -36,7 +45,6 @@ public class RegistryModel implements DataModel { public String getAbbreviation() { return abbreviation; } - public void setAbbreviation(String abbreviation) { this.abbreviation = abbreviation; } @@ -44,7 +52,6 @@ public class RegistryModel implements DataModel { public String getUri() { return uri; } - public void setUri(String uri) { this.uri = uri; } @@ -52,7 +59,6 @@ public class RegistryModel implements DataModel { public Date getCreated() { return created; } - public void setCreated(Date created) { this.created = created; } @@ -60,19 +66,46 @@ public class RegistryModel implements DataModel { public Date getModified() { return modified; } - public void setModified(Date modified) { this.modified = modified; } + public String getTag() { + return tag; + } + public void setTag(String tag) { + this.tag = tag; + } + + public String getPid() { + return pid; + } + public void setPid(String pid) { + this.pid = pid; + } + + public String getSource() { + return source; + } + public void setSource(String source) { + this.source = source; + } + @Override public RegistryModel fromDataModel(Registry entity) { this.id = entity.getId(); this.abbreviation = entity.getAbbreviation(); this.created = entity.getCreated(); this.label = entity.getLabel(); + this.name = entity.getLabel(); this.modified = entity.getModified(); this.uri = entity.getUri(); + String source1 = entity.getReference().substring(0, entity.getReference().indexOf(":")); + if (source1.equals("dmp")) { + this.source = "Internal"; + } else { + this.source = source1; + } return this; } @@ -82,11 +115,17 @@ public class RegistryModel implements DataModel { registry.setAbbreviation(this.abbreviation); registry.setCreated(this.created != null ? this.created : new Date()); registry.setId(this.id != null ? this.id : UUID.randomUUID()); - registry.setLabel(this.label); + registry.setLabel(this.label != null ? this.label : this.name); registry.setUri(this.uri); registry.setModified(new Date()); - registry.setReference("dmpdata/" + registry.getId()); + if (this.source == null) this.source = "dmp"; + if (this.source.equals(registry.getId().toString().substring(0, this.source.length()))) { + registry.setReference(registry.getId().toString()); + } else { + registry.setReference(this.source + ":" + registry.getId()); + } registry.setStatus((short)0); + registry.setCreationUser(new UserInfo()); return registry; } diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/services/ServiceModel.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/services/ServiceModel.java index d518ac8eb..19359d350 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/services/ServiceModel.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/services/ServiceModel.java @@ -1,26 +1,28 @@ package eu.eudat.models.data.services; import eu.eudat.data.entities.Service; +import eu.eudat.data.entities.UserInfo; import eu.eudat.models.DataModel; import java.util.Date; import java.util.UUID; -/** - * Created by ikalyvas on 9/3/2018. - */ public class ServiceModel implements DataModel { - public UUID id; - public String label; - public String abbreviation; - public String uri; - public Date created; - public Date modified; + private UUID id; + private String label; + private String name; + private String pid; + private String abbreviation; + private String uri; + private Date created; + private Date modified; + private String reference; + private String tag; + private String source; public UUID getId() { return id; } - public void setId(UUID id) { this.id = id; } @@ -28,15 +30,27 @@ public class ServiceModel implements DataModel { public String getLabel() { return label; } - public void setLabel(String label) { this.label = label; } + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + + public String getPid() { + return pid; + } + public void setPid(String pid) { + this.pid = pid; + } + public String getAbbreviation() { return abbreviation; } - public void setAbbreviation(String abbreviation) { this.abbreviation = abbreviation; } @@ -44,7 +58,6 @@ public class ServiceModel implements DataModel { public String getUri() { return uri; } - public void setUri(String uri) { this.uri = uri; } @@ -52,7 +65,6 @@ public class ServiceModel implements DataModel { public Date getCreated() { return created; } - public void setCreated(Date created) { this.created = created; } @@ -60,19 +72,46 @@ public class ServiceModel implements DataModel { public Date getModified() { return modified; } - public void setModified(Date modified) { this.modified = modified; } + public String getReference() { + return reference; + } + public void setReference(String reference) { + this.reference = reference; + } + + public String getTag() { + return tag; + } + public void setTag(String tag) { + this.tag = tag; + } + + public String getSource() { + return source; + } + public void setSource(String source) { + this.source = source; + } + @Override public ServiceModel fromDataModel(Service entity) { this.abbreviation = entity.getAbbreviation(); this.created = entity.getCreated(); this.id = entity.getId(); this.label = entity.getLabel(); + this.name = entity.getLabel(); this.modified = entity.getModified(); this.uri = entity.getUri(); + String source = entity.getReference().substring(0, entity.getReference().indexOf(":")); + if (source.equals("dmp")) { + this.source = "Internal"; + } else { + this.source = source; + } return this; } @@ -82,12 +121,19 @@ public class ServiceModel implements DataModel { service.setId(this.id != null ? this.id : UUID.randomUUID()); service.setAbbreviation(this.abbreviation); service.setCreated(this.created != null ? this.created : new Date()); - service.setLabel(this.label); + service.setLabel(this.label != null ? this.label : this.name); service.setModified(new Date()); service.setUri(this.uri); - service.setReference("innerdata/" + service.getId()); + if (this.source == null) this.source = "dmp"; + if (this.reference == null) this.reference = service.getId().toString(); + if (this.source.equals(this.reference.substring(0, this.source.length()))) { + service.setReference(this.reference); + } else { + service.setReference(this.source + ":" + this.reference); + } service.setModified(new Date()); - service.setStatus((short)0); + service.setStatus((short) 0); + service.setCreationUser(new UserInfo()); return service; } diff --git a/dmp-backend/web/src/main/resources/ExternalUrls.xml b/dmp-backend/web/src/main/resources/ExternalUrls.xml index 4235a1b5c..d987d3fcc 100644 --- a/dmp-backend/web/src/main/resources/ExternalUrls.xml +++ b/dmp-backend/web/src/main/resources/ExternalUrls.xml @@ -6,46 +6,50 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + cristin + + 1 + External + https://eestore.paas2.uninett.no/api/metadataschema/?search={like}&page={page}&size={pageSize} + 1 + application/vnd.api+json; charset=utf-8 + + $['data'][*]['attributes'] + + 'pid' + 'name' + 'uri' + 'description' + 'source' + + + $['meta']['pagination']['page','pages','count'] + + - FIRST - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + cristin + + 1 + External + https://eestore.paas2.uninett.no/api/tags/?search={like}&page={page}&size={pageSize} + 1 + application/vnd.api+json; charset=utf-8 + + $['data'][*]['attributes'] + + 'pid' + 'name' + 'uri' + 'description' + + + $['meta']['pagination']['page','pages','count'] + + - FIRST - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - internal - - 1 - GrantInternalMockUpData.json - Internal + cristin + + 2 + https://eestore.paas2.uninett.no/api/projectrepo/?search={like}&page={page}&size={pageSize} + 1 + application/vnd.api+json; charset=utf-8 $['data'][*]['attributes'] @@ -175,56 +145,73 @@ $['meta']['pagination']['page','pages','count'] - + + openAIRE + + 1 + https://services.openaire.eu/search/v2/api/resources?query=((oaftype%20exact%20project)%20and%20((projectcode_nt%20exact%20%22{like}%22)or({like}))){funderQuery}&page={page}&size={pageSize}&format=json + &fq=(funder%20exact%20%22{funderId}%22) + 0 + application/json; charset=utf-8 + + $['results'][*]['result']['metadata']['oaf:entity']['oaf:project'] + + 'originalId' + 'title' + 'count' + + + $['meta']['pagination']['page','pages','count'] + + - FIRST - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - internal - + - FIRST - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + openAire + + 1 + External + https://eestore.paas2.uninett.no/api/projectrepo/?search={like}&page={page}&size={pageSize} + 1 + application/vnd.api+json; charset=utf-8 + + $['data'][*]['attributes'] + + 'pid' + 'name' + 'uri' + 'description' + 'source' + + + $['meta']['pagination']['page','pages','count'] + + + - FIRST - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + cristin + + 1 + External + https://eestore.paas2.uninett.no/api/datarepo/?search={like}&page={page}&size={pageSize} + 1 + application/vnd.api+json; charset=utf-8 + + $['data'][*]['attributes'] + + 'pid' + 'name' + 'uri' + 'description' + 'source' + + + $['meta']['pagination']['page','pages','count'] + + + + + FIRST + + + + + + + cristin + + 1 + External + https://eestore.paas2.uninett.no/api/servicerepo/?search={like}&page={page}&size={pageSize} + 1 + application/vnd.api+json; charset=utf-8 + + $['data'][*]['attributes'] + + 'pid' + 'name' + 'uri' + 'description' + 'source' + + + $['meta']['pagination']['page','pages','count'] + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - internal 1 Internal - ServicesInternalMockUpData.json + mockData/ServicesInternalMockUpData.json $['data'][*]['attributes'] @@ -417,55 +531,42 @@ $['meta']['pagination']['page','pages','count'] - + --> - FIRST - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - internal - + cristin + 1 - Internal - ResearcherInternalMockUpData.json + External + https://eestore.paas2.uninett.no/api/personrepo/?search={like}&page={page}&size={pageSize} + 1 + application/vnd.api+json; charset=utf-8 + + $['data'][*]['attributes'] + + 'pid' + 'name' + 'uri' + 'description' + 'count' + + + $['meta']['pagination']['page','pages','count'] + + - FIRST - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - internal - + cristin + 1 - Internal - OrganisationInternalMockUpData.json + External + https://eestore.paas2.uninett.no/api/organizationrepo/?search={like}&page={page}&size={pageSize} + 1 + application/vnd.api+json; charset=utf-8 + + $['data'][*]['attributes'] + + 'pid' + 'name' + 'uri' + 'description' + 'count' + + + $['meta']['pagination']['page','pages','count'] + + - FIRST - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - internal - + cristin + 1 - Internal - DatasetsInternalMockUpData.json + External + https://eestore.paas2.uninett.no/api/datasetmdrepo/?search={like}&page={page}&size={pageSize} + 1 + application/vnd.api+json; charset=utf-8 $['data'][*]['attributes'] @@ -595,6 +683,42 @@ $['meta']['pagination']['page','pages','count'] + FIRST diff --git a/dmp-backend/web/src/main/resources/ExternalUrlsProduction.xml b/dmp-backend/web/src/main/resources/ExternalUrlsProduction.xml new file mode 100644 index 000000000..ecd11ddb9 --- /dev/null +++ b/dmp-backend/web/src/main/resources/ExternalUrlsProduction.xml @@ -0,0 +1,279 @@ + + + + + 1000 + + + + + internal + + 1 + Internal + RegistriesInternalMockUpData.json + + $['data'][*]['attributes'] + + 'pid' + + 'uri' + 'description' + + + $['meta']['pagination']['page','pages','count'] + + + + + FIRST + + + + + + internal + + 1 + Internal + TagsInternalMockUpData.json + + $['data'][*]['attributes'] + + 'pid' + 'name' + 'uri' + 'description' + + + $['meta']['pagination']['page','pages','count'] + + + FIRST + + + + + + openAIRE + + 1 + https://services.openaire.eu/search/v2/api/resources?query=((oaftype%20exact%20project)%20and%20((projectcode_nt%20exact%20%22{like}%22)or({like}))){funderQuery}&page={page}&size={pageSize}&format=json + &fq=(funder%20exact%20%22{funderId}%22) + 0 + application/json; charset=utf-8 + + $['results'][*]['result']['metadata']['oaf:entity']['oaf:project'] + + 'originalId' + 'title' + 'count' + + + $['meta']['pagination']['page','pages','count'] + + + FIRST + + + + + + FIRST + + + + + + servicesOpenAire + + 1 + External + https://services.openaire.eu/search/v2/api/publications?&refine=true&fields=relfunder&page={page}&size=0&format=json + 0 + application/json; charset=utf-8 + + $['refineResults']['relfunder'][*] + + 'name' + 'id' + 'count' + + + + + servicesOpenAire + + 1 + External + https://services.openaire.eu/search/v2/api/datasets?&refine=true&fields=relfunder&page=0&size={page}&format=json + 0 + application/json; charset=utf-8 + + $['refineResults']['relfunder'][*] + + 'name' + 'id' + 'count' + + + + + servicesOpenAire + + 1 + External + https://services.openaire.eu/search/v2/api/software?&refine=true&fields=relfunder&page={page}&size=0&format=json + 0 + application/json; charset=utf-8 + + $['refineResults']['relfunder'][*] + + 'name' + 'id' + 'count' + + + + + servicesOpenAire + + 1 + External + https://services.openaire.eu/search/v2/api/other?&refine=true&fields=relfunder&page={page}&size=0&format=json + 0 + application/json; charset=utf-8 + + $['refineResults']['relfunder'][*] + + 'name' + 'id' + 'count' + + + + + FIRST + + + + + + internal + + 1 + Internal + RepositoriesInternalMockUpData.json + + $['data'][*]['attributes'] + + 'pid' + 'name' + 'uri' + 'description' + + + $['meta']['pagination']['page','pages','count'] + + + FIRST + + + + + + + internal + + 1 + Internal + ServicesInternalMockUpData.json + + $['data'][*]['attributes'] + + 'pid' + + 'uri' + 'description' + + + $['meta']['pagination']['page','pages','count'] + + + FIRST + + + + + + + internal + + 1 + Internal + ResearcherInternalMockUpData.json + + $['data'][*]['attributes'] + + 'pid' + 'name' + 'uri' + 'description' + + + $['meta']['pagination']['page','pages','count'] + + + FIRST + + + + + + + internal + + 1 + Internal + OrganisationInternalMockUpData.json + + $['data'][*]['attributes'] + + 'pid' + 'name' + 'uri' + 'description' + + + $['meta']['pagination']['page','pages','count'] + + + FIRST + + + + + + internal + + 1 + Internal + DatasetsInternalMockUpData.json + + $['data'][*]['attributes'] + + 'pid' + 'name' + 'uri' + 'description' + + + $['meta']['pagination']['page','pages','count'] + + + FIRST + + + + + diff --git a/dmp-backend/web/src/main/resources/ExternalUrlsStaging.xml b/dmp-backend/web/src/main/resources/ExternalUrlsStaging.xml new file mode 100644 index 000000000..6f942f028 --- /dev/null +++ b/dmp-backend/web/src/main/resources/ExternalUrlsStaging.xml @@ -0,0 +1,298 @@ + + + + + 1000 + + + + + cristin + + 1 + External + https://eestore.paas2.uninett.no/api/metadataschema/?search={like}&page={page}&size={pageSize} + 1 + application/vnd.api+json; charset=utf-8 + + $['data'][*]['attributes'] + + 'pid' + 'name' + 'uri' + 'description' + 'source' + + + $['meta']['pagination']['page','pages','count'] + + + FIRST + + + + + + cristin + + 1 + External + https://eestore.paas2.uninett.no/api/tags/?search={like}&page={page}&size={pageSize} + 1 + application/vnd.api+json; charset=utf-8 + + $['data'][*]['attributes'] + + 'pid' + 'name' + 'uri' + 'description' + + + $['meta']['pagination']['page','pages','count'] + + + FIRST + + + + + + openAIRE + + 1 + https://services.openaire.eu/search/v2/api/resources?query=((oaftype%20exact%20project)%20and%20((projectcode_nt%20exact%20%22{like}%22)or({like}))){funderQuery}&page={page}&size={pageSize}&format=json + &fq=(funder%20exact%20%22{funderId}%22) + 0 + application/json; charset=utf-8 + + $['results'][*]['result']['metadata']['oaf:entity']['oaf:project'] + + 'originalId' + 'title' + 'count' + + + $['meta']['pagination']['page','pages','count'] + + + FIRST + + + + + + FIRST + + + + + + servicesOpenAire + + 1 + External + https://services.openaire.eu/search/v2/api/publications?&refine=true&fields=relfunder&page={page}&size=0&format=json + 0 + application/json; charset=utf-8 + + $['refineResults']['relfunder'][*] + + 'name' + 'id' + 'count' + + + + + servicesOpenAire + + 1 + External + https://services.openaire.eu/search/v2/api/datasets?&refine=true&fields=relfunder&page=0&size={page}&format=json + 0 + application/json; charset=utf-8 + + $['refineResults']['relfunder'][*] + + 'name' + 'id' + 'count' + + + + + servicesOpenAire + + 1 + External + https://services.openaire.eu/search/v2/api/software?&refine=true&fields=relfunder&page={page}&size=0&format=json + 0 + application/json; charset=utf-8 + + $['refineResults']['relfunder'][*] + + 'name' + 'id' + 'count' + + + + + servicesOpenAire + + 1 + External + https://services.openaire.eu/search/v2/api/other?&refine=true&fields=relfunder&page={page}&size=0&format=json + 0 + application/json; charset=utf-8 + + $['refineResults']['relfunder'][*] + + 'name' + 'id' + 'count' + + + + + FIRST + + + + + + cristin + + 1 + External + https://eestore.paas2.uninett.no/api/datarepo/?search={like}&page={page}&size={pageSize} + 1 + application/vnd.api+json; charset=utf-8 + + $['data'][*]['attributes'] + + 'pid' + 'name' + 'uri' + 'description' + 'source' + + + $['meta']['pagination']['page','pages','count'] + + + FIRST + + + + + + + cristin + + 1 + External + https://eestore.paas2.uninett.no/api/servicerepo/?search={like}&page={page}&size={pageSize} + 1 + application/vnd.api+json; charset=utf-8 + + $['data'][*]['attributes'] + + 'pid' + 'name' + 'uri' + 'description' + 'source' + + + $['meta']['pagination']['page','pages','count'] + + + FIRST + + + + + + + cristin + + 1 + External + https://eestore.paas2.uninett.no/api/personrepo/?search={like}&page={page}&size={pageSize} + 1 + application/vnd.api+json; charset=utf-8 + + $['data'][*]['attributes'] + + 'pid' + 'name' + 'uri' + 'description' + 'count' + + + $['meta']['pagination']['page','pages','count'] + + + FIRST + + + + + + + cristin + + 1 + External + https://eestore.paas2.uninett.no/api/organizationrepo/?search={like}&page={page}&size={pageSize} + 1 + application/vnd.api+json; charset=utf-8 + + $['data'][*]['attributes'] + + 'pid' + 'name' + 'uri' + 'description' + 'count' + + + $['meta']['pagination']['page','pages','count'] + + + FIRST + + + + + + cristin + + 1 + External + https://eestore.paas2.uninett.no/api/datasetmdrepo/?search={like}&page={page}&size={pageSize} + 1 + application/vnd.api+json; charset=utf-8 + + $['data'][*]['attributes'] + + 'pid' + 'name' + 'uri' + 'description' + 'source' + + + $['meta']['pagination']['page','pages','count'] + + + FIRST + + + + + + diff --git a/dmp-backend/web/src/main/resources/RDACommonStandards.txt b/dmp-backend/web/src/main/resources/RDACommonStandards.txt new file mode 100644 index 000000000..134b84e73 --- /dev/null +++ b/dmp-backend/web/src/main/resources/RDACommonStandards.txt @@ -0,0 +1,39 @@ +ethical_issues_exist +cost +cost.title +cost.description +cost.value +cost.currency_code +contact +contact.mail +contact.name +contact.contact_id +contact.contact_id.contact_id +contact.contact_id.contact_id_type +project +project.title +project.project_start +project.project_end +project.funding +project.funding.funder_id +project.funding.funder_id.funder_id +project.funding.funder_id.funder_id_type +project.funding.grant_id +project.funding.grant_id.grant_id +project.funding.grant_id.grant_id_type +dataset +dataset.title +dataset.type +dataset.personal_data +dataset.sensitive_data +dataset.dataset_id +dataset.dataset_id.dataset_id +dataset.dataset_id.dataset_id_type +dataset.metadata +dataset.metadata.language +dataset.metadata.metadata_id +dataset.metadata.metadata_id.metadata_id +dataset.metadata.metadata_id.metadata_id_type +dataset.security_and_privacy +dataset.security_and_privacy.title +dataset.security_and_privacy.description \ No newline at end of file diff --git a/dmp-backend/web/src/main/resources/application-devel.properties b/dmp-backend/web/src/main/resources/application-devel.properties index d6460eb55..00fb05c37 100644 --- a/dmp-backend/web/src/main/resources/application-devel.properties +++ b/dmp-backend/web/src/main/resources/application-devel.properties @@ -15,21 +15,22 @@ http-logger.server-address = http://localhost:31311 pdf.converter.url=http://localhost:88/ ####################CONFIGURATION FILES OVERRIDES CONFIGURATIONS########## -configuration.externalUrls=/tmp/ExternalUrls.xml -configuration.dynamicGrantUrl=/tmp/GrantConfiguration.xml -configuration.dynamicProjectUrl=/tmp/ProjectConfiguration.xml -configuration.dynamicFunderUrl=/tmp/FunderConfiguration.xml -configuration.h2020template=C:\\Users\\gkolokythas\\Documents\\openDmp\\dmp-backend\\web\\src\\main\\resources\\documents\\h2020.docx -configuration.resources.path = +configuration.externalUrls=/web/src/main/resources/ExternalUrls.xml +configuration.rda=/web/src/main/resources/RDACommonStandards.txt +configuration.h2020template=/web/src/main/resources/documents/h2020.docx +configuration.configurable_login_providers=/web/src/main/resources/configurableLoginProviders.json -####################MOCK FILES CONFIGURATIONS########## -dataset.tags.mock=/mockupTags.json #############TWITTER LOGIN CONFIGURATIONS######### twitter.login.redirect_uri=http://127.0.0.1:4200/login/twitter #############LINKEDIN LOGIN CONFIGURATIONS######### +linkedin.login.clientId= +linkedin.login.clientSecret= linkedin.login.redirect_uri=http://localhost:4200/login/linkedin +linkedin.login.user_info_url=https://api.linkedin.com/v2/me +linkedin.login.user_email=https://api.linkedin.com/v2/emailAddress?q=members&projection=(elements*(handle~)) +linkedin.login.access_token_url=https://www.linkedin.com/uas/oauth2/accessToken #############FACEBOOK LOGIN CONFIGURATIONS######### facebook.login.clientId= @@ -40,6 +41,8 @@ facebook.login.namespace= b2access.externallogin.user_info_url=https://b2access-integration.fz-juelich.de:443/oauth2/userinfo b2access.externallogin.access_token_url=https://b2access-integration.fz-juelich.de:443/oauth2/token b2access.externallogin.redirect_uri=http://opendmp.eu/api/oauth/authorized/b2access +b2access.externallogin.clientid= +b2access.externallogin.clientSecret= #############ORCID CONFIGURATIONS######### orcid.login.client_id=APP-766DI5LP8T75FC4R @@ -47,6 +50,13 @@ orcid.login.client_secret=f6ddc717-f49e-4bce-b302-2e479b226a24 orcid.login.access_token_url=https://orcid.org/oauth/token orcid.login.redirect_uri=http://localhost:4200/login/external/orcid +#############OPENAIRE CONFIGURATIONS######### +openaire.login.client_id= +openaire.login.client_secret= +openaire.login.access_token_url= +openaire.login.redirect_uri= +openaire.login.user_info_url= + #############CONFIRMATION EMAIL CONFIGURATIONS######### conf_email.expiration_time_seconds=14400 conf_email.subject=OpenDMP email confirmation diff --git a/dmp-backend/web/src/main/resources/application-production.properties b/dmp-backend/web/src/main/resources/application-production.properties index 6de88b0a2..9218ae216 100644 --- a/dmp-backend/web/src/main/resources/application-production.properties +++ b/dmp-backend/web/src/main/resources/application-production.properties @@ -17,11 +17,9 @@ pdf.converter.url=http://docsbox-web/ ####################CONFIGURATION FILES OVERRIDES CONFIGURATIONS########## configuration.externalUrls=/tmp/ExternalUrls.xml +configuration.rda=/tmp/RDACommonStandards.txt configuration.h2020template=/tmp/h2020.docx -configuration.resources.path=/tmp - -####################MOCK FILES CONFIGURATIONS########## -dataset.tags.mock=/mockupTags.json +configuration.configurable_login_providers= ####################SPRING MAIL CONFIGURATIONS################# spring.mail.default-encoding=UTF-8 @@ -46,6 +44,9 @@ google.login.clientId= linkedin.login.clientId= linkedin.login.clientSecret= linkedin.login.redirect_uri=https://opendmp.eu/login/linkedin +linkedin.login.user_info_url=https://api.linkedin.com/v2/me +linkedin.login.user_email=https://api.linkedin.com/v2/emailAddress?q=members&projection=(elements*(handle~)) +linkedin.login.access_token_url=https://www.linkedin.com/uas/oauth2/accessToken #############TWITTER LOGIN CONFIGURATIONS######### twitter.login.clientId= @@ -65,6 +66,13 @@ orcid.login.client_secret= orcid.login.access_token_url=https://orcid.org/oauth/token orcid.login.redirect_uri=https://opendmp.eu/login/external/orcid +#############OPENAIRE CONFIGURATIONS######### +openaire.login.client_id= +openaire.login.client_secret= +openaire.login.access_token_url= +openaire.login.redirect_uri= +openaire.login.user_info_url= + #############SPRING DATASOURCE CONFIGURATIONS######### spring.datasource.maxIdle: 10 spring.datasource.max-active: 70 diff --git a/dmp-backend/web/src/main/resources/application-staging.properties b/dmp-backend/web/src/main/resources/application-staging.properties index 226accae4..a4b4a0385 100644 --- a/dmp-backend/web/src/main/resources/application-staging.properties +++ b/dmp-backend/web/src/main/resources/application-staging.properties @@ -17,11 +17,9 @@ pdf.converter.url=http://docsbox-web/ ####################CONFIGURATION FILES OVERRIDES CONFIGURATIONS########## configuration.externalUrls=/tmp/ExternalUrls.xml -configuration.h2020template=/tmp/h2020.docx -configuration.resources.path=/tmp/ - -####################MOCK FILES CONFIGURATIONS########## -dataset.tags.mock=mockupTags.json +configuration.rda=/tmp/RDACommonStandards.txt +configuration.h2020template=tmp/h2020.docx +configuration.configurable_login_providers= ####################INVITATION MAIL CONFIGURATIONS############## ####################GENERIC MAIL CONFIGURATIONS################# @@ -48,6 +46,9 @@ google.login.clientId= linkedin.login.clientId= linkedin.login.clientSecret= linkedin.login.redirect_uri=https://devel.opendmp.eu/login/linkedin +linkedin.login.user_info_url=https://api.linkedin.com/v2/me +linkedin.login.user_email=https://api.linkedin.com/v2/emailAddress?q=members&projection=(elements*(handle~)) +linkedin.login.access_token_url=https://www.linkedin.com/uas/oauth2/accessToken #############TWITTER LOGIN CONFIGURATIONS######### twitter.login.clientId= @@ -71,6 +72,13 @@ orcid.login.client_secret= orcid.login.access_token_url=https://orcid.org/oauth/token orcid.login.redirect_uri=https://opendmp.eu/login/external/orcid +#############OPENAIRE CONFIGURATIONS######### +openaire.login.client_id= +openaire.login.client_secret= +openaire.login.access_token_url= +openaire.login.redirect_uri= +openaire.login.user_info_url= + #############ZENODO CONFIGURATIONS######### zenodo.url=https://sandbox.zenodo.org/api/ zenodo.access_token= diff --git a/dmp-backend/web/src/main/resources/application.properties b/dmp-backend/web/src/main/resources/application.properties index cacdd641f..ddd1ca1f9 100644 --- a/dmp-backend/web/src/main/resources/application.properties +++ b/dmp-backend/web/src/main/resources/application.properties @@ -19,6 +19,12 @@ spring.mail.test-connection=false spring.mail.properties.mail.smtp.auth=false spring.mail.properties.mail.smtp.starttls.enable=false +####################CONFIGURATION FILES OVERRIDES CONFIGURATIONS########## +configuration.externalUrls= +configuration.rda= +configuration.h2020template= +configuration.configurable_login_providers= + #############LOGIN CONFIGURATIONS######### #############GENERIC LOGIN CONFIGURATIONS######### autouser.root.email= @@ -37,6 +43,9 @@ google.login.clientId= linkedin.login.clientId= linkedin.login.clientSecret= linkedin.login.redirect_uri=http://opendmp.eu/login/linkedin +linkedin.login.user_info_url=https://api.linkedin.com/v2/me +linkedin.login.user_email=https://api.linkedin.com/v2/emailAddress?q=members&projection=(elements*(handle~)) +linkedin.login.access_token_url=https://www.linkedin.com/uas/oauth2/accessToken #############TWITTER LOGIN CONFIGURATIONS######### twitter.login.clientId= diff --git a/dmp-backend/web/src/main/resources/configurableLoginProviders.json b/dmp-backend/web/src/main/resources/configurableLoginProviders.json new file mode 100644 index 000000000..ae519164b --- /dev/null +++ b/dmp-backend/web/src/main/resources/configurableLoginProviders.json @@ -0,0 +1,27 @@ +{ + "providers": [ + { + "enabled": false, + "configurableLoginId": "myId", + "name": "myApp", + "clientId": "", + "clientSecret": "", + "redirect_uri": "", + "access_token_url": "", + "grant_type": "authorization_code", + "token": { + "access_token": "access_token", + "expires_in": "expires_in" + }, + "user": { + "id": "sub", + "name": "name", + "email": "email", + "user_info_url": "" + }, + "oauthUrl": "/authorize", + "scope": "email", + "state": "123562" + } + ] +} diff --git a/dmp-backend/web/src/main/resources/documents/h2020.docx b/dmp-backend/web/src/main/resources/documents/h2020.docx index b3e1fa144..2f98459a0 100644 Binary files a/dmp-backend/web/src/main/resources/documents/h2020.docx and b/dmp-backend/web/src/main/resources/documents/h2020.docx differ diff --git a/dmp-backend/web/src/main/resources/DatasetsInternalMockUpData.json b/dmp-backend/web/src/main/resources/mockData/DatasetsInternalMockUpData.json similarity index 100% rename from dmp-backend/web/src/main/resources/DatasetsInternalMockUpData.json rename to dmp-backend/web/src/main/resources/mockData/DatasetsInternalMockUpData.json diff --git a/dmp-backend/web/src/main/resources/FunderInternalMockUpData.json b/dmp-backend/web/src/main/resources/mockData/FunderInternalMockUpData.json similarity index 100% rename from dmp-backend/web/src/main/resources/FunderInternalMockUpData.json rename to dmp-backend/web/src/main/resources/mockData/FunderInternalMockUpData.json diff --git a/dmp-backend/web/src/main/resources/GrantInternalMockUpData.json b/dmp-backend/web/src/main/resources/mockData/GrantInternalMockUpData.json similarity index 100% rename from dmp-backend/web/src/main/resources/GrantInternalMockUpData.json rename to dmp-backend/web/src/main/resources/mockData/GrantInternalMockUpData.json diff --git a/dmp-backend/web/src/main/resources/OrganisationInternalMockUpData.json b/dmp-backend/web/src/main/resources/mockData/OrganisationInternalMockUpData.json similarity index 100% rename from dmp-backend/web/src/main/resources/OrganisationInternalMockUpData.json rename to dmp-backend/web/src/main/resources/mockData/OrganisationInternalMockUpData.json diff --git a/dmp-backend/web/src/main/resources/ProjectInternalMockUpData.json b/dmp-backend/web/src/main/resources/mockData/ProjectInternalMockUpData.json similarity index 100% rename from dmp-backend/web/src/main/resources/ProjectInternalMockUpData.json rename to dmp-backend/web/src/main/resources/mockData/ProjectInternalMockUpData.json diff --git a/dmp-backend/web/src/main/resources/RegistriesInternalMockUpData.json b/dmp-backend/web/src/main/resources/mockData/RegistriesInternalMockUpData.json similarity index 100% rename from dmp-backend/web/src/main/resources/RegistriesInternalMockUpData.json rename to dmp-backend/web/src/main/resources/mockData/RegistriesInternalMockUpData.json diff --git a/dmp-backend/web/src/main/resources/RepositoriesInternalMockUpData.json b/dmp-backend/web/src/main/resources/mockData/RepositoriesInternalMockUpData.json similarity index 100% rename from dmp-backend/web/src/main/resources/RepositoriesInternalMockUpData.json rename to dmp-backend/web/src/main/resources/mockData/RepositoriesInternalMockUpData.json diff --git a/dmp-backend/web/src/main/resources/ResearcherInternalMockUpData.json b/dmp-backend/web/src/main/resources/mockData/ResearcherInternalMockUpData.json similarity index 100% rename from dmp-backend/web/src/main/resources/ResearcherInternalMockUpData.json rename to dmp-backend/web/src/main/resources/mockData/ResearcherInternalMockUpData.json diff --git a/dmp-backend/web/src/main/resources/ServicesInternalMockUpData.json b/dmp-backend/web/src/main/resources/mockData/ServicesInternalMockUpData.json similarity index 100% rename from dmp-backend/web/src/main/resources/ServicesInternalMockUpData.json rename to dmp-backend/web/src/main/resources/mockData/ServicesInternalMockUpData.json diff --git a/dmp-backend/web/src/main/resources/TagsInternalMockUpData.json b/dmp-backend/web/src/main/resources/mockData/TagsInternalMockUpData.json similarity index 100% rename from dmp-backend/web/src/main/resources/TagsInternalMockUpData.json rename to dmp-backend/web/src/main/resources/mockData/TagsInternalMockUpData.json diff --git a/dmp-backend/web/src/main/resources/mockupTags.json b/dmp-backend/web/src/main/resources/mockData/mockupTags.json similarity index 100% rename from dmp-backend/web/src/main/resources/mockupTags.json rename to dmp-backend/web/src/main/resources/mockData/mockupTags.json diff --git a/dmp-dataset-templates/AcademyOfFinland.xml b/dmp-dataset-templates/AcademyOfFinland.xml new file mode 100644 index 000000000..e9ce27510 --- /dev/null +++ b/dmp-dataset-templates/AcademyOfFinland.xml @@ -0,0 +1,256 @@ + + + + + + + + + + +
+ + +
+ 1.1 + + + + 1.1.1 + + + + + + + + + What kinds of data is your research based on? What data will be collected, produced or reused?What file formats will the data be in? + Give a rough estimate of the size of the data produced or collected. Also explain what kinds of existing data you will use, for example, the types of texts, images, photographs, measurements, statistics, physical samples or codes. + + +
+
+ 1.2 + + + + 1.2.1 + + + + + + + + + How will the consistency and quality of data be controlled? + Explain how the data collection, analysis and processing methods used may affect the quality of data and how you will minimize the risks related to data accuracy. + + +
+
+ 1 + General description of data + + +
+ +
+ + +
+ 3.1 + + + + 3.1.1 + + + + + + + + + How will you document your data to make them findable, accessible, interoperable and reusable for you and others? What kinds of metadata standards, files or other documentation will you use to help others understand and use your data? + + + +
+
+ 3 + Documentation and metadata + + +
+
+ + +
+ 4.1 + + + + 4.1.1 + + + + + + + + + Where will your data be stored, and how will they be backed up? + Describe where you will store and back up your data during your research project. Methods for preserving and sharing your data after your research project has ended are explained in more detail in Section 5 + Consider who will be responsible for backup and recovery. If there are several researchers involved, create a plan with your collaborators and ensure safe transfer between participants. + +
+
+ 4.2 + + + + 4.2.1 + + + + + + + + + Who will be responsible for controlling access to your data, and how will secured access be controlled? + Describe who has access to your data, what they are authorised to do with the data and how you will ensure the safe transfer of data to your collaborators. + + +
+
+ 4 + Storage and backup during the research project + + +
+
+ + +
+ 5.1 + + + + 5.1.1 + + + + + + + + + What part of the data can be made openly available or published? Where and when will the data, or their metadata, be made available? + Describe whether you will publish or otherwise make all your data or only parts of them openly available. If your data or parts of them cannot be opened, please explain why. + + +
+
+ 5.2 + + + + 5.2.1 + + + + + + + + + Where will data with long-term value be archived, and for how long? + Briefly describe what data to archive and for how long – as well as what data to dispose of after the project. Describe the access policy to the archived data. + + +
+
+ 5 + Opening, publishing and archiving the data after the research project + + +
+
+ + +
+ 6.1 + + + + 6.1.1 + + + + + + + + + Who will be responsible for specific tasks of data management during the research project life cycle? + Estimate also the resources (e.g. financial, time and effort) required for data management. + Estimate the need to hire expert help to manage, preserve and share the data. Consider the additional computational facilities and resources that need to be accessed, and what the associated costs will amount to. + +
+
+ 6 + Data management responsibilities and resources + + +
+
+
\ No newline at end of file diff --git a/dmp-dataset-templates/FWF.xml b/dmp-dataset-templates/FWF.xml new file mode 100644 index 000000000..84c5a7986 --- /dev/null +++ b/dmp-dataset-templates/FWF.xml @@ -0,0 +1,1287 @@ + + + + + + + + +
+ + +
+ 1.1 + + + + 1.1.1 + + + + + + + + + What kinds of data/source code will be generated or reused (type, format, volume)? + + + +
+
+ 1.2 + + + + 1.2.1 + + + + + + + + + How will the research data be generated and which methods will be used? + + + +
+
+ 1.3 + + + + 1.3.1 + + + + + + + + + How will you structure the data and handle versioning? + + + +
+
+ 1.4 + + + + 1.4.1 + + + + + + + + + Who is the target audience? + + + +
+
+ 1 + Data Characteristics: Description of the data + + +
+
+ +
+ + +
+ 2.1.1 + + + + 2.1.1.1 + + + + + true + + + true + + + + + + + 2.1.1.2 + + + + + + + + + 2.1.1.3 + + + + + true + + + + + + + + Will you use metadata to describe the data? + + + +
+
+ 2.1.2 + + + + 2.1.2.1 + + + + + + + + 2.1.2.2 + + + + + + + + + URL/Location + + + +
+
+ 2.1.3 + + + + 2.1.3.1 + + + + + true + + + true + + + + + + + 2.1.3.2 + + + + + + + + + 2.1.3.3 + + + + + true + + + + + + + + Will your metadata use standardized vocabularies? + + + +
+
+ 2.1.4 + + + + 2.1.4.1 + + + + + + + + 2.1.4.2 + + + + + + + + + URL/Description + + + +
+
+ 2.1 + Metadata standards + + What metadata standards (if any) will be in use and why? +
+
+ +
+ + +
+ 2.2.1.1 + + + + 2.2.1.1.1 + + + + + some + + + none + + + + + + + + + + + Will all your data be openly accessible? + + + +
+
+ 2.2.1.2 + + + + 2.2.1.2.1 + + + + + + + + 2.2.1.2.2 + + + + + + + + 2.2.1.2.3 + + + + + + + + + Data type/ Reason/ URL + + + +
+
+ 2.2.1.3 + + + + 2.2.1.3.1 + + + + + + + + 2.2.1.3.2 + + + + + + + + 2.2.1.3.3 + + + + + + + + + Data type/ Reason/ URL + + + +
+
+ 2.2.1.4 + + + + 2.2.1.4.1 + + + + + + + + + 2.2.1.4.2 + + + + + true + + + + + + + + How will the data be made available? + + + +
+
+ 2.2.1.5 + + + + 2.2.1.5.1 + + + + + + + + 2.2.1.5.2 + + + + + + + + + URL/Name + + + +
+
+ 2.2.1 + What information is needed for the data to be findable, accessible, interoperable and re-usable (FAIR) in the future? + + +
+
+ + +
+ 2.2.2.1 + + + + 2.2.2.1.1 + + + + + true + + + + + + + + Will you provide persistent identifiers for your data? + + + +
+
+ 2.2.2.2 + + + + 2.2.2.2.1 + + + + + + + + + + + + Persistent identifiers + Select a persistent identifier (PID) from the list. You may select multiple PIDs according to the types of research outputs, needs and the area of your research. + + +
+
+ 2.2.2.3 + + + + 2.2.2.3.1 + + + + + true + + + + + + + + Will you provide searchable metadata for your data? + + + +
+
+ 2.2.2.4 + + + + 2.2.2.4.1 + + + + + + + + + 2.2.2.4.2 + + + + + true + + + + + + + + What services will you use to provide searchable metadata? + + + +
+
+ 2.2.2.5 + + + + 2.2.2.5.1 + + + + + + + + 2.2.2.5.2 + + + + + + + + + URL/Name + + + +
+
+ 2.2.2 + Is the data machine-readable? + + +
+
+ + +
+ 2.2.3.1 + + + + 2.2.3.1.1 + + + + + + + + + How are you planning to document this information? + + + +
+
+ 2.2.3 + How are you planning to document this information? + + +
+
+ + 2.2 + Documentation of data + + +
+
+ + +
+ 2.3.1 + + + + 2.3.1.1 + + + + + + + + + What quality assurance processes will you adopt? + + + +
+
+ 2.3.2 + + + + 2.3.2.1 + + + + + + + + + How will the consistency and quality of data collection be controlled and documented? + + + +
+
+ 2.3 + Data quality control + + +
+
+ + 2 + Documentation and Metadata + + +
+
+ +
+ + +
+ 3.1.1 + + + + 3.1.1.1 + + + + + + + + + What persistent identifier will be used? + + + +
+
+ 3.1 + Data sharing strategy + + +
+
+ + +
+ 3.2.1 + + + + 3.2.1.1 + + + + + true + + + + + + + + Will there be data that will not be stored for long-term? + + + +
+
+ 3.2.2 + + + + 3.2.2.1 + + + + + + + + + What data will not be stored for long-term? + + + +
+
+ 3.2.3 + + + + 3.2.3.1 + + + + + true + + + true + + + + + + + + Will there be data that will be preserved for long-term? + + + +
+
+ 3.2.4 + + + + 3.2.4.1 + + + + + + + + + What data will be preserved for long-term + + + +
+
+ 3.2.5 + + + + 3.2.5.1 + + + + + true + + + false + + + + + + + + Will you use standardised formats for some or all of your data? + + + +
+
+ 3.2.6 + + + + 3.2.6.1 + + + + + + + + + 3.2.6.2 + + + + + true + + + + + + + + Which standardised data formats do you plan on using? + + + +
+
+ 3.2.7 + + + + 3.2.7.1 + + + + + + + + 3.2.7.2 + + + + + + + + + Standardized formats + Is the structure of the file(s) provided in a standardized format? + + +
+
+ 3.2.8 + + + + 3.2.8.1 + + + + + + + + 3.2.8.2 + + + + + + + + 3.2.8.3 + + + + + + + + + Please describe the formats you plan to store your data in, including any URLs to documentation. + + + +
+
+ 3.2.9 + + + + 3.2.9.1 + + + + + + + + + How will the data be stored after the project ends? + + + +
+
+ 3.2.10 + + + + 3.2.10.1 + + + + + + + + + + + + Where will the data be stored after the project ends? Is the storage sufficiently secure for the data and does the storage provide backup and recovery procedures? + + + +
+
+ 3.2.11 + + + + 3.2.11.1 + + + + + + + + + + + + For how long will the data be stored? + + + +
+
+ 3.2.12 + + + + 3.2.12.1 + + + + + + + + + Are there any costs that need to be covered for storage? + + + +
+
+ 3.2.13 + + + + 3.2.13.1 + + + + + + + + + + + + At what point during or after the project will the data be stored? + + + +
+
+ 3.2.14 + + + + 3.2.14.1 + + + + + + + + + Are there any technical barriers to making the research data fully or partially accessible? + + + +
+
+ 3.2 + Data storage strategy + + +
+
+ + 3 + Data Availability and Storage + + +
+ +
+
\ No newline at end of file diff --git a/dmp-dataset-templates/Horizon2020_V2_Wordlist_fixes.xml b/dmp-dataset-templates/Horizon2020_V2_Wordlist_fixes.xml new file mode 100644 index 000000000..b86ec2096 --- /dev/null +++ b/dmp-dataset-templates/Horizon2020_V2_Wordlist_fixes.xml @@ -0,0 +1,1881 @@ + + + + + + + + +
+ + +
+ 1.1 + + + + + 1.1.1 + + + + + + + + + What is the purpose of the data collection/generation and its relation to the objectives of the project? + + + +
+
+ 1.2 + + + + + 1.2.1 + + + + + + + + + What types and formats of data will the project generate/collect? + + + +
+
+ 1.3 + + + + + 1.3.1 + + + + + + + + + Will you re-use any existing data and how? + + + +
+
+ 1.4 + + + + + 1.4.1 + + + + + + + + + What is the origin of the data? + + + +
+
+ 1.5 + + + + + 1.5.1 + + + + + + + + + What is the expected size of the data? + + + +
+
+ 1.6 + + + + + 1.6.1 + + + + + + + + + To whom might it be useful ('data utility')? + + + +
+
+ 1 + Data Summary + + Answer the following questions to provide a summary of the types and characteristics of data collected, generated, shared and re-used during your research activities. Highlight why it is of relevance to the project and useful to other researchers. +
+
+ +
+ + +
+ 2.1.1 + + + + + 2.1.1.1 + + + + + + + true + + + true + + + true + + + true + + + true + + + + + + + + 2.1.1.2 + + + + + + + + + + 2.1.1.3 + + + + + true + + + + + + + + Will you use metadata to describe the data? + + + +
+
+ 2.1.2 + + + + + 2.1.2.1 + + + + + + + + + + + 2.1.2.2 + + + + + + + + + + + URL/Location + + + +
+
+ 2.1.3 + + + + + 2.1.3.1 + + + + + true + + + true + + + + + + + + 2.1.3.2 + + + + + + + + + + + + 2.1.3.3 + + + + + true + + + + + + + + Will your metadata use standardised vocabularies? + + + +
+
+ 2.1.4 + + + + + 2.1.4.1 + + + + + + + + + + + 2.1.4.2 + + + + + + + + + + + URL/Description + + + +
+
+ 2.1.5 + + + + + 2.1.5.1 + + + + + + + + + + + Will you make the metadata available free-of-charge? + + + +
+
+ 2.1.6 + + + + + 2.1.6.1 + + + + + + + + + + + Will your metadata be harvestable? + + + +
+
+ 2.1.7 + + + + + 2.1.7.1 + + + + + + + true + + + + + + + + Will you use naming conventions for your data? + + + +
+
+ 2.1.8 + + + + + 2.1.8.1 + + + + + + + + + + + 2.1.8.2 + + + + + + + + + + + URL/Name + + + +
+
+ 2.1.9 + + + + + 2.1.9.1 + + + + + + + + + + + Will you provide clear version numbers for your data? + + + +
+
+ 2.1.10 + + + + + 2.1.10.1 + + + + + + + true + + + + + + + + Will you provide persistent identifiers for your data? + + + +
+
+ 2.1.11 + + + + + 2.1.11.1 + + + + + + + + + + + + + + Persistent identifiers + Select a persistent identifier (PID) from the list. You may select multiple PIDs according to the types of research outputs, needs and the area of your research. + + +
+
+ 2.1.12 + + + + + 2.1.12.1 + + + + + + + true + + + + + + + + Will you provide searchable metadata for your data? + + + +
+
+ 2.1.13 + + + + + 2.1.13.1 + + + + + + + + + + + + 2.1.13.2 + + + + + + + true + + + + + + + + What services will you use to provide searchable metadata? + + + +
+
+ 2.1.14 + + + + + 2.1.14.1 + + + + + + + + + + + 2.1.14.2 + + + + + + + + + + + URL/Name + + + +
+
+ 2.1.15 + + + + + 2.1.15.1 + + + + + + + true + + + false + + + + + + + + Will you use standardised formats for some or all of your data? + + + +
+
+ 2.1.16 + + + + + 2.1.16.1 + + + + + + + + + + + + 2.1.16.2 + + + + + + + true + + + + + + + + Which standardised data formats do you plan on using? + + + +
+
+ 2.1.17 + + + + + 2.1.17.1 + + + + + + + + + + + 2.1.17.2 + + + + + + + + + + + Standardised formats + Is the structure of the file(s) provided in a standardised format? + + +
+
+ 2.1.18 + + + + + 2.1.18.1 + + + + + + + + + + + 2.1.18.2 + + + + + + + + + + + 2.1.18.3 + + + + + + + + + + + Please describe the formats you plan to store your data in, including any URLs to documentation. + + + +
+
+ 2.1.19 + + + + + 2.1.19.1 + + + + + + + some + + + none + + + + + + + + + + + Are the file formats you will use open? + + + +
+
+ 2.1.20 + + + + + 2.1.20.1 + + + + + + + + + + + Please describe which data are not in an open format and why? + + + +
+
+ 2.1.21 + + + + + 2.1.21.1 + + + + + + + + + + + Please describe which data are not in an open format and why? + + + +
+
+ 2.1.22 + + + + + 2.1.22.1 + + + + + + + forsomedata + + + fornodata + + + + + + + + + + + Do supported open-source tools exist for accessing the data? + + + +
+
+ 2.1.23 + + + + + 2.1.23.1 + + + + + + + + + + + Please describe which data require proprietary tools to access the data? + + + +
+
+ 2.1.24 + + + + + 2.1.24.1 + + + + + + + + + + + Please describe which data require proprietary tools to access the data? + + + +
+
+ 2.1.25 + + + + + 2.1.25.1 + + + + + + + + + + + Will you provide metadata describing the quality of the data? + + + +
+
+ 2.1 + Making data findable, including provisions for metadata + + Data are findable when described with metadata and vocabularies in a standardized way, assigned a Persistent Identifiers (PIDs) and are registered or indexed in a searchable resource +
+
+ + +
+ 2.2.1 + + + + + 2.2.1.1 + + + + + + + true + + + + + + + + Are there ethical or legal issues that can impact sharing the data? + + + +
+
+ 2.2.2 + + + + + 2.2.2.1 + + + + + + + some + + + none + + + + + + + + + + + Will all your data be openly accessible? + + + +
+
+ 2.2.3 + + + + + 2.2.3.1 + + + + + + + + + + + 2.2.3.2 + + + + + + + + + + + 2.2.3.3 + + + + + + + + + + + Data type/ Reason/ URL + + + +
+
+ 2.2.4 + + + + + 2.2.4.1 + + + + + + + + + 2.2.4.2 + + + + + + + + + 2.2.4.3 + + + + + + + + + Data type/ Reason/ URL + + + +
+
+ 2.2.5 + + + + + 2.2.5.1 + + + + + + + + + + + + 2.2.5.2 + + + + + + + true + + + + + + + + How will the data be made available? + Select the repository where your data will be uploaded. + + +
+
+ 2.2.6 + + + + + 2.2.6.1 + + + + + + + + + + + 2.2.6.2 + + + + + + + + + + + URL/Name + + + +
+
+ 2.2.7 + + + + + 2.2.7.1 + + + + + + + + + + + + + + Is the storage sufficiently secure for the data and does the storage provide backup and recovery procedures? + + + +
+
+ 2.2.8 + + + + + 2.2.8.1 + + + + + + + true + + + true + + + + + + + + Are there any methods or tools required to access the data? + + + +
+
+ 2.2.9 + + + + + 2.2.9.1 + + + + + + + + + + + 2.2.9.2 + + + + + + + + + + + Please provide links describing the methods for accessing the data. + + + +
+
+ 2.2.10 + + + + + 2.2.10.1 + + + + + + + + + + + 2.2.10.2 + + + + + + + + + + + Please provide links describing the tools for accessing the data. + + + +
+
+ 2.2.11 + + + + + 2.2.11.1 + + + + + + + + + + + + + + Will you also make auxiliary data that may be of interest to researchers available? + + + +
+
+ 2.2 + Making data openly accessible + + Not all data can be made publicly open, hence data can be FAIR but not open, or open but not FAIR or both FAIR and open. Data are accessible when uploaded in a data repository and retrieved by their PIDs. When data can not be shared openly, metadata should be provided (even when the data are no longer available). In the case of sensitive or personal data, anonymization or pseudonymization and specific access rights can be applied. Where accessing data requires the use of complementary methods or tools, such procedures should be documented. +
+
+ + +
+ 2.3.1 + + + + + 2.3.1.1 + + + + + + + some + + + none + + + + + + + + + + + Will you use a standard vocabulary for your data types? + + + +
+
+ 2.3.2 + + + + + 2.3.2.1 + + + + + + + + + + + Will you provide a mapping to more commonly used ontologies? + + + +
+
+ 2.3.3 + + + + + 2.3.3.1 + + + + + + + + + + + Will you provide a mapping to more commonly used ontologies? + + + +
+
+ 2.3 + Making data interoperable + + Data are interoperable, meaning they can be easily understood and shared with other platforms and systems, when they are created using standard vocabularies and include references to other data and metadata. +
+
+ + +
+ 2.4.1 + + + + + 2.4.1.1 + + + + + + + later + + + never + + + + + + + + + + + When do you plan to make your data available for reuse? + + + +
+
+ 2.4.2 + + + + + 2.4.2.1 + + + + + + + + + + + Please specify how long after the project has ended the data will be made available? + + + +
+
+ 2.4.3 + + + + + 2.4.3.1 + + + + + + + + + + + Please describe the reason the data will not be made available. + + + +
+
+ 2.4.4 + + + + + 2.4.4.1 + + + + + + + + + + + + What internationally recognised licence will you use for your data? + + + +
+
+ 2.4.5 + + + + + 2.4.5.1 + + + + + + + true + + + + + + + + Do you have documented procedures for quality assurance of your data? + + + +
+
+ 2.4.6 + + + + + 2.4.6.1 + + + + + + + + + + <description/> + <extendedDescription/> + <additionalInformation/> + </fieldSet> + <fieldSet id="fieldSet-83SiE" ordinal="6"> + <numbering>2.4.7</numbering> + <commentField commentFieldValue="" hasCommentField="false"/> + <fields> + <field id="supportForDataReuse" ordinal="0"> + <rdaCommonStandard/> + <numbering>2.4.7.1</numbering> + <validations> + <validation type="0"/> + </validations> + <defaultValue type="" value=""/> + <visible style=""> + <rule ruleStyle="" target="supportForDataReuseTimeSpan" type=""> + <value type="">true</value> + </rule> + <rule ruleStyle="" target="unsupportedforreusewhy" type=""> + <value type="">false</value> + </rule> + </visible> + <viewStyle cssClass="" renderstyle="booleanDecision"/> + <data label=""/> + </field> + </fields> + <multiplicity max="0" min="0"/> + <title>Will you provide any support for data reuse? + + + +
+
+ 2.4.8 + + + + + 2.4.8.1 + + + + + + + + + + + + + + How long do you intend to support data reuse? + + + +
+
+ 2.4.9 + + + + + 2.4.9.1 + + + + + + + + + + + Please specify why the data will be unsupported for reuse. + + + +
+
+ 2.4 + Increase data reuse + + Data can be reused when the conditions about how others can make use of the data are well-described following community-standards and are communicated as specified by the owners. Such information can be found in licenses attributed to data and in references about the data provenance. +
+
+ + +
+ 2.5.1 + + + + + 2.5.1.1 + + + + + + + + + + + + + + How will the cost of making your data findable, accessible, interoperable and reusable be covered? + + + +
+
+ 2.5.2 + + + + + 2.5.2.1 + + + + + + + false + + + + + + + + Will you identify a data manager to manage your data, if not who will be responsible for the management of your data? + + + +
+
+ 2.5.3 + + + + + 2.5.3.1 + + + + + + + + + + + Identify the people or roles that will be responsible for the management of the project data + + + +
+
+ 2.5.4 + + + + + 2.5.4.1 + + + + + + + other + + + + + + + + + + + How do you intend to ensure data reuse after your project finishes? + + + +
+
+ 2.5 + Allocation of resources + + Data management can be costly, especially when its planning hasn't been sufficient from the very beginning of the research process. Costing of data management includes for example potential use of proprietary services and tools or extra effort needed to perform specific tasks or even to develop tools from scratch. +
+
+ + 2 + FAIR Data + + In general terms, your research data should be 'FAIR', that is findable, accessible, interoperable and re-usable. These principles precede implementation choices and do not necessarily suggest any specific technology, standard, or implementation-solution. This template is not intended as a strict technical implementation of the FAIR principles, it is rather inspired by FAIR as a general concept. +
+
+ + +
+ 3.1 + + + + + 3.1.1 + + + + + + + keptoninsecure + + + + + + + + + + + What do you plan to do with research data of limited use + + + +
+
+ 3.2 + + + + + 3.2.1 + + + + + + + + + + + Please describe why the data will be kept on insecure, unmanaged storage + + + +
+
+ 3 + Data Security + + +
+
+ + +
+ 4.1 + + + + + 4.1.1 + + + + + + + true + + + + + + + + Do you make use of other procedures for data management? + + + +
+
+ 4.2 + + + + + 4.2.1 + + + + + + + + + + + Please provide links to documentation on these other procedures. + + + +
+
+ 4 + Other + + +
+
+
\ No newline at end of file diff --git a/dmp-dataset-templates/NationalScienceCenterPoland.xml b/dmp-dataset-templates/NationalScienceCenterPoland.xml new file mode 100644 index 000000000..a93d5a345 --- /dev/null +++ b/dmp-dataset-templates/NationalScienceCenterPoland.xml @@ -0,0 +1 @@ +
1.1.1dmp1.1.1.1What quality assurance processes will you use?
1.1.21.1.2.1Which existing data (yours or third party) will you re-use?
1.1.31.1.3.1How data provenance will be documented?
1.1.41.1.4.1How will you organize your files and handle versioning?
1.1How will new data be collected or produced and/or how will existing data be reused? What standards, methodologies or software will be used if new data are collected or produced?
1.2.11.2.1.1What is the purpose of the data collection/generation and its relation to the objectives of the project?
1.2.21.2.2.1 What is the origin of the data?
1.2.31.2.3.11.2.3.21.2.3.31.2.3.4What type, format and volume of data will you collect, generate or reuse?
1.2What data (for example the kinds, formats, and volumes) will be collected or produced?The descriptions should include the type, format and content of each dataset. Furthermore, provide an estimation of the volume of the generated data sets. Give details on the data format: the way in which the data is encoded for storage, often reflected by the filename extension (i.e. pdf. xls.) Give preference to open and standard formats.
1Data description and collection or re-use of existing data
2.1.12.1.1.1truetruetrue2.1.1.22.1.1.3trueWill you use metadata to describe the data?
2.1.22.1.2.12.1.2.2URL/Location
2.1.32.1.3.1truetrue2.1.3.22.1.3.3trueWill your metadata use standardised vocabularies?
2.1.42.1.4.12.1.4.2URL/Description
2.1.52.1.5.1What information is required for users (computer or human) to read and interpret the data in the future?
2.1.62.1.6.1trueIs the data machine-readable?
2.1.72.1.7.1trueWill you provide searchable metadata for your data?
2.1.82.1.8.12.1.8.2trueWhat services will you use to provide searchable metadata?
2.1.92.1.9.12.1.9.2URL/Name
2.1.102.1.10.1How will you generate this documentation?
2.1.112.1.11.1trueWill you use standardized formats to annotate some or all of your (meta)data?
2.1.122.1.12.12.1.12.2trueWhich standardised data formats do you plan on using?
2.1.132.1.13.12.1.13.2Other standardized formatsIs the structure of the file(s) provided in a standardized format?
2.1.142.1.14.1Will you use international standards or schemes (i.e. Dublin Core, DDI) to structure metadata?
2.1.152.1.15.1 Persistent identifiers
2.1What metadata and documentation (for example methodology or data collection and way of organising data) will accompany data?
2.2.12.2.1.1true2.2.1.2Do you have documented procedures for quality assurance of your data?
2.2.22.2.2.1How the data collection, analysis and processing methods used may affect the quality of data?
2.2.32.2.3.1How measurement error and bias will be eliminated?
2.2.42.2.4.1How you will minimise the risks related to data accuracy?
2.2What data quality control measures will be used?
2Documentation and data quality
3.1.13.1.1.13.1.1.2What is your storage capacity and where will the data be stored?
3.1.23.1.2.1What are the back-up procedures?
3.1.33.1.3.1Are special measures needed to transfer data from mobile devices, from fieldwork sites or from home equipment to a central work server?
3.1.43.1.4.1Do analogue or paper-based research data (maps, photographs, text) need to be digitised to increase their potential for sharing?
3.1How will data and metadata be stored and backed up during the research process?
3.2.13.2.1.1keptoninsecureWhat do you plan to do with research data of limited use
3.2.23.2.2.1Please describe why the data will be kept on insecure, unmanaged storage
3.2.33.2.3.1How the data will be recovered in the event of an incident?
3.2.43.2.4.1Who will have an access to the data during the research?
3.2.53.2.5.1How access to data will be controlled, especially in collaborative partnerships?
3.2How will data security and protection of sensitive data be taken care of during the research?If external services are asked for storage, it is important that this does not conflict with the policy of each entity involved in the project, especially concerning the issue of sensitive data. Consider data protection, particularly if your data is sensitive for example containing personal data, politically sensitive information, dual-use data. Explain which institutional data protection policies are in place.
3Storage and backup during the research process
5.1.15.1.1.1How will potential users find out about your data?
5.1.25.1.2.1For how long will the data be stored?
5.1.35.1.3.1Are there any barriers and constraints to making the research data fully or partially accessible?
5.1.45.1.4.1Will journal publishers require deposit of data supporting article findings?
5.1.55.1.5.1Do you need to ask participants for their consent for data to be shared?
5.1How and when will data be shared? Are there possible restrictions to data sharing or embargo reasons?
5.2.15.2.1.15.2.1.25.2.1.3What data must be retained or destroyed for contractual, legal, or regulatory purposes?
5.2.25.2.2.1How it will be decided what data to keep?
5.2.35.2.3.1What procedure would be used to select data to be preserved?
5.2.45.2.4.15.2.4.2true5.2.4.3What repository will you be using? Is this repository conform to the FAIR Data Principles?
5.2.55.2.5.15.2.5.2URL/Name
5.2How will data for preservation be selected, and where will data be preserved long term (for example a data repository or archive)?Consider how and on which repository the data will be made available. Outline the plan for data preservation and give information on how long the data will be retained. Consider the cost of data deposit and storage space for long-term storage. Estimate how much data storage space is needed for the entire duration of the project. Please, explain whether you choose digital repository maintained by a nonprofit organisation?
5.3.15.3.1.1Do data need to be converted to a standard or open format with long-term validity for long-term preservation?
5.3.25.3.2.1Is additional equipment or software needed for scanning or conversion?
5.3.35.3.3.1What mechanism will be used for data sharing; e.g. request handled directly, repository?
5.3What methods or software tools will be needed to access and use the data?The methods applied to data sharing will depend on several factors such as type, size, complexity and sensitivity of data. Indicate whether potential users need specific tools to access and (re-)use the data. Consider the sustainability of software needed for accessing the data.
5.4.15.4.1.1trueWill persistent identifier for the data be obtained?
5.4.25.4.2.1Which existing persistent identifier will be used (e.g. Digital Object Identifiers, Accession Numbers)?
5.4How will the application of a unique and persistent identifier (such as a Digital Object Identifier (DOI)) to each data set be ensured?Explain how the data might be re-used in other contexts. Persistent identifier should be applied so that data can be reliably and efficiently located and referred to. Persistent identifiers also help to track citations and reuse.
5Data sharing and long-term preservationData have to be shared as soon as possible, but at the latest at the time of publication of the respective scientific output. Please, also consider how the reuse of your data will be valued and acknowledged by other researchers. Explain when the data will be made available. Justify the retention period for data storage. Indicate the expected timely release. Indicate whether data sharing will be postponed or restricted for example to publish, protect intellectual property, or seek patents. Consider whether a non-disclosure agreement would give sufficient protection for confidential data.
6.1.16.1.1.1Who will be responsible for data management (i.e. data steward)?
6.1.26.1.2.1What is the role of data steward in your institution?
6.1.36.1.3.1What is his/her position in the institution?
6.1Who will be responsible for data management?
6.2.16.2.1.1What resources will be dedicated to data management and ensuring that data will be FAIR?
6.2.26.2.2.1What are the costs for making data FAIR in your project?
6.2.36.2.3.1How will these be covered?
6.2What resources will be dedicated to data management and ensuring that data will be FAIR?
6Data management responsibilities and resources
\ No newline at end of file diff --git a/dmp-dataset-templates/NetherlandsOrganisationForScientificResearch (NWO).xml b/dmp-dataset-templates/NetherlandsOrganisationForScientificResearch (NWO).xml new file mode 100644 index 000000000..e4fedbd0e --- /dev/null +++ b/dmp-dataset-templates/NetherlandsOrganisationForScientificResearch (NWO).xml @@ -0,0 +1,885 @@ + + + + + + + + + +
+ + +
+ 1.1 + + + + 1.1.1 + + + + + + + + 1.1.2 + + + + + + + + + Name applicant and project number + + + Fill in the name of the projectleader and the project number allocated by NWO +
+
+ 1.2 + + + + 1.2.1 + + + + + + + + + Did you ask for support of the data management support office of your institution? + + + NWO urgently advises researchers to seek support with the completion of this data management plan at an early stage. All universities and university medical centres provide professionalised support for research data management through their university library or ICT-department. A list of contact persons can be found on the website of NWO. +
+
+ 1 + General Information + + +
+
+ + +
+ 2.1 + + + + 2.1.1 + + + + + + + + + Describe the data that will be collected/generated within the project + + + Describe the data and documents that will be generated during the project +
+
+ 2.2 + + + + 2.2.1 + + + + + + + + + Specify the type and format of the data + + + Which type and format data will be stored, digital/non-digital, raw/processed data, software, curricula material or combinations of these. NWO understands ‘data’ to be both collected, unprocessed data as well as analysed, generated data. This can be in all conceivable formats; digital and non-digital (for example samples, completed questionnaires, sound recordings, etc.). +
+
+ 2 + Description dataset + + +
+
+ +
+ + +
+ 3.1.1 + + + + 3.1.1.1 + + + + + + + + 3.1.1.2 + + + + + + + + + What is the volume of the data and where will the data be stored? + + + Make a realistic estimation of the volume of the data that will be generated and the necessary storage capacity and state where you plan to store the data during the research. In the case of digital data, NWO data to be stored in the central storage centre of your institution, for example the ICT department and/or the university library. +
+
+ 3.1.2 + + + + 3.1.2.1 + + + + + + + + + Is there sufficient storage capacity during the project? + + + It is important that there is enough storage capacity, and in the case of digital data, also a backup of your data. An automatic backup by the ICT Department is safer than a manual backup. Storage of data on laptops, hard disks or external media is in general risky and will therefore, in principle, not be accepted by NWO. If external services are used then you must ensure that no conflicts of interest with the policy of research partners or co-financiers and with the policy of your department or institute, for example about the security of sensitive data +
+
+ 3.1.3 + + + + 3.1.3.1 + + + + + + + + 3.1.3.2 + + + + + + + + + Will the data be backed up regularly during the project? Who is responsible for this? + + + +
+
+ 3.1.4 + + + + 3.1.4.1 + + + + + + + + 3.1.4.2 + + + + + + + + + + + + What are the expected costs? How will these costs be covered? + Please specify these and state an amount that is as realistic as possible. + + Make a realistic estimation of the costs. Important factors that determine the costs are: +a. the type of data; +b. b. the capacity needed for storage and backup; +c. c. the amount of manual work for the allocating of metadata and the drawing up of other documentation such as code books and queries used in the statistical package; +d. d. the extent to which the data needs to be made secure; +e. e. the hiring in of external data management and other expertise. + +
+
+ 3.1 + During the research + + +
+
+ + +
+ 3.2.1 + + + + 3.2.1.1 + + + + + true + + + false + + + + + + + 3.2.1.2 + + + + + + + + + + Will the data be stored in trusted repository after the project? + + + Specify in which trusted repository the data will be stored. There are a number of international certification schemes which determine the trustworthiness of data repositories. Of these the international Data Seal of Approval is the most basic set of criteria. Trusted Digital Repositories with a quality mark include repositories with a Data Seal of Approval, DIN-31644-, ISO-16363- or WDS/ICSU certification. An overview of existing repositories with Data Seal of Approval can be found in this list of repositories. +
+
+ 3.2.2 + + + + 3.2.2.1 + + + + + + + + + How will the data be made findable, accessible, interoperable and re-usable? + + + +
+
+ 3.2.3 + + + + 3.2.3.1 + + + + + true + + + + + + + + Will you provide persistent identifiers for your data? + + + A persistent identifier helps to make your data findable and citable by others. Most trusted repositories will provide a PID upon deposition of the data. +
+
+ 3.2.4 + + + + 3.2.4.1 + + + + + + + + + + + + Persistent identifiers + + + +
+
+ 3.2.5 + + + + 3.2.5.1 + + + + + + + + + For how long will the data be archived? + + + According to the Netherlands Code of Conduct for Scientific Practice (2018), raw and processed data must be stored for a period appropriate for the discipline and methodology at issue. NWO considers a minimal period of 10 years reasonable. +
+
+ 3.2.6 + + + + 3.2.6.1 + + + + + + + + 3.2.6.2 + + + + + + + + + + + + What are the expected costs? How will these costs be covered? + Specify this and state an amount that is as realistic as possible. + + +
+
+ 3.2 + After the research + + The data should preferably be stored for the long-term in a national or international trusted repository. If this is not possible then the data should be stored by the institutional repository. Contact the intended data repository or archive well in advance about the requirements for depositing the data. +
+
+ + 3 + Data Storage + + +
+
+ +
+ + +
+ 4.1.1 + + + + 4.1.1.1 + + + + + true + + + true + + + true + + + + + + + 4.1.1.2 + + + + + + + + + 4.1.1.3 + + + + + true + + + + + + + + Will you use metadata to describe the data? + + + +
+
+ 4.1.2 + + + + 4.1.2.1 + + + + + + + + 4.1.2.2 + + + + + + + + + URL/Location + + + +
+
+ 4.1.3 + + + + 4.1.3.1 + + + + + true + + + true + + + + + + + 4.1.3.2 + + + + + + + + + 4.1.3.3 + + + + + true + + + + + + + + Will your metadata use standardized vocabularies? + + + +
+
+ 4.1.4 + + + + 4.1.4.1 + + + + + + + + 4.1.4.2 + + + + + + + + + URL/Description + + + +
+
+ 4.1.5 + + + + 4.1.5.1 + + + + + true + + + + + + + + Will you use naming conventions for your data? + + + +
+
+ 4.1.6 + + + + 4.1.6.1 + + + + + + + + 4.1.6.2 + + + + + + + + + URL/Name + + + +
+
+ 4.1.7 + + + + 4.1.7.1 + + + + + + + + + Will you provide clear version numbers for your data? + + + +
+
+ 4.1.8 + + + + 4.1.8.1 + + + + + true + + + + + + + + Will you provide searchable metadata for your data? + + + +
+
+ 4.1.9 + + + + 4.1.9.1 + + + + + + + + + 4.1.9.2 + + + + + true + + + + + + + + What services will you use to provide searchable metadata? + + + +
+
+ 4.1.10 + + + + 4.1.10.1 + + + + + + + + 4.1.10.2 + + + + + + + + + URL/Name + + + +
+
+ 4.1 + How will the data be documented? + + +
+
+ + 4 + Standards and Metadata + + To make data findable and readable in the future and to be able to interpret it the data collection must be provided with descriptive information in the form of metadata. Without metadata – meaning without a good documentation of the data – most data can not be interpreted ore reused properly. Disciplines have developed different standards for metadata. That way datasets stemming from the same discipline can be linked or data can be combined. A widely used standards is the Dublin Core standard. The Digital Curation Centre (DCC) maintains a list of widely used disciplinary meta data standards. +
+
+ + +
+ 5.1 + + + + 5.1.1 + + + + + later + + + never + + + + + + + + + + + Are the data available for reuse after the project and when? + + + +
+
+ 5.2 + + + + 5.2.1 + + + + + + + + + Please specify how long after the project has ended the data will be made available? + + + +
+
+ 5.3 + + + + 5.3.1 + + + + + + + + + Please explain why the data are not suitable and/or available for reuse. + + + +
+
+ 5.4 + + + + 5.4.1 + + + + + true + + + + + + + 5.4.2 + + + + + + + + + Is there part of the data that cannot be made (directly) available? If yes, then please state the part concerned. + + + +
+
+ 5.5 + + + + 5.5.1 + + + + + true + + + + + + + + Are there any conditions for the reuse of the data? + + + State whether there are embargoes, licenses, commercial objectives or other conditions apply to the reuse of the data. +
+
+ 5.6 + + + + 5.6.1 + + + + + + + + + Are these conditions defined in a consortium agreement? + + + +
+
+ 5 + Making data available + + NWO expects data stemming from NOW funded research projects to be made openly available for reuse after the end of the project. Following the guidelines of the European Commission the general rule for NWO is: “as open as possible, as closed as necessary”. If there are good reasons not to make data openly available immediately after the project (or only after an embargo period) please motivate here. In addition it is advised to determine which conditions apply to obtain access to your data. Examples of this are agreements that will be made concerning methodology, publications, the access period, availability of data, the costs (handling fee), copyright aspects, etc. +
+
+
\ No newline at end of file diff --git a/dmp-dataset-templates/ScienceFoundationIrelandLuxembourgNationalResearchFund.xml b/dmp-dataset-templates/ScienceFoundationIrelandLuxembourgNationalResearchFund.xml new file mode 100644 index 000000000..3a7467e76 --- /dev/null +++ b/dmp-dataset-templates/ScienceFoundationIrelandLuxembourgNationalResearchFund.xml @@ -0,0 +1,1540 @@ + + + + + + + + + + +
+ +
+ + +
+ 1.1.1 + + + + 1.1.1.1 + + + + + + + + + Explain which methodologies or software will be used if new data are collected or produced. + + + +
+
+ 1.1.2 + + + + 1.1.2.1 + + + + + + + + + State any constraints on re-use of existing data if there are any. + + + +
+
+ 1.1.3 + + + + 1.1.3.1 + + + + + + + + + Explain how data provenance will be documented. + + + +
+
+ 1.1.4 + + + + 1.1.4.1 + + + + + + + + + Briefly state the reasons if the re-use of any existing data sources has been considered but discarded. + + + +
+
+ 1.1 + How will new data be collected or produced and/or how will existing data be re-used? + + +
+
+ + +
+ 1.2.1 + + + + 1.2.1.1 + + + + + + + + + + + + Give details on the kind of data: + + + +
+
+ 1.2.2 + + + + 1.2.2.1 + + + + + + + + + + + + Give details on the data format: + + + +
+
+ 1.2.3 + + + + 1.2.3.1 + + + + + + + + + Justify the use of certain formats. + For example, decisions may be based on staff +expertise within the host organisation, a +preference for open formats, standards +accepted by data repositories, widespread +usage within the research community, or on +the software or equipment that will be used. + Give preference to open and standard +formats as they facilitate sharing and +long-term re-use of data (several repositories +provide lists of such ‘preferred formats’). + +
+
+ 1.2.4 + + + + 1.2.4.1 + + + + + + + + + Give details on the volumes. + they can be expressed in storage space required (bytes), +and/or in numbers of objects, files, rows, and columns. + + +
+
+ 1.2 + What data (for example the kind, formats, and volumes), will be collected or produced? + + +
+
+ + 1 + Data Description And Collection Or Re-use Of Existing Data + + +
+
+ +
+ + +
+ 2.1.1 + + + + 2.1.1.1 + + + + + + + + + Indicate which metadata will be provided to help others identify and discover the data. + + + +
+
+ 2.1.2 + + + + 2.1.2.1 + + + + + + + + + + + + Indicate which metadata standards will be used. + Use community metadata standards where +these are in place + + +
+
+ 2.1.3 + + + + 2.1.3.1 + + + + + + + + + Indicate how the data will be organised during the project. + Mentioning for example +conventions, version control, and folder +structures. Consistent, well-ordered research +data will be easier to find, understand, and +re-use. + + +
+
+ 2.1.4 + + + + 2.1.4.1 + + + + + + + + + Consider what other documentation is needed to enable re-use. + This may include information on the methodology used to +collect the data, analytical and procedural +information, definitions of variables, units of +measurement, and so on. + + +
+
+ 2.1.5 + + + + 2.1.5.1 + + + + + + + + + Consider how this information will be captured and where it will be recorded. + + For example in a database with links to each +item, a ‘readme’ text file, file headers, code +books, or lab notebooks. + +
+
+ 2.1 + What metadata and documentation will accompany the data? + + For example the methodology of data collection and way of organizing data +
+
+ + +
+ 2.2.1 + + + + 2.2.1.1 + + + + + + + + + Explain how the consistency and quality of data collection will be controlled and documented + This may include processes +such as calibration, repeated samples or +measurements, standardised data capture, +data entry validation, peer review of data, or +representation with controlled vocabularies. + + +
+
+ 2.2 + What data quality control measures will be used? + + +
+
+ + 2 + Documentation And Data Quality + + +
+
+ +
+ + +
+ 3.1.1 + + + + 3.1.1.1 + + + + + + + + 3.1.1.2 + + + + + + + + + + + + Describe where the data will be stored and backed up during research activities and how often the backup will be performed. + It is recommended to store data in least at two separate locations. + Give preference to the use of robust, +managed storage with automatic backup, +such as provided by IT support services +of the home institution. Storing data on +laptops, stand-alone hard drives, or external +storage devices such as USB sticks is not +recommended. + +
+
+ 3.1 + How will data and metadata be stored and backed up during the research? + + +
+
+ + +
+ 3.2.1 + + + + 3.2.1.1 + + + + + + + + + Explain how the data will be recovered in the event of an incident. + + + +
+
+ 3.2.2 + + + + 3.2.2.1 + + + + + + + + + Explain who will have access to the data during the research and how access to data is controlled, especially in collaborative partnerships. + + + +
+
+ 3.2.3 + + + + 3.2.3.1 + + + + + + + + + Describe the main risks and how these will be managed. + Consider data protection, particularly +if your data is sensitive for example +containing personal data, politically sensitive +information, or trade secrets. + + +
+
+ 3.2.4 + + + + 3.2.4.1 + + + + + + + + + Explain which institutional data protection policies are in place. + + + +
+
+ 3.2 + How will data security and protection of sensitive data be taken care of during the research? + + +
+
+ + 3 + Storage And Backup During The Research Process + + +
+ +
+ +
+ + +
+ 5.1.1 + + + + 5.1.1.1 + + + + + + + + + Explain how the data will be discoverable. and shared + + For example by deposit in a +trustworthy data repository, indexed in a +catalogue, use of a secure data service, +direct handling of data requests, or use of +another mechanism. + +
+
+ 5.1.2 + + + + 5.1.2.1 + + + + + + + + + Outline the plan for data preservation and give information on how long the data will be retained. + + + +
+
+ 5.1.3 + + + + 5.1.3.1 + + + + + + + + + Explain when the data will be made available. + + + +
+
+ 5.1.4 + + + + 5.1.4.1 + + + + + + + + + Indicate the expected timely release. + + + +
+
+ 5.1.5 + + + + 5.1.5.1 + + + + + true + + + + + + + + Will exclusive use of the data be claimed? + + + +
+
+ 5.1.6 + + + + 5.1.6.1 + + + + + + + + 5.1.6.2 + + + + + + + + + For what reason and how long exclusive use will be claimed? + + + +
+
+ 5.1.7 + + + + 5.1.7.1 + + + + + + + + + + + 5.1.7.2 + + + + + + + + + Indicate whether data sharing will be postponed or restricted + + For example to +publish, protect intellectual property, or seek +patents. + +
+
+ 5.1.8 + + + + 5.1.8.1 + + + + + + + + + Indicate who will be able to use the data. + + + +
+
+ 5.1.9 + + + + 5.1.9.1 + + + + + true + + + true + + + + + + + + Is it necessary to restrict access to certain communities or to apply a data sharing agreement? + + + +
+
+ 5.1.10 + + + + 5.1.10.1 + + + + + + + + + Explain how and why. + + + +
+
+ 5.1.11 + + + + 5.1.11.1 + + + + + + + + + Explain what action will be taken to overcome or to minimise restrictions. + + + +
+
+ 5.1 + How and when will data be shared? Are there possible restrictions to data sharing or embargo reasons? + + +
+
+ + +
+ 5.2.1 + + + + 5.2.1.1 + + + + + + + + 5.2.1.2 + + + + + + + + + + + + Indicate what data must be retained or destroyed for contractual, legal, or regulatory purposes. + + + +
+
+ 5.2.2 + + + + 5.2.2.1 + + + + + + + + + Indicate how it will be decided what data to keep. + + + +
+
+ 5.2.3 + + + + 5.2.3.1 + + + + + + + + + Describe the data to be preserved long-term. + + + +
+
+ 5.2.4 + + + + 5.2.4.1 + + + + + + + + + Explain the foreseeable research uses (and/ or users) for the data. + + + +
+
+ 5.2.5 + + + + 5.2.5.1 + + + + + + + + + Indicate where the data will be deposited. + + + +
+
+ 5.2.6 + + + + 5.2.6.1 + + + + + false + + + + + + + + Will there be established repository proposed? + + + +
+
+ 5.2.7 + + + + 5.2.7.1 + + + + + + + + + Demonstrate that the data can be curated effectively beyond the lifetime of the grant. + It is recommended to demonstrate that the +repositories policies and procedures +(including any metadata standards, and +costs involved) have been checked. + + +
+
+ 5.2 + How will data for preservation be selected, and where data will be preserved long-term? + + For example a data repository or archive +
+
+ + +
+ 5.3.1 + + + + 5.3.1.1 + + + + + Another mechanism + + + + + + + + + + 5.3.1.2 + + + + + + + + + Indicate how the data will be shared. + + + +
+
+ 5.3.2 + + + + 5.3.2.1 + + + + + + + + + Indicate whether potential users need specific tools to access and (re-)use the data. + Consider the sustainability of software +needed for accessing the data. + + +
+
+ 5.3 + What methods or software tools are needed to access and use data? + + +
+
+ + +
+ 5.4.1 + + + + 5.4.1.1 + + + + + + + + + Explain how the data might be re-used in other contexts + Persistent identifiers should +be applied so that data can be reliably and +efficiently located and referred to. Persistent +identifiers also help to track citations and +re-use. + + +
+
+ 5.4.2 + + + + 5.4.2.1 + + + + + + + + + Indicate whether a persistent identifier for the data will be pursued + Typically, a +trustworthy, long-term repository will provide +a persistent identifier. + + +
+
+ 5.4 + How will the application of a unique and persistent identifier to each data set be ensured? + + Such as a Digital Object Identifier (DOI) +
+
+ + 5 + Data Sharing And Long-term Preservation + + +
+
+ +
+ + +
+ 6.1.1 + + + + 6.1.1.1 + + + + + + + + 6.1.1.2 + + + + + + + + + Outline the roles and responsibilities for data management/stewardship activities. + Name responsible individual(s) where possible. + For example data capture, metadata production, +data quality, storage and backup, data +archiving, and data sharing. + +
+
+ 6.1.2 + + + + 6.1.2.1 + + + + + true + + + + + + + + Is it a collaborative project + + + +
+
+ 6.1.3 + + + + 6.1.3.1 + + + + + + + + + Explain the co-ordination of data management responsibilities across partners + + + +
+
+ 6.1.4 + + + + 6.1.4.1 + + + + + + + + + Indicate who is responsible for implementing the DMP, and for ensuring it is reviewed and, if necessary, revised. + + Consider regular updates of the DMP + +
+
+ 6.1 + Who will be responsible for data management? + + For example role, position, and institution. i.e. the data steward +
+
+ + +
+ 6.2.1 + + + + 6.2.1.1 + + + + + + + + + Explain how the necessary resources (for example time) to prepare the data for sharing/preservation (data curation) have been costed in. + Carefully consider and justify +any resources needed to deliver the data. +These may include storage costs, hardware, +staff time, costs of preparing data for +deposit, and repository charges. + + +
+
+ 6.2.2 + + + + 6.2.2.1 + + + + + true + + + + + + + + Indicate whether additional resources will be needed to prepare data for deposit or to meet any charges from data repositories + + + +
+
+ 6.2.3 + + + + 6.2.3.1 + + + + + + + + + Explain how much is needed and how such costs will be covered. + + + +
+
+ 6.2 + What resources will be dedicated to data management and ensuring that data will be FAIR (Findable, Accessible, Interoperable, Re-usable)? + + For example financial and time +
+
+ + 6 + Data Management Responsibilities And Resources + + +
+
+
\ No newline at end of file diff --git a/dmp-dataset-templates/SwedishResearchCouncil.xml b/dmp-dataset-templates/SwedishResearchCouncil.xml new file mode 100644 index 000000000..d3d7879d5 --- /dev/null +++ b/dmp-dataset-templates/SwedishResearchCouncil.xml @@ -0,0 +1 @@ +
1.1.11.1.1.1What is the purpose of the data collection/generation and its relation to the objectives of the project?
1.1.21.1.2.1What is the origin of the data?
1.1How will data be collected, created or reused?
1.2.11.2.1.11.2.1.21.2.1.31.2.1.4What types of data will be created and/or collected, in terms of data format and amount/volume of data?
1.2What types of data will be created and/or collected, in terms of data format and amount/volume of data?
1Description of data – reuse of existing data and/or production of new data
2.1.12.1.1.1truetruetrue2.1.1.22.1.1.3trueWill you use metadata to describe the data?
2.1.22.1.2.12.1.2.2URL/Location
2.1.32.1.3.1truetrue2.1.3.22.1.3.3trueWill your metadata use standardised vocabularies?
2.1.42.1.4.12.1.4.2URL/Description
2.1.52.1.5.1true Will you provide searchable metadata for your data?
2.1.62.1.6.12.1.6.2trueWhat services will you use to provide searchable metadata?
2.1.72.1.7.12.1.7.2URL/Name
2.1How will the material be documented and described, with associated metadata relating to structure, standards and format for descriptions of the content, collection method, etc.?
2.2.12.2.1.1How will data quality be safeguarded and documented (for example repeated measurements, validation of data input, etc.)?
2.2How will data quality be safeguarded and documented (for example repeated measurements, validation of data input, etc.)?
2Documentation and data quality
3.1.13.1.1.1 Is the storage sufficiently secure for the data and does the storage provide backup and recovery procedures?
3.1How is storage and backup of data and metadata safeguarded during the research process?
3.2.13.2.1.1How is data security and controlled access to data safeguarded, in relation to the handling of sensitive data and personal data, for example?
3.2.23.2.2.1keptoninsecureWhat do you plan to do with research data of limited use?
3.2.33.2.3.1Please describe why the data will be kept on insecure, unmanaged storage
3.2How is data security and controlled access to data safeguarded, in relation to the handling of sensitive data and personal data, for example?
3Storage and backup
5.1.15.1.1.1somenoneWill all your data be openly accessible?
5.1.25.1.2.15.1.2.25.1.2.3Data type/ Reason/ URL
5.1.35.1.3.15.1.3.25.1.3.3Data type/ Reason/ URL
5.1How, when and where will research data or information about data (metadata) be made accessible? Are there any conditions, embargoes and limitations on the access to and reuse of data to be considered?
5.2.15.2.1.15.2.1.2In what way is long-term storage safeguarded, and by whom?
5.2.25.2.2.1How will the selection of data for long-term storage be made?
5.2In what way is long-term storage safeguarded, and by whom? How will the selection of data for long-term storage be made?
5.3.15.3.1.1truetrueAre there any methods or tools required to access the data?
5.3.25.3.2.15.3.2.2Please provide links describing the methods for accessing the data.
5.3.35.3.3.15.3.3.2Please provide links describing the tools for accessing the data.
5.3.45.3.4.1forsomedatafornodataDo supported open-source tools exist for accessing the data?
5.3.55.3.5.1Please describe which data require proprietary tools to access the data?
5.3.65.3.6.1Please describe which data require proprietary tools to access the data?
5.3Will specific systems, software, source code or other types of services be necessary in order to understand, partake of or use/analyse data in the long term?
5.4.15.4.1.1Persistent identifiersSelect a persistent identifier (PID) from the list. You may select multiple PIDs according to the types of research outputs, needs and the area of your research.
5.4How will the use of unique and persistent identifiers, such as a Digital Object Identifier (DOI), be safeguarded?
5Accessibility and long-term storage
6.1.16.1.1.1falseWill you identify a data manager to manage your data, if not who will be responsible for the management of your data?
6.1.26.1.2.1 Identify the people or roles that will be responsible for the management of the project data.
6.1Who is responsible for data management and (possibly) supports the work with this while the research project is in progress? Who is responsible for data management, ongoing management and long-term storage after the research project has ended?
6.2.16.2.1.1What resources (costs, labour input or other) will be required for data management (including storage, back-up, provision of access and processing for long-term storage)?
6.2.26.2.2.1What resources will be needed to ensure that data fulfill the FAIR (findable, accessible, interoperable and reusable) principles?
6.2What resources (costs, labour input or other) will be required for data management (including storage, back-up, provision of access and processing for long-term storage)? What resources will be needed to ensure that data fulfil the FAIR principles?
6Responsibility and resources
\ No newline at end of file diff --git a/dmp-dataset-templates/TheResearchCouncilOfNorway.xml b/dmp-dataset-templates/TheResearchCouncilOfNorway.xml new file mode 100644 index 000000000..7170ca130 --- /dev/null +++ b/dmp-dataset-templates/TheResearchCouncilOfNorway.xml @@ -0,0 +1,293 @@ + + + + + + + +
+ +
+ + +
+ 1.1.1 + + + + 1.1.1.1 + + + + + + + + + What is the purpose of the data collection/generation and its relation to the objectives of the project? + + + +
+
+ 1.1.2 + + + + 1.1.2.1 + + + + + + + + + What types and formats of data will the project generate/collect? + + + +
+
+ 1.1.3 + + + + 1.1.3.1 + + + + + + + + + What is the origin of the data? + + + +
+
+ 1.1 + The kind of data that will be generated + + +
+
+ + +
+ 1.2.1 + + + + 1.2.1.1 + + + + + true + + + true + + + + + + + 1.2.1.2 + + + + + + + + + 1.2.1.3 + + + + + true + + + + + + + + Will you use metadata to describe the data? + + + +
+
+ 1.2.2 + + + + 1.2.2.1 + + + + + + + + 1.2.2.2 + + + + + + + + + URL/Location + + + +
+
+ 1.2 + How the data will be described + + +
+
+ + 1 + Data Origin and Description + + +
+
+ + +
+ 2.1 + + + + 2.1.1 + + + + + + + + + Where the data will be stored + + + +
+
+ 2 + Storage and Backup + + +
+
+ +
+ + +
+ 3.1.1 + + + + 3.1.1.1 + + + + + + + + + Are there ethical or legal issues that can impact sharing the data? + + + +
+
+ 3.1.2 + + + + 3.1.2.1 + + + + + + + + + 3.1.2.2 + + + + + true + + + + + + + + How will the data be made available? + + + +
+
+ 3.1.3 + + + + 3.1.3.1 + + + + + + + + 3.1.3.2 + + + + + + + + + URL/Name + + + +
+
+ 3.1 + Whether and how the data can be shared + + +
+
+ + 3 + Data Sharing and Long-term Preservation + + +
+
+
\ No newline at end of file diff --git a/dmp-dataset-templates/UKResearchInnovation.xml b/dmp-dataset-templates/UKResearchInnovation.xml new file mode 100644 index 000000000..2d0953e0e --- /dev/null +++ b/dmp-dataset-templates/UKResearchInnovation.xml @@ -0,0 +1 @@ +
1.1.11.1.1.1What is the purpose of the data collection/generation and its relation to the objectives of the project?Up to three lines of text that summarise the type of study (or studies) for which the data are being collected.
1.1Type of study
1.2.11.2.1.1What is the origin of the data?Types of data to be managed in the following terms: quantitative, qualitative; generated from surveys, clinical measurements, interviews, medical records, electronic health records, administrative records, genotypic data, images, tissue samples...
1.2Types of data
1.3.11.3.1.1What types and formats of data will the project generate/collect?File formats, software used, number of records, databases, sweeps, repetitions… (in terms that are meaningful in your field). Do formats and software enable sharing and long-term validity of data?
1.3Format and scale of the data
1Description of the data
2.1.12.1.1.1What internationally recognised licence will you use for your data?
2.1.22.1.2.1trueWill you use naming conventions for your data?
2.1.32.1.3.12.1.3.2URL/Name
2.1Methodologies for data collection / generationHow the data will be collected/generated and which community data standards (if any) will be used at this stage.
2.2.12.2.1.1truetrue2.2.1.22.2.1.3trueWill you use standardised vocabularies?
2.2.22.2.2.12.2.2.2URL/Description
2.2.32.2.3.1truefalseWill you use standardised formats for some or all of your data?
2.2.42.2.4.12.2.4.2trueWhich standardised data formats do you plan on using?
2.2.52.2.5.12.2.5.2Standardised formatsIs the structure of the file(s) provided in a standardised format?
2.2.62.2.6.12.2.6.22.2.6.3Please describe the formats you plan to store your data in, including any URLs to documentation.
2.2.72.2.7.1Will you provide metadata describing the quality of the data?
2.2Data quality and standardsHow consistency and quality of data collection / generation will be controlled and documented, through processes of calibration, repeat samples or measurements, standardised data capture or recording, data entry validation, peer review of data or representation with controlled vocabularies.
2Data collection / generationMake sure you justify why new data collection or long term management is needed in your Case for Support. Focus in this template on the good practice and standards for ensuring new data are of high quality and processing is well documented
3.1.13.1.1.1Briefly describe how data will be stored, backed-up, managed and curated in the short to medium term. Specify any community agreed or other formal data standards used (with URL references).
3.1Managing, storing and curating data
3.2.13.2.1.1truetruetrue3.2.1.23.2.1.3trueWill you use metadata to describe the data?
3.2.23.2.2.13.2.2.2URL/Location
3.2.33.2.3.1Will your metadata be harvestable?
3.2Metadata standards and data documentationWhat metadata is produced about the data generated from the research/innovation? For example, descriptions of data that enable research/innovation data to be used by others outside of your own team. This may include documenting the methods used to generate the data, analytical and procedural information, capturing instrument metadata alongside data, documenting provenance of data and their coding, detailed descriptions for variables, records,etc.
3.3Data preservation strategy and standards
3Data management, documentation and curation
4.1.14.1.1.1truefalse4.1.1.2If your organisation is ISO compliant? If yes, please state the registration number.
4.1.24.1.2.1Identify formal information standards with which your study is or will be compliant.
4.1Formal information/data security standards
4.2.14.2.1.1keptoninsecureWhat do you plan to do with research data of limited use
4.2.24.2.2.1Please describe why the data will be kept on insecure, unmanaged storage
4.2Main risks to data securityAll personal data has an element of risk. Summarise the main risks to the confidentiality and security of information related to human participants, the level of risk and how these risks will be managed. Cover the main processes or facilities for storage and processing of personal data, data access, with controls put in place and any auditing of user compliance with consent and security conditions. It is not sufficient to write not applicable under this heading
4Data security and confidentiality of potentially disclosive informationThis section MUST be completed if your data includes personal data relating to human participants. For other research/innovation, the safeguarding and security of data should also be considered. Information provided will be in line with your ethical review. Please note this section concerns protecting the data, not the patients.
5.1.15.1.1.15.1.1.25.1.1.3trueHow will the data be made available?Identify any data repository (-ies) that are, or will be, entrusted with storing, curating and/or sharing data from your study, where they exist for particular disciplinary domains or data types.
5.1.25.1.2.15.1.2.2URL/Name
5.1.35.1.3.1somenoneWill all your data be openly accessible?Is the data you propose to collect (or existing data you propose to use) in the study suitable for sharing? If yes, briefly state why it is suitable. If No, indicate why the data will not be suitable for sharing and then go to Section 6.
5.1.45.1.4.15.1.4.25.1.4.3Data type/ Reason/ URL
5.1.55.1.5.15.1.5.25.1.5.3Data type/ Reason/ URL
5.1Suitability for sharing
5.2.15.2.1.1As part of the consent process, proposed procedures for data sharing should be set out clearly and current and potential future risks associated with this explained to participants.
5.2Restrictions or delays to sharing, with planned actions to limit such restrictionsRestriction to data sharing may be due to participant confidentiality, consent agreements or IPR. Strategies to limit restrictions may include data being anonymised or aggregated; gaining participant consent for data sharing; gaining copyright permissions. For prospective studies, consent procedures should include provision for data sharing to maximise the value of the data for wider research/innovation use, while providing adequate safeguards for participants.
5.3.15.3.1.1truetrueAre there any methods or tools required to access the data?
5.3.25.3.2.15.3.2.2Please provide links describing the methods for accessing the data.
5.3.35.3.3.15.3.3.2Please provide links describing the tools for accessing the data.
5.3.45.3.4.1How widely accessible is this depository? Indicate whether your policy or approach to data sharing is (or will be) published on your study website (or by other means).
5.3Discovery by potential users of the research/innovation dataIndicate how potential new users (outside of your organisation) can find out about your data and identify whether it could be suitable for their research/innovation purposes, e.g. through summary information (metadata) being readily available on the study website or in databases or catalogues.
5.4.15.4.1.1falseWill you identify a data manager to manage your data, if not who will be responsible for the management of your data?
5.4.25.4.2.1Identify the people or roles that will be responsible for the management of the project data
5.4Governance of accessIdentify who makes or will make the decision on whether to supply the data to a potential new user. Indicate whether the data will be deposited in and available from an identified community database, repository, archive or other infrastructure established to curate and share data.
5.5.15.5.1.1What are the timescale/dependencies for when data will be accessible to others outside of your team?Summarize the principles of your current/intended policy.
5.5The study team’s exclusive use of the dataUKRI’s requirement is for timely data sharing, with the understanding that a limited, defined period of exclusive use of data for primary research/innovation is reasonable according to the nature and value of the data, and that this restriction on sharing should be based on simple, clear principles.
5.6.15.6.1.1Indicate whether external users are (will be) bound by data sharing agreements, setting out their main responsibilities.
5.6Regulation of responsibilities of users
5Data sharing and access
6.16.1.16.1.2Apart from the PI, who is responsible at your organisation/within your consortia for
6Responsibilities
7.17.1.1Complete, policies which are relevant to your study, and are in the public domain, e.g. accessible through the internet. (Data Management Policy & Procedures, Data Security Policy, Data Sharing Policy, Institutional Information Policy)
7Relevant institutional, departmental or study policies on data sharing and data security
8.18.1.1falsetrue8.1.2Is Author of this Data Management Plan different to that of the Principal Investigator?
8.28.2.18.2.28.2.3Author of this Data Management Plan details
8Author of this Data Management Plan (Name) and, if different to that of the Principal Investigator, their telephone & email contact details
\ No newline at end of file diff --git a/dmp-db-scema/updates/04/Add_creationUser_on_DataRepository_ExternalDataset_Registry_Service.sql b/dmp-db-scema/updates/04/Add_creationUser_on_DataRepository_ExternalDataset_Registry_Service.sql new file mode 100644 index 000000000..4cc036bdb --- /dev/null +++ b/dmp-db-scema/updates/04/Add_creationUser_on_DataRepository_ExternalDataset_Registry_Service.sql @@ -0,0 +1,11 @@ +ALTER TABLE "DataRepository" +ADD COLUMN "CreationUser" uuid + +ALTER TABLE "ExternalDataset" +ADD COLUMN "CreationUser" uuid + +ALTER TABLE "Registry" +ADD COLUMN "CreationUser" uuid + +ALTER TABLE "Service" +ADD COLUMN "CreationUser" uuid \ No newline at end of file diff --git a/dmp-db-scema/updates/04/Funder_add_column_CreationUser.sql b/dmp-db-scema/updates/04/Funder_add_column_CreationUser.sql new file mode 100644 index 000000000..7c84eb69f --- /dev/null +++ b/dmp-db-scema/updates/04/Funder_add_column_CreationUser.sql @@ -0,0 +1,2 @@ +ALTER TABLE "Funder" +ADD COLUMN "CreationUser" uuid \ No newline at end of file diff --git a/dmp-db-scema/updates/04/Funder_update_CreationUser_values.sql b/dmp-db-scema/updates/04/Funder_update_CreationUser_values.sql new file mode 100644 index 000000000..130130ab9 --- /dev/null +++ b/dmp-db-scema/updates/04/Funder_update_CreationUser_values.sql @@ -0,0 +1,4 @@ +Update "Funder" as funder + set "CreationUser" = grant1."CreationUser" + from "Grant" as grant1 + where funder."ID" = grant1."Funder" \ No newline at end of file diff --git a/dmp-db-scema/updates/04/Researcher_add_column_CreationUser.sql b/dmp-db-scema/updates/04/Researcher_add_column_CreationUser.sql new file mode 100644 index 000000000..55b7a4542 --- /dev/null +++ b/dmp-db-scema/updates/04/Researcher_add_column_CreationUser.sql @@ -0,0 +1,2 @@ +ALTER TABLE "Researcher" +ADD COLUMN "CreationUser" uuid \ No newline at end of file diff --git a/dmp-db-scema/updates/05/External_References_Reference_Prefix_Update.sql b/dmp-db-scema/updates/05/External_References_Reference_Prefix_Update.sql new file mode 100644 index 000000000..615ebb4c9 --- /dev/null +++ b/dmp-db-scema/updates/05/External_References_Reference_Prefix_Update.sql @@ -0,0 +1,31 @@ +-- Registry Update Script +UPDATE public."Registry" +SET "Reference" = REPLACE("Reference", 'dmpdata/', 'dmp:') +WHERE "Reference" LIKE 'dmpdata/%'; + +-- Service Update Script +UPDATE public."Service" +SET "Reference" = REPLACE("Reference", 'dmpdata/', 'dmp:') +WHERE "Reference" LIKE 'dmpdata/%'; +UPDATE public."Service" +SET "Reference" = REPLACE("Reference", 'innerdata/', 'dmp:') +WHERE "Reference" LIKE 'innerdata/%'; + +-- DataRepository +UPDATE public."DataRepository" +SET "Reference" = REPLACE("Reference", 'dmpdata/', 'dmp:') +where "Reference" like 'dmpdata/%'; +UPDATE public."DataRepository" +SET "Reference" = CONCAT('re3data:', "Reference") +where "Reference" LIKE '%:re3data%'; +UPDATE public."DataRepository" +SET "Reference" = CONCAT('dmp:', "Reference") +where "Reference" LIKE '%:internal%'; +UPDATE public."DataRepository" +SET "Reference" = CONCAT('eestore:', "Reference") +where "Reference" LIKE '%:eestore%'; + +-- ExternalDataset +UPDATE public."ExternalDataset" +SET "Reference" = REPLACE("Reference", 'dmpdata/', 'dmp:') +WHERE "Reference" LIKE 'dmpdata/%'; \ No newline at end of file diff --git a/dmp-db-scema/updates/05/Grant_Funder_Project_Reference_Prefix_Update.sql b/dmp-db-scema/updates/05/Grant_Funder_Project_Reference_Prefix_Update.sql new file mode 100644 index 000000000..bb1e529fe --- /dev/null +++ b/dmp-db-scema/updates/05/Grant_Funder_Project_Reference_Prefix_Update.sql @@ -0,0 +1,26 @@ +-- Grant +UPDATE public."Grant" +SET "Reference" = CONCAT('cristin:', "Reference") +WHERE "Reference" LIKE '%cristin/%'; +UPDATE public."Grant" +SET "Reference" = CONCAT('OpenAIRE:', "Reference") +where "Reference" like '%_________::%' and +"Reference" not like 'OpenAIRE:%'; + +-- Funder +UPDATE public."Funder" +SET "Reference" = CONCAT('cristin:', "Reference") +WHERE "Reference" LIKE '%cristin/%'; +UPDATE public."Funder" +SET "Reference" = CONCAT('openaire:', "Reference") +WHERE "Reference" LIKE '%_________::%' and +upper("Reference") NOT LIKE upper('openAIRE:%'); + +-- Project +UPDATE public."Project" +SET "Reference" = CONCAT('cristin:', "Reference") +WHERE "Reference" LIKE '%cristin/%'; +UPDATE public."Project" +SET "Reference" = CONCAT('openaire:', "Reference") +WHERE "Reference" LIKE '%_________::%' and +upper("Reference") NOT LIKE upper('openAIRE:%'); \ No newline at end of file diff --git a/dmp-frontend/angular.json b/dmp-frontend/angular.json index 1ccca7310..6de6bf84c 100644 --- a/dmp-frontend/angular.json +++ b/dmp-frontend/angular.json @@ -23,9 +23,12 @@ "styles": [ "src/styles.scss", "src/assets/scss/material-dashboard.scss", - "src/assets/css/demo.css" + "src/assets/css/demo.css", + "node_modules/cookieconsent/build/cookieconsent.min.css" ], - "scripts": [] + "scripts": [ + "node_modules/cookieconsent/build/cookieconsent.min.js" + ] }, "configurations": { "production": { diff --git a/dmp-frontend/browserslist b/dmp-frontend/browserslist new file mode 100644 index 000000000..80848532e --- /dev/null +++ b/dmp-frontend/browserslist @@ -0,0 +1,12 @@ +# This file is used by the build system to adjust CSS and JS output to support the specified browsers below. +# For additional information regarding the format and rule options, please see: +# https://github.com/browserslist/browserslist#queries + +# You can see what browsers were selected by your queries by running: +# npx browserslist + +> 0.5% +last 2 versions +Firefox ESR +not dead +not IE 9-11 # For IE 9-11 support, remove 'not'. \ No newline at end of file diff --git a/dmp-frontend/package.json b/dmp-frontend/package.json index 8b88cd0a1..cc6e1ab8a 100644 --- a/dmp-frontend/package.json +++ b/dmp-frontend/package.json @@ -1,63 +1,61 @@ { - "name": "dmp-frontend2", - "version": "0.0.0", - "license": "MIT", - "scripts": { - "ng": "ng", - "start": "ng serve", - "build": "ng build --prod", - "test": "ng test", - "lint": "ng lint", - "e2e": "ng e2e" - }, - "private": true, - "dependencies": { - "@angular/animations": "^6.1.7", - "@angular/common": "^6.1.7", - "@angular/compiler": "^6.1.7", - "@angular/core": "^6.1.7", - "@angular/flex-layout": "6.0.0-beta.18", - "@angular/forms": "^6.1.7", - "@angular/material-moment-adapter": "^6.4.7", - "@angular/platform-browser": "^6.1.7", - "@ngx-translate/core": "^10.0.2", - "@ngx-translate/http-loader": "^3.0.1", - "@swimlane/ngx-datatable": "^13.1.0", - "bootstrap": "^4.1.3", - "core-js": "^2.5.5", - "file-saver": "^2.0.0-rc.3", - "moment": "^2.22.2", - "moment-timezone": "^0.5.23", - "ngx-cookie-service": "^1.0.10", - "rxjs": "^6.3.2", - "rxjs-compat": "^6.3.2", - "web-animations-js": "^2.3.1", - "zone.js": "^0.8.26" - }, - "devDependencies": { - "@angular-devkit/build-angular": "^0.8.5", - "@angular/cdk": "^6.3.0", - "@angular/material": "^6.4.7", - "@angular/cli": "6.2.5", - "@angular/compiler-cli": "^6.1.10", - "@angular/http": "^6.1.10", - "@angular/platform-browser-dynamic": "^6.1.10", - "@angular/router": "^6.1.10", - "@angular/language-service": "^6.1.10", - "@types/facebook-js-sdk": "^2.8.4", - "@types/file-saver": "^1.3.1", - "@types/gapi": "^0.0.36", - "@types/gapi.auth2": "^0.0.47", - "@types/jasmine": "~2.8.9", - "@types/jasminewd2": "~2.0.5", - "@types/moment-timezone": "^0.5.4", - "@types/node": "^10.11.7", - "codelyzer": "~4.5.0", - "jasmine-core": "^3.2.1", - "jasmine-spec-reporter": "^4.2.1", - "protractor": "~5.4.1", - "ts-node": "~7.0.1", - "tslint": "~5.11.0", - "typescript": "2.9.1" - } + "name": "dmp-frontend2", + "version": "0.0.0", + "license": "MIT", + "scripts": { + "ng": "ng", + "start": "ng serve", + "build": "ng build --prod", + "test": "ng test", + "lint": "ng lint", + "e2e": "ng e2e" + }, + "private": true, + "dependencies": { + "@angular/animations": "^8.2.7", + "@angular/common": "^8.2.7", + "@angular/compiler": "^8.2.7", + "@angular/core": "^8.2.7", + "@angular/forms": "^8.2.7", + "@angular/material-moment-adapter": "^8.2.0", + "@angular/platform-browser": "^8.2.7", + "@ngx-translate/core": "^11.0.1", + "@ngx-translate/http-loader": "^4.0.0", + "@swimlane/ngx-datatable": "^16.0.2", + "@w11k/angular-sticky-things": "^1.1.2", + "bootstrap": "^4.3.1", + "cookieconsent": "^3.1.1", + "core-js": "^2.5.5", + "file-saver": "^2.0.2", + "moment": "^2.24.0", + "moment-timezone": "^0.5.26", + "ngx-cookie-service": "^2.2.0", + "ngx-cookieconsent": "^2.2.3", + "rxjs": "^6.3.2", + "tslib": "^1.10.0", + "web-animations-js": "^2.3.2", + "zone.js": "~0.9.1" + }, + "devDependencies": { + "@angular-devkit/build-angular": "~0.803.5", + "@angular/cdk": "^8.2.0", + "@angular/material": "^8.2.0", + "@angular/cli": "8.3.5", + "@angular/compiler-cli": "^8.2.7", + "@angular/platform-browser-dynamic": "^8.2.7", + "@angular/router": "^8.2.7", + "@angular/language-service": "^8.2.7", + "@types/facebook-js-sdk": "^3.3.0", + "@types/file-saver": "^2.0.1", + "@types/gapi": "^0.0.39", + "@types/gapi.auth2": "^0.0.50", + "@types/jasmine": "~3.4.0", + "@types/jasminewd2": "~2.0.6", + "@types/moment-timezone": "^0.5.12", + "@types/node": "^10.11.7", + "codelyzer": "^5.1.1", + "ts-node": "~8.4.1", + "tslint": "~5.20.0", + "typescript": "3.5.3" + } } diff --git a/dmp-frontend/src/app/app-routing.module.ts b/dmp-frontend/src/app/app-routing.module.ts index 6e0f16745..9ba283c4d 100644 --- a/dmp-frontend/src/app/app-routing.module.ts +++ b/dmp-frontend/src/app/app-routing.module.ts @@ -14,7 +14,7 @@ const appRoutes: Routes = [ }, { path: 'datasetcreatewizard', - loadChildren: './ui/dataset-create-wizard/dataset-create-wizard.module#DatasetCreateWizardModule', + loadChildren: () => import('./ui/dataset-create-wizard/dataset-create-wizard.module').then(m => m.DatasetCreateWizardModule), data: { breadcrumb: true, title: 'GENERAL.TITLES.DATASETCREATEWIZARD' @@ -22,7 +22,7 @@ const appRoutes: Routes = [ }, { path: 'explore', - loadChildren: './ui/explore-dataset/explore-dataset.module#ExploreDatasetModule', + loadChildren: () => import('./ui/explore-dataset/explore-dataset.module').then(m => m.ExploreDatasetModule), data: { breadcrumb: true, title: 'GENERAL.TITLES.EXPLORE' @@ -30,7 +30,7 @@ const appRoutes: Routes = [ }, { path: 'explore-plans', - loadChildren: './ui/explore-dmp/explore-dmp.module#ExploreDmpModule', + loadChildren: () => import('./ui/explore-dmp/explore-dmp.module').then(m => m.ExploreDmpModule), data: { breadcrumb: true, title: 'GENERAL.TITLES.EXPLORE-PLANS' @@ -38,7 +38,7 @@ const appRoutes: Routes = [ }, { path: 'datasets', - loadChildren: './ui/dataset/dataset.module#DatasetModule', + loadChildren: () => import('./ui/dataset/dataset.module').then(m => m.DatasetModule), data: { breadcrumb: true, title: 'GENERAL.TITLES.DATASETS' @@ -46,23 +46,24 @@ const appRoutes: Routes = [ }, { path: 'about', - loadChildren: './ui/about/about.module#AboutModule', + loadChildren: () => import('./ui/about/about.module').then(m => m.AboutModule), data: { breadcrumb: true, title: 'GENERAL.TITLES.ABOUT' } }, - { - path: 'grants', - loadChildren: './ui/grant/grant.module#GrantModule', - data: { - breadcrumb: true, - title: 'GENERAL.TITLES.GRANTS' - } - }, + // ----------- UNCOMMENT TO ADD AGAIN GRANTS -------- + // { + // path: 'grants', + // loadChildren: () => import('./ui/grant/grant.module').then(m => m.GrantModule), + // data: { + // breadcrumb: true, + // title: 'GENERAL.TITLES.GRANTS' + // } + // }, { path: 'plans', - loadChildren: './ui/dmp/dmp.module#DmpModule', + loadChildren: () => import('./ui/dmp/dmp.module').then(m => m.DmpModule), data: { breadcrumb: true, title: 'GENERAL.TITLES.PLANS' @@ -70,7 +71,7 @@ const appRoutes: Routes = [ }, { path: 'dmp-profiles', - loadChildren: './ui/admin/dmp-profile/dmp-profile.module#DmpProfileModule', + loadChildren: () => import('./ui/admin/dmp-profile/dmp-profile.module').then(m => m.DmpProfileModule), data: { breadcrumb: true, title: 'GENERAL.TITLES.DMP-PROFILES' @@ -78,7 +79,7 @@ const appRoutes: Routes = [ }, { path: 'quick-wizard', - loadChildren: './ui/quick-wizard/quick-wizard.module#OuickWizardModule', + loadChildren: () => import('./ui/quick-wizard/quick-wizard.module').then(m => m.OuickWizardModule), data: { breadcrumb: true, title: "GENERAL.TITLES.QUICK-WIZARD" @@ -86,29 +87,69 @@ const appRoutes: Routes = [ }, { path: 'dataset-profiles', - loadChildren: './ui/admin/dataset-profile/dataset-profile.module#DatasetProfileModule', + loadChildren: () => import('./ui/admin/dataset-profile/dataset-profile.module').then(m => m.DatasetProfileModule), data: { breadcrumb: true, title: 'GENERAL.TITLES.DATASET-PROFILES' } }, + { + path: 'contact-support', + loadChildren: () => import('./ui/contact/contact.module').then(m => m.ContactModule), + data: { + breadcrumb: true, + title: 'CONTACT.SUPPORT.TITLE' + } + }, + { + path: 'glossary', + loadChildren: () => import('./ui/glossary/glossary.module').then(m => m.GlossaryModule), + data: { + breadcrumb: true, + title: 'GLOSSARY.TITLE' + } + }, + { + path: 'faq', + loadChildren: () => import('./ui/faq/faq.module').then(m => m.FaqModule), + data: { + breadcrumb: true, + title: 'FAQ.TITLE' + } + }, + { + path: 'privacy-policy', + loadChildren: () => import('./ui/sidebar/sidebar-footer/privacy/privacy.module').then(m => m.PrivacyModule), + data: { + breadcrumb: true, + title: 'GENERAL.TITLES.PRIVACY' + } + }, + { + path: 'terms-of-service', + loadChildren: () => import('./ui/sidebar/sidebar-footer/terms/terms.module').then(m => m.TermsModule), + data: { + breadcrumb: true, + title: 'GENERAL.TITLES.TERMS' + } + }, { path: 'home', - loadChildren: './ui/dashboard/dashboard.module#DashboardModule', + loadChildren: () => import('./ui/dashboard/dashboard.module').then(m => m.DashboardModule), data: { breadcrumb: true } }, { path: 'unauthorized', - loadChildren: './ui/misc/unauthorized/unauthorized.module#UnauthorizedModule', + loadChildren: () => import('./ui/misc/unauthorized/unauthorized.module').then(m => m.UnauthorizedModule), data: { breadcrumb: true }, }, { path: 'users', - loadChildren: './ui/admin/user/user.module#UserModule', + loadChildren: () => import('./ui/admin/user/user.module').then(m => m.UserModule), data: { breadcrumb: true, title: 'GENERAL.TITLES.USERS' @@ -116,7 +157,7 @@ const appRoutes: Routes = [ }, { path: 'profile', - loadChildren: './ui/user-profile/user-profile.module#UserProfileModule', + loadChildren: () => import('./ui/user-profile/user-profile.module').then(m => m.UserProfileModule), data: { breadcrumb: true, title: 'GENERAL.TITLES.PROFILE' @@ -124,14 +165,14 @@ const appRoutes: Routes = [ }, { path: 'login/admin', - loadChildren: './ui/auth/admin-login/admin-login.module#AdminLoginModule', + loadChildren: () => import('./ui/auth/admin-login/admin-login.module').then(m => m.AdminLoginModule), data: { breadcrumb: true }, }, { path: 'login', - loadChildren: './ui/auth/login/login.module#LoginModule', + loadChildren: () => import('./ui/auth/login/login.module').then(m => m.LoginModule), data: { breadcrumb: true, title: 'GENERAL.TITLES.LOGIN' diff --git a/dmp-frontend/src/app/app.component.scss b/dmp-frontend/src/app/app.component.scss index 634a06f22..51ca45e9b 100644 --- a/dmp-frontend/src/app/app.component.scss +++ b/dmp-frontend/src/app/app.component.scss @@ -1,17 +1,21 @@ .fixed { - position: fixed; - top: 0; - /* Sets the sticky toolbar to be on top */ - z-index: 1000; - width: 100%; + position: fixed; + top: 0; + /* Sets the sticky toolbar to be on top */ + z-index: 1000; + width: 100%; } .main-container { - margin-top: 64px; - padding-top: 10px; + margin-top: 64px; + padding-top: 10px; } .sidebar-shadow { - box-shadow: 0 4px 18px 0px rgba(0, 0, 0, 0.12), 0 7px 10px -5px rgba(0, 0, 0, 0.15); - z-index: 100; + box-shadow: 0 4px 18px 0px rgba(0, 0, 0, 0.12), 0 7px 10px -5px rgba(0, 0, 0, 0.15); + z-index: 100; +} + +::ng-deep .mat-chip { + height: auto !important; } diff --git a/dmp-frontend/src/app/app.component.ts b/dmp-frontend/src/app/app.component.ts index 4c0a5ade9..013a2c0f5 100644 --- a/dmp-frontend/src/app/app.component.ts +++ b/dmp-frontend/src/app/app.component.ts @@ -1,13 +1,17 @@ + +import { of as observableOf, Subscription } from 'rxjs'; + +import { switchMap, filter, map } from 'rxjs/operators'; import { Component, OnInit } from '@angular/core'; import { ActivatedRoute, NavigationEnd, Router } from '@angular/router'; import { TranslateService } from '@ngx-translate/core'; -import { Observable } from 'rxjs'; import { environment } from '../environments/environment'; import { AuthService } from './core/services/auth/auth.service'; import { CultureService } from './core/services/culture/culture-service'; import { BreadCrumbResolverService } from './ui/misc/breadcrumb/service/breadcrumb.service'; -import { filter, map } from 'rxjs/operators'; import { Title } from '@angular/platform-browser'; +import { NgcCookieConsentService, NgcStatusChangeEvent } from "ngx-cookieconsent"; +import { CookieService } from "ngx-cookie-service"; declare const gapi: any; @@ -20,9 +24,10 @@ declare var $: any; }) export class AppComponent implements OnInit { - hasBreadCrumb = Observable.of(false); + hasBreadCrumb = observableOf(false); sideNavOpen = false; helpContentEnabled = environment.HelpService.Enabled; + private statusChangeSubscription: Subscription; constructor( private router: Router, @@ -31,8 +36,9 @@ export class AppComponent implements OnInit { private translate: TranslateService, private breadCrumbResolverService: BreadCrumbResolverService, private titleService: Title, - private language: TranslateService, - private cultureService: CultureService + private cultureService: CultureService, + private cookieService: CookieService, + private ccService: NgcCookieConsentService ) { this.initializeServices(); } @@ -46,12 +52,16 @@ export class AppComponent implements OnInit { } ngOnInit() { - this.hasBreadCrumb = this.router.events - .filter(event => event instanceof NavigationEnd) - .map(() => this.route) - .map(route => route.firstChild) - .switchMap(route => route.data) - .map(data => data['breadcrumb']); + if (!this.cookieService.check("cookiesConsent")) { + this.cookieService.set("cookiesConsent", "false", 356); + } + + this.hasBreadCrumb = this.router.events.pipe( + filter(event => event instanceof NavigationEnd), + map(() => this.route), + map(route => route.firstChild), + switchMap(route => route.data), + map(data => data['breadcrumb'])); const appTitle = this.titleService.getTitle(); this.router @@ -69,17 +79,45 @@ export class AppComponent implements OnInit { }) ).subscribe((ttl: string) => { if (ttl.length > 0) { - this.language.get(ttl).subscribe((translated: string) => { - this.language.get('GENERAL.TITLES.PREFIX').subscribe( (titlePrefix: string) => { + this.translate.get(ttl).subscribe((translated: string) => { + this.translate.get('GENERAL.TITLES.PREFIX').subscribe((titlePrefix: string) => { this.titleService.setTitle(titlePrefix + translated); }); }); } else { - this.language.get('GENERAL.TITLES.GENERAL').subscribe((translated: string) => { + this.translate.get('GENERAL.TITLES.GENERAL').subscribe((translated: string) => { this.titleService.setTitle(translated); }); } }); + + this.statusChangeSubscription = this.ccService.statusChange$.subscribe((event: NgcStatusChangeEvent) => { + if (event.status == "dismiss") { + this.cookieService.set("cookiesConsent", "true", 365); + } + }); + + this.translate + .get(['COOKIE.MESSAGE', 'COOKIE.DISMISS', 'COOKIE.DENY', 'COOKIE.LINK', 'COOKIE.POLICY']) + .subscribe(data => { + this.ccService.getConfig().content = this.ccService.getConfig().content || {}; + // Override default messages with the translated ones + this.ccService.getConfig().content.message = data['COOKIE.MESSAGE']; + this.ccService.getConfig().content.dismiss = data['COOKIE.DISMISS']; + this.ccService.getConfig().content.deny = data['COOKIE.DENY']; + this.ccService.getConfig().content.link = data['COOKIE.LINK']; + this.ccService.getConfig().content.policy = data['COOKIE.POLICY']; + + if (this.cookieService.get("cookiesConsent") == "true") { + this.ccService.getConfig().enabled = false; + } + this.ccService.destroy(); + this.ccService.init(this.ccService.getConfig()); + }) + } + + ngOnDestroy() { + this.statusChangeSubscription.unsubscribe(); } login() { @@ -99,9 +137,10 @@ export class AppComponent implements OnInit { this.router.navigate(['/plans'], { queryParams: { /*refresh : Math.random() ,returnUrl: this.state.url*/ } }); } - goToGrants() { - this.router.navigate(['/grants'], { queryParams: { /*refresh : Math.random() ,returnUrl: this.state.url*/ } }); - } + // ----------- UNCOMMENT TO ADD AGAIN GRANTS -------- + // goToGrants() { + // this.router.navigate(['/grants'], { queryParams: { /*refresh : Math.random() ,returnUrl: this.state.url*/ } }); + // } initializeServices() { this.translate.setDefaultLang('en'); diff --git a/dmp-frontend/src/app/app.module.ts b/dmp-frontend/src/app/app.module.ts index 7d4640e5e..b82670f0c 100644 --- a/dmp-frontend/src/app/app.module.ts +++ b/dmp-frontend/src/app/app.module.ts @@ -1,7 +1,7 @@ import { OverlayModule } from '@angular/cdk/overlay'; import { HttpClient, HttpClientModule } from '@angular/common/http'; import { LOCALE_ID, NgModule } from '@angular/core'; -import { DateAdapter, MAT_DATE_FORMATS, MAT_DATE_LOCALE } from '@angular/material'; +import { DateAdapter, MAT_DATE_FORMATS, MAT_DATE_LOCALE } from '@angular/material/core'; import { MatMomentDateModule, MAT_MOMENT_DATE_FORMATS } from '@angular/material-moment-adapter'; import { BrowserModule, Title } from '@angular/platform-browser'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; @@ -23,12 +23,45 @@ import { ReactiveFormsModule, FormsModule } from '@angular/forms'; import { DatasetCreateWizardModule } from './ui/dataset-create-wizard/dataset-create-wizard.module'; import { NavbarModule } from './ui/navbar/navbar.module'; import { SidebarModule } from './ui/sidebar/sidebar.module'; +import { NgcCookieConsentModule, NgcCookieConsentConfig } from 'ngx-cookieconsent'; +import { CookieService } from "ngx-cookie-service"; +import { environment } from '../environments/environment'; // AoT requires an exported function for factories export function HttpLoaderFactory(http: HttpClient) { return new TranslateHttpLoader(http, 'assets/i18n/', '.json'); } +const cookieConfig: NgcCookieConsentConfig = { + enabled: true, + cookie: { + domain: environment.App // or 'your.domain.com' // it is mandatory to set a domain, for cookies to work properly (see https://goo.gl/S2Hy2A) + }, + palette: { + popup: { + background: "#000000", + text: "#ffffff", + link: "#ffffff" + }, + button: { + background: "#00b29f", + text: "#ffffff", + border: "transparent" + } + }, + content: { + message: "This website uses cookies to enhance the user experience.", + dismiss: "Got it!", + deny: "Refuse cookies", + link: "Learn more", + href: "http://localhost:4200/terms-of-service", + policy: "Cookie Policy" + }, + position: "bottom-right", + theme: 'edgeless', + type: 'info' +}; + @NgModule({ imports: [ BrowserModule, @@ -57,7 +90,8 @@ export function HttpLoaderFactory(http: HttpClient) { FormsModule, DatasetCreateWizardModule, NavbarModule, - SidebarModule + SidebarModule, + NgcCookieConsentModule.forRoot(cookieConfig) ], declarations: [ AppComponent @@ -75,7 +109,8 @@ export function HttpLoaderFactory(http: HttpClient) { deps: [CultureService], useFactory: (cultureService) => cultureService.getCurrentCulture().name }, - Title + Title, + CookieService ], bootstrap: [AppComponent] }) diff --git a/dmp-frontend/src/app/common/date/moment-utc-date-adapter.ts b/dmp-frontend/src/app/common/date/moment-utc-date-adapter.ts index 722f3ae2f..659926878 100644 --- a/dmp-frontend/src/app/common/date/moment-utc-date-adapter.ts +++ b/dmp-frontend/src/app/common/date/moment-utc-date-adapter.ts @@ -1,5 +1,5 @@ import { Inject, Injectable, Optional } from '@angular/core'; -import { MAT_DATE_LOCALE } from '@angular/material'; +import { MAT_DATE_LOCALE } from '@angular/material/core'; import { MomentDateAdapter } from '@angular/material-moment-adapter'; import * as moment from 'moment'; import { Moment } from 'moment'; diff --git a/dmp-frontend/src/app/common/http/interceptors/response-payload.interceptor.ts b/dmp-frontend/src/app/common/http/interceptors/response-payload.interceptor.ts index 125ac38ce..f34b273d4 100644 --- a/dmp-frontend/src/app/common/http/interceptors/response-payload.interceptor.ts +++ b/dmp-frontend/src/app/common/http/interceptors/response-payload.interceptor.ts @@ -1,6 +1,6 @@ import { HttpHandler, HttpHeaderResponse, HttpProgressEvent, HttpRequest, HttpResponse, HttpSentEvent, HttpUserEvent } from '@angular/common/http'; import { Injectable } from '@angular/core'; -import { MatSnackBar } from '@angular/material'; +import { MatSnackBar } from '@angular/material/snack-bar'; import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; import { BaseInterceptor } from './base.interceptor'; diff --git a/dmp-frontend/src/app/common/http/interceptors/status-code.interceptor.ts b/dmp-frontend/src/app/common/http/interceptors/status-code.interceptor.ts index 78a4aa331..867889a96 100644 --- a/dmp-frontend/src/app/common/http/interceptors/status-code.interceptor.ts +++ b/dmp-frontend/src/app/common/http/interceptors/status-code.interceptor.ts @@ -1,3 +1,5 @@ + +import {tap} from 'rxjs/operators'; import { Injectable } from "@angular/core"; import { BaseInterceptor } from "./base.interceptor"; import { InterceptorType } from "./interceptor-type"; @@ -10,11 +12,11 @@ export class StatusCodeInterceptor extends BaseInterceptor { type: InterceptorType; interceptRequest(req: HttpRequest, next: HttpHandler): Observable> { - return next.handle(req).do(event => { }, err => { + return next.handle(req).pipe(tap(event => { }, err => { if (err.status === 480) { this.router.navigate(['confirmation']); } - }); + })); } constructor( diff --git a/dmp-frontend/src/app/common/material/material.module.ts b/dmp-frontend/src/app/common/material/material.module.ts index 909d1ea8e..c450d3ea2 100644 --- a/dmp-frontend/src/app/common/material/material.module.ts +++ b/dmp-frontend/src/app/common/material/material.module.ts @@ -1,37 +1,35 @@ import { NgModule } from '@angular/core'; -import { - MatButtonModule, - MatToolbarModule, - MatIconModule, - MatCardModule, - MatGridListModule, - MatSnackBarModule, - MatSidenavModule, - MatListModule, - MatChipsModule, - MatFormFieldModule, - MatSelectModule, - MatOptionModule, - MatInputModule, - MatExpansionModule, - MatAutocompleteModule, - MatProgressSpinnerModule, - MatTabsModule, - MatDialogModule, - MatMenuModule, - MatRadioModule, - MatStepperModule, - MatTooltipModule, - MatProgressBarModule, - MatCheckboxModule, - MatDatepickerModule, - MatButtonToggleModule, - MatSliderModule, - MatSlideToggleModule, - MatTableModule, - MatPaginatorModule, - MatSortModule, -} from '@angular/material'; +import { MatAutocompleteModule } from '@angular/material/autocomplete'; +import { MatButtonModule } from '@angular/material/button'; +import { MatButtonToggleModule } from '@angular/material/button-toggle'; +import { MatCardModule } from '@angular/material/card'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { MatChipsModule } from '@angular/material/chips'; +import { MatOptionModule } from '@angular/material/core'; +import { MatDatepickerModule } from '@angular/material/datepicker'; +import { MatDialogModule } from '@angular/material/dialog'; +import { MatExpansionModule } from '@angular/material/expansion'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatGridListModule } from '@angular/material/grid-list'; +import { MatIconModule } from '@angular/material/icon'; +import { MatInputModule } from '@angular/material/input'; +import { MatListModule } from '@angular/material/list'; +import { MatMenuModule } from '@angular/material/menu'; +import { MatPaginatorModule } from '@angular/material/paginator'; +import { MatProgressBarModule } from '@angular/material/progress-bar'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; +import { MatRadioModule } from '@angular/material/radio'; +import { MatSelectModule } from '@angular/material/select'; +import { MatSidenavModule } from '@angular/material/sidenav'; +import { MatSlideToggleModule } from '@angular/material/slide-toggle'; +import { MatSliderModule } from '@angular/material/slider'; +import { MatSnackBarModule } from '@angular/material/snack-bar'; +import { MatSortModule } from '@angular/material/sort'; +import { MatStepperModule } from '@angular/material/stepper'; +import { MatTableModule } from '@angular/material/table'; +import { MatTabsModule } from '@angular/material/tabs'; +import { MatToolbarModule } from '@angular/material/toolbar'; +import { MatTooltipModule } from '@angular/material/tooltip'; import { CdkTableModule } from '@angular/cdk/table'; @NgModule({ diff --git a/dmp-frontend/src/app/common/ui/common-ui.module.ts b/dmp-frontend/src/app/common/ui/common-ui.module.ts index 124c9957a..fe8455d39 100644 --- a/dmp-frontend/src/app/common/ui/common-ui.module.ts +++ b/dmp-frontend/src/app/common/ui/common-ui.module.ts @@ -2,17 +2,20 @@ import { CommonModule } from '@angular/common'; import { NgModule } from '@angular/core'; import { TranslateModule } from '@ngx-translate/core'; import { MaterialModule } from '../material/material.module'; +import { FormsModule } from '@angular/forms'; @NgModule({ imports: [ CommonModule, MaterialModule, - TranslateModule + TranslateModule, + FormsModule ], exports: [ CommonModule, MaterialModule, - TranslateModule + TranslateModule, + FormsModule ] }) export class CommonUiModule { } diff --git a/dmp-frontend/src/app/core/common/enum/auth-provider.ts b/dmp-frontend/src/app/core/common/enum/auth-provider.ts index 460ce2b50..b8b70efd8 100644 --- a/dmp-frontend/src/app/core/common/enum/auth-provider.ts +++ b/dmp-frontend/src/app/core/common/enum/auth-provider.ts @@ -5,5 +5,7 @@ export enum AuthProvider { LinkedIn = 4, //NativeLogin=5, B2Access = 6, - ORCID = 7 + ORCID = 7, + OpenAire = 8, + Configurable = 9 } diff --git a/dmp-frontend/src/app/core/common/enum/role.ts b/dmp-frontend/src/app/core/common/enum/role.ts new file mode 100644 index 000000000..a11abaf81 --- /dev/null +++ b/dmp-frontend/src/app/core/common/enum/role.ts @@ -0,0 +1,4 @@ +export enum Role { + Owner = 0, + Member = 1 +} diff --git a/dmp-frontend/src/app/core/model/admin/dataset-profile/dataset-profile.ts b/dmp-frontend/src/app/core/model/admin/dataset-profile/dataset-profile.ts index 18a16cd33..916cf3b28 100644 --- a/dmp-frontend/src/app/core/model/admin/dataset-profile/dataset-profile.ts +++ b/dmp-frontend/src/app/core/model/admin/dataset-profile/dataset-profile.ts @@ -54,6 +54,7 @@ export interface Field { data: any; visible: Visibility; validations: ValidationType[]; + rdaCommonStandard: string; } export interface ViewStyle { diff --git a/dmp-frontend/src/app/core/model/configurable-provider/configurableProvider.ts b/dmp-frontend/src/app/core/model/configurable-provider/configurableProvider.ts new file mode 100644 index 000000000..c8098f618 --- /dev/null +++ b/dmp-frontend/src/app/core/model/configurable-provider/configurableProvider.ts @@ -0,0 +1,9 @@ +export class ConfigurableProvider { + configurableLoginId: string; + name: string; + clientId: string; + redirect_uri: string; + oauthUrl: string; + scope: string; + state: string; +} diff --git a/dmp-frontend/src/app/core/model/data-repository/data-repository.ts b/dmp-frontend/src/app/core/model/data-repository/data-repository.ts index 76f5cf372..3037199c0 100644 --- a/dmp-frontend/src/app/core/model/data-repository/data-repository.ts +++ b/dmp-frontend/src/app/core/model/data-repository/data-repository.ts @@ -5,4 +5,5 @@ export interface DataRepositoryModel { uri: string; pid: string; info: string; + source: string; } diff --git a/dmp-frontend/src/app/core/model/dataset/dataset-listing.ts b/dmp-frontend/src/app/core/model/dataset/dataset-listing.ts index 80e0f931e..1776ab9be 100644 --- a/dmp-frontend/src/app/core/model/dataset/dataset-listing.ts +++ b/dmp-frontend/src/app/core/model/dataset/dataset-listing.ts @@ -15,4 +15,5 @@ export interface DatasetListingModel { created: Date; modified: Date; finalizedAt: Date; + dmpPublishedAt?: Date; } diff --git a/dmp-frontend/src/app/core/model/dmp/dmp-create-wizard/dmp-create-wizard-form.model.ts b/dmp-frontend/src/app/core/model/dmp/dmp-create-wizard/dmp-create-wizard-form.model.ts index f53ef7d9c..a3303ccac 100644 --- a/dmp-frontend/src/app/core/model/dmp/dmp-create-wizard/dmp-create-wizard-form.model.ts +++ b/dmp-frontend/src/app/core/model/dmp/dmp-create-wizard/dmp-create-wizard-form.model.ts @@ -1,10 +1,9 @@ -import { DmpModel } from "../dmp" -import { DatasetProfileModel } from "../../dataset/dataset-profile"; -import { FormGroup } from "@angular/forms/src/model"; -import { ValidationContext } from "../../../../common/forms/validation/validation-context"; -import { Validators, FormBuilder } from "@angular/forms"; +import { FormBuilder, FormGroup, Validators } from "@angular/forms"; import { BackendErrorValidator } from "../../../../common/forms/validation/custom-validator"; import { ValidationErrorModel } from "../../../../common/forms/validation/error-model/validation-error-model"; +import { ValidationContext } from "../../../../common/forms/validation/validation-context"; +import { DatasetProfileModel } from "../../dataset/dataset-profile"; +import { DmpModel } from "../dmp"; export class DmpCreateWizardFormModel { dmp: DmpModel; @@ -18,7 +17,7 @@ export class DmpCreateWizardFormModel { return this; } - buildForm(context: ValidationContext = null): FormGroup{ + buildForm(context: ValidationContext = null): FormGroup { if (context == null) { context = this.createValidationContext(); } const formBuilder = new FormBuilder(); const formGroup = formBuilder.group({ @@ -37,6 +36,3 @@ export class DmpCreateWizardFormModel { return baseContext; } } - - - diff --git a/dmp-frontend/src/app/core/model/external-dataset/external-dataset.ts b/dmp-frontend/src/app/core/model/external-dataset/external-dataset.ts index e4cff37d9..40d841e5e 100644 --- a/dmp-frontend/src/app/core/model/external-dataset/external-dataset.ts +++ b/dmp-frontend/src/app/core/model/external-dataset/external-dataset.ts @@ -3,8 +3,9 @@ import { ExternalDatasetType } from '../../common/enum/external-dataset-type'; export interface ExternalDatasetModel { abbreviation: String; id: String; - label: String; + name: String; reference: String; type: ExternalDatasetType; info: String; -} \ No newline at end of file + source: String; +} diff --git a/dmp-frontend/src/app/core/model/organisation/organization.ts b/dmp-frontend/src/app/core/model/organisation/organization.ts index 58e807273..5fd54c7ab 100644 --- a/dmp-frontend/src/app/core/model/organisation/organization.ts +++ b/dmp-frontend/src/app/core/model/organisation/organization.ts @@ -5,4 +5,5 @@ export interface OrganizationModel { name: string; label: string; status: Status; + tag: string; } diff --git a/dmp-frontend/src/app/core/model/registry/registry.ts b/dmp-frontend/src/app/core/model/registry/registry.ts index c9568466c..6658e9b57 100644 --- a/dmp-frontend/src/app/core/model/registry/registry.ts +++ b/dmp-frontend/src/app/core/model/registry/registry.ts @@ -3,7 +3,9 @@ export interface RegistryModel { abbreviation: String; definition: String; id: String; + pid: String; label: String; reference: String; uri: String; + source: String; } diff --git a/dmp-frontend/src/app/core/query/explore-dataset/explore-dataset-criteria.ts b/dmp-frontend/src/app/core/query/explore-dataset/explore-dataset-criteria.ts index 65d03f029..7c10b2bf0 100644 --- a/dmp-frontend/src/app/core/query/explore-dataset/explore-dataset-criteria.ts +++ b/dmp-frontend/src/app/core/query/explore-dataset/explore-dataset-criteria.ts @@ -1,8 +1,10 @@ import { GrantStateType } from "../../common/enum/grant-state-type"; import { BaseCriteria } from "../base-criteria"; +import { Role } from '../../common/enum/role'; export class ExploreDatasetCriteriaModel extends BaseCriteria { public grantStatus: GrantStateType; + public role: Role; public dmpIds: string[] = []; public grants: string[] = []; public datasetProfile: string[] = []; diff --git a/dmp-frontend/src/app/core/query/explore-dmp/explore-dmp-criteria.ts b/dmp-frontend/src/app/core/query/explore-dmp/explore-dmp-criteria.ts index cfd2ea409..e577c31aa 100644 --- a/dmp-frontend/src/app/core/query/explore-dmp/explore-dmp-criteria.ts +++ b/dmp-frontend/src/app/core/query/explore-dmp/explore-dmp-criteria.ts @@ -1,8 +1,10 @@ import { BaseCriteria } from "../base-criteria"; import { GrantStateType } from "../../common/enum/grant-state-type"; +import { Role } from '../../common/enum/role'; export class ExploreDmpCriteriaModel extends BaseCriteria { public grantStatus: GrantStateType; + public role: Role; public grants: string[] = []; public datasetProfile: string[] = []; public dmpOrganisations: string[] = []; diff --git a/dmp-frontend/src/app/core/services/auth/auth.service.ts b/dmp-frontend/src/app/core/services/auth/auth.service.ts index b08921e01..7eea789d2 100644 --- a/dmp-frontend/src/app/core/services/auth/auth.service.ts +++ b/dmp-frontend/src/app/core/services/auth/auth.service.ts @@ -1,10 +1,12 @@ + +import { of as observableOf, throwError as observableThrowError, Observable } from 'rxjs'; + +import { map, catchError, takeUntil } from 'rxjs/operators'; import { HttpClient, HttpHeaders } from '@angular/common/http'; import { Injectable } from '@angular/core'; -import { MatSnackBar } from '@angular/material'; +import { MatSnackBar } from '@angular/material/snack-bar'; import { Router } from '@angular/router'; import { TranslateService } from '@ngx-translate/core'; -import { takeUntil } from 'rxjs/operators'; -import { Observable } from 'rxjs/Rx'; import { environment } from '../../../../environments/environment'; import { SnackBarNotificationComponent } from '../../../library/notification/snack-bar/snack-bar-notification.component'; import { BaseService } from '../../common/base/base.service'; @@ -12,6 +14,7 @@ import { Credential } from '../../model/auth/credential'; import { LoginInfo } from '../../model/auth/login-info'; import { Principal } from '../../model/auth/Principal'; import { UiNotificationService, SnackBarNotificationLevel } from '../notification/ui-notification-service'; +import { ConfigurableProvider } from "../../model/configurable-provider/configurableProvider"; @Injectable() @@ -67,31 +70,31 @@ export class AuthService extends BaseService { public login(loginInfo: LoginInfo): Observable { const url = this.actionUrl + 'externallogin'; - return this.http.post(url, loginInfo, { headers: this.headers }) - .map((res: any) => { + return this.http.post(url, loginInfo, { headers: this.headers }).pipe( + map((res: any) => { const principal = this.current(res.payload); //this.loginContextSubject.next(true); return principal; - }) - .catch((error: any) => { + }), + catchError((error: any) => { //this.loginContextSubject.next(false); - return Observable.throw(error); - }); + return observableThrowError(error); + })); } public nativeLogin(credentials: Credential): Observable { const url = this.actionUrl + 'nativelogin'; - return this.http.post(url, credentials, { headers: this.headers }) - .map((res: any) => { + return this.http.post(url, credentials, { headers: this.headers }).pipe( + map((res: any) => { const principal = this.current(res.payload); //this.loginContextSubject.next(true); return principal; - }) - .catch((error: any) => { + }), + catchError((error: any) => { //this.loginContextSubject.next(false); - return Observable.throw(error); - }); + return observableThrowError(error); + })); } @@ -116,22 +119,22 @@ export class AuthService extends BaseService { const principal = this.current(); if (!principal) { this.clear(); - return Observable.of(); + return observableOf(); } let headers = this.headers; headers = headers.set('AuthToken', principal.token); - return this.http.post(url, null, { headers: headers }) - .map((res: any) => { + return this.http.post(url, null, { headers: headers }).pipe( + map((res: any) => { const princ = this.current(res.payload); return princ; - }) - .catch((error: any) => { + }), + catchError((error: any) => { //console.warn('could not retrieve me info:\n', error); this.clear(); const princ = this.current(); this.router.navigate(['/login']); - return Observable.of(princ); - }); + return observableOf(princ); + })); } public onLogOutSuccess(logoutMessage: any) { @@ -143,4 +146,14 @@ export class AuthService extends BaseService { this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-LOGOUT'), SnackBarNotificationLevel.Error); this.router.navigate(['/login']); } + + public getConfigurableProviders(): Observable { + const url = this.actionUrl + 'configurableLogin'; + return this.http.get(url, { headers: this.headers }).pipe( + map((res: any) => { + const providers = res.payload.providers; + return providers; + }) + ); + } } diff --git a/dmp-frontend/src/app/core/services/dataset-profile/dataset-profile.service.ts b/dmp-frontend/src/app/core/services/dataset-profile/dataset-profile.service.ts index 644e4028d..56d259e2e 100644 --- a/dmp-frontend/src/app/core/services/dataset-profile/dataset-profile.service.ts +++ b/dmp-frontend/src/app/core/services/dataset-profile/dataset-profile.service.ts @@ -1,10 +1,12 @@ import { HttpClient, HttpHeaders, HttpResponse } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { Observable } from 'rxjs'; +import { takeUntil } from "rxjs/operators"; import { environment } from '../../../../environments/environment'; import { BaseHttpParams } from '../../../common/http/base-http-params'; import { InterceptorType } from '../../../common/http/interceptors/interceptor-type'; import { DatasetProfileEditorModel } from '../../../ui/admin/dataset-profile/editor/dataset-profile-editor-model'; +import { BaseService } from "../../common/base/base.service"; import { DatasetProfile } from '../../model/admin/dataset-profile/dataset-profile'; import { DataTableData } from '../../model/data-table/data-table-data'; import { DataTableRequest } from '../../model/data-table/data-table-request'; @@ -14,12 +16,16 @@ import { DatasetProfileCriteria } from '../../query/dataset-profile/dataset-prof import { BaseHttpService } from '../http/base-http.service'; @Injectable() -export class DatasetProfileService { +export class DatasetProfileService extends BaseService { + + private rdaCommonStandards: String[]; + private rdaCommonStandardsLoading: boolean; private actionUrl: string; private headers = new HttpHeaders(); constructor(private http: BaseHttpService, private httpClient: HttpClient) { + super(); this.actionUrl = environment.Server + 'admin/'; } @@ -70,4 +76,17 @@ export class DatasetProfileService { formData.append('file', file[0], labelSent); return this.http.post(this.actionUrl + "upload", formData, { params: params }); } + + getRDACommonStandards(): String[] { + if (!this.rdaCommonStandards && !this.rdaCommonStandardsLoading) { this.getRDACommonStandardsInternal(); } + return this.rdaCommonStandards; + } + + private getRDACommonStandardsInternal() { + this.rdaCommonStandardsLoading = true; + return this.http.get(this.actionUrl + "getRDACommonStandards").pipe(takeUntil(this._destroyed)).subscribe(x => { + this.rdaCommonStandards = x; + this.rdaCommonStandardsLoading = false; + }); + } } diff --git a/dmp-frontend/src/app/core/services/dataset-wizard/dataset-wizard.service.ts b/dmp-frontend/src/app/core/services/dataset-wizard/dataset-wizard.service.ts index b08009aad..e11802ccd 100644 --- a/dmp-frontend/src/app/core/services/dataset-wizard/dataset-wizard.service.ts +++ b/dmp-frontend/src/app/core/services/dataset-wizard/dataset-wizard.service.ts @@ -2,17 +2,14 @@ import { HttpClient, HttpHeaders, HttpResponse } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { Observable } from 'rxjs'; import { environment } from '../../../../environments/environment'; -import { RequestItem } from '../../query/request-item'; +import { BaseHttpParams } from '../../../common/http/base-http-params'; +import { InterceptorType } from '../../../common/http/interceptors/interceptor-type'; import { DatasetProfileDefinitionModel } from '../../model/dataset-profile-definition/dataset-profile-definition'; import { DatasetProfileModel } from '../../model/dataset/dataset-profile'; import { DatasetWizardModel } from '../../model/dataset/dataset-wizard'; -import { DmpModel } from '../../model/dmp/dmp'; import { DatasetProfileCriteria } from '../../query/dataset-profile/dataset-profile-criteria'; -import { DmpCriteria } from '../../query/dmp/dmp-criteria'; +import { RequestItem } from '../../query/request-item'; import { BaseHttpService } from '../http/base-http.service'; -import { ContentType } from '@angular/http/src/enums'; -import { BaseHttpParams } from '../../../common/http/base-http-params'; -import { InterceptorType } from '../../../common/http/interceptors/interceptor-type'; @Injectable() export class DatasetWizardService { @@ -70,7 +67,7 @@ export class DatasetWizardService { return this.http.get(this.actionUrl + id + '/unlock', { headers: this.headers }); } - public uploadXml(fileList: FileList, datasetTitle: string, dmpId: string, datasetProfileId: string): Observable { + public uploadXml(fileList: FileList, datasetTitle: string, dmpId: string, datasetProfileId: string): Observable { const formData: FormData = new FormData(); if (fileList instanceof FileList) { for (let i = 0; i < fileList.length; i++) { @@ -90,6 +87,6 @@ export class DatasetWizardService { } public updateDatasetProfile(id: String): Observable { - return this.http.get(this.actionUrl + "profile/"+ id, { headers: this.headers }); + return this.http.get(this.actionUrl + "profile/" + id, { headers: this.headers }); } } diff --git a/dmp-frontend/src/app/core/services/dataset/dataset.service.ts b/dmp-frontend/src/app/core/services/dataset/dataset.service.ts index 920b644ba..d1b59d588 100644 --- a/dmp-frontend/src/app/core/services/dataset/dataset.service.ts +++ b/dmp-frontend/src/app/core/services/dataset/dataset.service.ts @@ -31,8 +31,8 @@ export class DatasetService { return this.http.get(this.actionUrl + 'makepublic/' + id); } - getDatasetProfiles(): Observable { - return this.http.get(environment.Server + 'datasetprofiles/getAll'); + getDatasetProfiles(dataTableRequest: DataTableRequest): Observable { + return this.http.post(environment.Server + 'datasetprofiles/getAll', dataTableRequest); } getDatasetProfilesUsedPaged(dataTableRequest: DataTableRequest) { diff --git a/dmp-frontend/src/app/core/services/dmp/dmp.service.ts b/dmp-frontend/src/app/core/services/dmp/dmp.service.ts index 4cb45c308..2df142252 100644 --- a/dmp-frontend/src/app/core/services/dmp/dmp.service.ts +++ b/dmp-frontend/src/app/core/services/dmp/dmp.service.ts @@ -2,23 +2,22 @@ import { HttpClient, HttpHeaders, HttpResponse } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { Observable } from 'rxjs'; import { environment } from '../../../../environments/environment'; +import { BaseHttpParams } from '../../../common/http/base-http-params'; +import { InterceptorType } from '../../../common/http/interceptors/interceptor-type'; import { DynamicFieldGrantCriteria } from '../../../models/dynamic-field-grant/DynamicFieldGrantCriteria'; import { DataTableData } from '../../model/data-table/data-table-data'; import { DataTableRequest } from '../../model/data-table/data-table-request'; +import { DatasetListingModel } from '../../model/dataset/dataset-listing'; import { DatasetProfileModel } from '../../model/dataset/dataset-profile'; +import { DatasetsToBeFinalized } from '../../model/dataset/datasets-toBeFinalized'; import { DmpModel } from '../../model/dmp/dmp'; import { DmpListingModel } from '../../model/dmp/dmp-listing'; +import { DmpOverviewModel } from '../../model/dmp/dmp-overview'; import { DatasetProfileCriteria } from '../../query/dataset-profile/dataset-profile-criteria'; import { DmpCriteria } from '../../query/dmp/dmp-criteria'; +import { ExploreDmpCriteriaModel } from '../../query/explore-dmp/explore-dmp-criteria'; import { RequestItem } from '../../query/request-item'; import { BaseHttpService } from '../http/base-http.service'; -import { ContentType } from '@angular/http/src/enums'; -import { BaseHttpParams } from '../../../common/http/base-http-params'; -import { InterceptorType } from '../../../common/http/interceptors/interceptor-type'; -import { ExploreDmpCriteriaModel } from '../../query/explore-dmp/explore-dmp-criteria'; -import { DmpOverviewModel } from '../../model/dmp/dmp-overview'; -import { DatasetListingModel } from '../../model/dataset/dataset-listing'; -import { DatasetsToBeFinalized } from '../../model/dataset/datasets-toBeFinalized'; @Injectable() export class DmpService { @@ -93,7 +92,7 @@ export class DmpService { } getDoi(id: string): Observable { - return this.http.post(this.actionUrl + 'createZenodoDoi/' + id, {headers: this.headers}); + return this.http.post(this.actionUrl + 'createZenodoDoi/' + id, { headers: this.headers }); } getDynamicField(requestItem: RequestItem): any { @@ -119,7 +118,7 @@ export class DmpService { return this.httpClient.get(this.actionUrl + 'rda/' + id, { responseType: 'blob', observe: 'response' }); } - public uploadXml(fileList: FileList, dmpTitle: string): Observable { + public uploadXml(fileList: FileList, dmpTitle: string): Observable { const formData: FormData = new FormData(); if (fileList instanceof FileList) { for (let i = 0; i < fileList.length; i++) { diff --git a/dmp-frontend/src/app/core/services/email-confirmation/email-confirmation.service.ts b/dmp-frontend/src/app/core/services/email-confirmation/email-confirmation.service.ts index fc7673568..29433964f 100644 --- a/dmp-frontend/src/app/core/services/email-confirmation/email-confirmation.service.ts +++ b/dmp-frontend/src/app/core/services/email-confirmation/email-confirmation.service.ts @@ -1,7 +1,7 @@ +import { HttpHeaders } from '@angular/common/http'; import { Injectable } from "@angular/core"; -import { HttpHeaders } from "@angular/common/http/src/headers"; -import { BaseHttpService } from "../http/base-http.service"; import { environment } from "../../../../environments/environment"; +import { BaseHttpService } from "../http/base-http.service"; @Injectable() export class EmailConfirmationService { @@ -17,6 +17,6 @@ export class EmailConfirmationService { } public sendConfirmationEmail(email: string) { - return this.http.post(this.actioUrl, email, {headers: this.headers}); + return this.http.post(this.actioUrl, email, { headers: this.headers }); } } diff --git a/dmp-frontend/src/app/core/services/help-content/help-content.service.ts b/dmp-frontend/src/app/core/services/help-content/help-content.service.ts index 638e289c9..f0397b5b6 100644 --- a/dmp-frontend/src/app/core/services/help-content/help-content.service.ts +++ b/dmp-frontend/src/app/core/services/help-content/help-content.service.ts @@ -1,55 +1,57 @@ +import { HttpClient } from '@angular/common/http'; /** * Created by stefania on 7/17/17. */ import { Injectable } from '@angular/core'; -import { Http, Response } from '@angular/http'; -import { Observable } from 'rxjs/Rx'; +import { Observable, throwError as observableThrowError } from 'rxjs'; +import { catchError, map } from 'rxjs/operators'; import { environment } from '../../../../environments/environment'; import { PageHelpContent } from '../../model/help-content/page-help-content'; import { CachedContentItem } from './cached-content-item'; + @Injectable() export class HelpContentService { private _helpServiceUrl = environment.HelpService.Url; cache = new Map(); - constructor(private http: Http) { + constructor(private http: HttpClient) { } - getActivePageContent(route: string) { - if (!this.cache.get(route) || !this.isValidCachedItem(route)) { - return this.http.get(this._helpServiceUrl + '/page/route?q=' + route) - .map(res => { - this.cache.set(route, { timestamp: Date.now(), content: res.json() }); - return res.json(); - }) - .catch(this.handleError); - } - return Observable.create(observer => observer.next(this.cache.get(route).content)); - } - private extractData(res: Response) { - const body = res.json(); - return body.data || {}; - } - private handleError(error: Response | any) { - // In a real world app, we might use a remote logging infrastructure - // We'd also dig deeper into the error to get a better message - let errMsg = ''; - if (error instanceof Response) { - const body = error.text() || ''; - //const err = body.error || JSON.stringify(body); - errMsg = `${error.status} - ${error.statusText || ''} ${body}`; - } else { - errMsg = (error.message) ? error.message : - error.status ? `${error.status} - ${error.statusText}` : 'Server error'; - console.error(errMsg); // log to console instead - } - return Observable.throw(errMsg); - } + // getActivePageContent(route: string) { + // if (!this.cache.get(route) || !this.isValidCachedItem(route)) { + // return this.http.get(this._helpServiceUrl + '/page/route?q=' + route).pipe( + // map((res: Response) => { + // this.cache.set(route, { timestamp: Date.now(), content: res.json() as PageHelpContent }); + // return res.json(); + // }), + // catchError(this.handleError)); + // } + // return Observable.create(observer => observer.next(this.cache.get(route).content)); + // } + // private extractData(res: Response) { + // const body = res.json(); + // return body. || {}; + // } + // private handleError(error: Response | any) { + // // In a real world app, we might use a remote logging infrastructure + // // We'd also dig deeper into the error to get a better message + // let errMsg = ''; + // if (error instanceof Response) { + // const body = error.text() || ''; + // //const err = body.error || JSON.stringify(body); + // errMsg = `${error.status} - ${error.statusText || ''} ${body}`; + // } else { + // errMsg = (error.message) ? error.message : + // error.status ? `${error.status} - ${error.statusText}` : 'Server error'; + // console.error(errMsg); // log to console instead + // } + // return observableThrowError(errMsg); + // } - isValidCachedItem(route) { - const cachedTimestamp = this.cache.get(route).timestamp; - const currentTimestamp = Date.now(); - if (currentTimestamp - cachedTimestamp > 30000) { return false; } else { return true; } - } + // isValidCachedItem(route) { + // const cachedTimestamp = this.cache.get(route).timestamp; + // const currentTimestamp = Date.now(); + // if (currentTimestamp - cachedTimestamp > 30000) { return false; } else { return true; } + // } } diff --git a/dmp-frontend/src/app/core/services/http/base-http.service.ts b/dmp-frontend/src/app/core/services/http/base-http.service.ts index a3e0aca26..7fe8f473d 100644 --- a/dmp-frontend/src/app/core/services/http/base-http.service.ts +++ b/dmp-frontend/src/app/core/services/http/base-http.service.ts @@ -1,3 +1,5 @@ + +import {map} from 'rxjs/operators'; import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { Observable } from 'rxjs'; @@ -39,7 +41,7 @@ export class BaseHttpService { } private interceptRepsonse(observable: Observable): Observable { - return observable + return observable.pipe( // .catch((errorResponse) => { // if (errorResponse.status === 401) { // this.snackBar.openFromComponent(SnackBarNotificationComponent, { @@ -69,7 +71,7 @@ export class BaseHttpService { // } // } // }) - .map(response => { + map(response => { if (response instanceof Blob) { return response; } if (response['statusCode'] === ApiMessageCode.SUCCESS_MESSAGE) { //throw new Error('Request failed'); @@ -83,6 +85,6 @@ export class BaseHttpService { } else { return response['payload']; } - }); + })); } } diff --git a/dmp-frontend/src/app/library/auto-complete/multiple/multiple-auto-complete.component.html b/dmp-frontend/src/app/library/auto-complete/multiple/multiple-auto-complete.component.html index 80447c971..adc236268 100644 --- a/dmp-frontend/src/app/library/auto-complete/multiple/multiple-auto-complete.component.html +++ b/dmp-frontend/src/app/library/auto-complete/multiple/multiple-auto-complete.component.html @@ -1,13 +1,13 @@
- + {{this._displayFn(selectedItem)}} cancel - + diff --git a/dmp-frontend/src/app/library/auto-complete/multiple/multiple-auto-complete.component.scss b/dmp-frontend/src/app/library/auto-complete/multiple/multiple-auto-complete.component.scss index 59bdf7561..07c37ced4 100644 --- a/dmp-frontend/src/app/library/auto-complete/multiple/multiple-auto-complete.component.scss +++ b/dmp-frontend/src/app/library/auto-complete/multiple/multiple-auto-complete.component.scss @@ -1,22 +1,32 @@ .multiple-auto-complete { - margin-left: inherit; - margin-right: inherit; + margin-left: inherit; + margin-right: inherit; - .multi-chip-list { - padding-left: 0; - } + .multi-chip-list { + padding-left: 0; - .multi-loading-bar { - padding-right: 0; - padding-left: 0; - } + .chip { + border-radius: 2em !important; + height: auto !important; + min-width: fit-content !important; + } + } - .not-loading { - display: none; - } + .multi-loading-bar { + padding-right: 0; + padding-left: 0; + } + + .not-loading { + display: none; + } } .two-line-mat-option { - height: 3.5em; - line-height: 1.2em; + // height: 3.5em; + line-height: 1.2em; +} + +::ng-deep .mat-autocomplete-panel.panel-width { + max-width: 78vw !important; } diff --git a/dmp-frontend/src/app/library/auto-complete/multiple/multiple-auto-complete.component.ts b/dmp-frontend/src/app/library/auto-complete/multiple/multiple-auto-complete.component.ts index 73763d3e5..a19d1c55d 100644 --- a/dmp-frontend/src/app/library/auto-complete/multiple/multiple-auto-complete.component.ts +++ b/dmp-frontend/src/app/library/auto-complete/multiple/multiple-auto-complete.component.ts @@ -2,7 +2,9 @@ import { FocusMonitor } from '@angular/cdk/a11y'; import { COMMA, ENTER } from '@angular/cdk/keycodes'; import { Component, ElementRef, EventEmitter, Input, OnDestroy, OnInit, Optional, Output, Self, ViewChild } from '@angular/core'; import { ControlValueAccessor, NgControl } from '@angular/forms'; -import { MatAutocompleteSelectedEvent, MatAutocompleteTrigger, MatChipInputEvent, MatFormFieldControl } from '@angular/material'; +import { MatAutocompleteSelectedEvent, MatAutocompleteTrigger } from '@angular/material/autocomplete'; +import { MatChipInputEvent } from '@angular/material/chips'; +import { MatFormFieldControl } from '@angular/material/form-field'; import { Observable, of as observableOf, Subject } from 'rxjs'; import { debounceTime, distinctUntilChanged, map, mergeMap, startWith, tap } from 'rxjs/operators'; import { AutoCompleteGroup } from '../auto-complete-group'; @@ -87,8 +89,8 @@ export class MultipleAutoCompleteComponent implements OnInit, MatFormFieldContro } private _selectedValue; - @ViewChild('textInput') textInput: ElementRef; - @ViewChild(MatAutocompleteTrigger) autocomplete: MatAutocompleteTrigger; + @ViewChild('textInput', { static: true }) textInput: ElementRef; + @ViewChild(MatAutocompleteTrigger, { static: true }) autocomplete: MatAutocompleteTrigger; constructor( private fm: FocusMonitor, diff --git a/dmp-frontend/src/app/library/auto-complete/single/single-auto-complete-configuration.ts b/dmp-frontend/src/app/library/auto-complete/single/single-auto-complete-configuration.ts index d90d89a58..97aedab67 100644 --- a/dmp-frontend/src/app/library/auto-complete/single/single-auto-complete-configuration.ts +++ b/dmp-frontend/src/app/library/auto-complete/single/single-auto-complete-configuration.ts @@ -8,6 +8,8 @@ export interface SingleAutoCompleteConfiguration { minFilteringChars?: number; // Load and present items from start, without user query. Default: true. loadDataOnStart?: boolean; + // Remove item after selection. + removeAfterSelection?: boolean; // Static or initial items. initialItems?: (data?: any) => Observable; // Data retrieval function @@ -20,6 +22,12 @@ export interface SingleAutoCompleteConfiguration { titleFn?: (item: any) => string; // Property formating for dropdown subtitleFn?: (item: any) => string; + // Property formating for icon on chip + iconFn?: (item: any) => string; + // Property for link on chip + linkFn?: (item: any) => string; + // Disable option. + disableOption?: (item: any) => boolean; //Extra data passed to query function extraData?: any; // Callback to intercept value assignment based on item selection diff --git a/dmp-frontend/src/app/library/auto-complete/single/single-auto-complete.component.html b/dmp-frontend/src/app/library/auto-complete/single/single-auto-complete.component.html index 46fd53fe5..abe733c08 100644 --- a/dmp-frontend/src/app/library/auto-complete/single/single-auto-complete.component.html +++ b/dmp-frontend/src/app/library/auto-complete/single/single-auto-complete.component.html @@ -1,6 +1,7 @@
- + + {{_iconFn(value)}} {{_displayFn(value)}} cancel @@ -8,10 +9,10 @@ - + - + {{_titleFn(item)}}
@@ -20,7 +21,7 @@
- + {{_titleFn(item)}}
diff --git a/dmp-frontend/src/app/library/auto-complete/single/single-auto-complete.component.scss b/dmp-frontend/src/app/library/auto-complete/single/single-auto-complete.component.scss index 4f67174f7..4a8d65c72 100644 --- a/dmp-frontend/src/app/library/auto-complete/single/single-auto-complete.component.scss +++ b/dmp-frontend/src/app/library/auto-complete/single/single-auto-complete.component.scss @@ -1,22 +1,35 @@ .auto-complete { - margin-left: inherit; - margin-right: inherit; + margin-left: inherit; + margin-right: inherit; - .not-loading { - display: none; - } + .not-loading { + display: none; + } - .chip-list { - width: 100%; - } + .chip-list { + width: 100%; + } - .progress-loader { - position: absolute; - right: 0; - } + .progress-loader { + position: absolute; + right: 0; + } } .two-line-mat-option { - height: 3.5em; - line-height: 1.2em; + // height: 3.5em; + line-height: 1.2em; +} + +.chip { + cursor: pointer; + opacity: 1 !important; +} + +.chip:hover { + background-color: #c5c5c5; +} + +::ng-deep .mat-autocomplete-panel.panel-width { + max-width: 78vw !important; } diff --git a/dmp-frontend/src/app/library/auto-complete/single/single-auto-complete.component.ts b/dmp-frontend/src/app/library/auto-complete/single/single-auto-complete.component.ts index 1d740aefb..2079b101a 100644 --- a/dmp-frontend/src/app/library/auto-complete/single/single-auto-complete.component.ts +++ b/dmp-frontend/src/app/library/auto-complete/single/single-auto-complete.component.ts @@ -2,12 +2,14 @@ import { FocusMonitor } from '@angular/cdk/a11y'; import { COMMA, ENTER } from '@angular/cdk/keycodes'; import { Component, ElementRef, EventEmitter, Input, OnDestroy, OnInit, Optional, Output, Self } from '@angular/core'; import { ControlValueAccessor, NgControl } from '@angular/forms'; -import { MatAutocompleteSelectedEvent, MatFormFieldControl } from '@angular/material'; +import { MatAutocompleteSelectedEvent } from '@angular/material/autocomplete'; +import { MatFormFieldControl } from '@angular/material/form-field'; import { Observable, of as observableOf, Subject } from 'rxjs'; import { debounceTime, distinctUntilChanged, map, mergeMap, startWith, tap } from 'rxjs/operators'; import { AutoCompleteGroup } from '../auto-complete-group'; import { SingleAutoCompleteConfiguration } from './single-auto-complete-configuration'; import { switchMap } from 'rxjs/internal/operators/switchMap'; +import { Router } from '@angular/router'; @Component({ @@ -23,6 +25,8 @@ export class SingleAutoCompleteComponent implements OnInit, MatFormFieldControl< @Input() configuration: SingleAutoCompleteConfiguration; // Selected Option Event @Output() optionSelected: EventEmitter = new EventEmitter(); + // Removed Option Event + @Output() optionRemoved: EventEmitter = new EventEmitter(); id = `single-autocomplete-${SingleAutoCompleteComponent.nextId++}`; stateChanges = new Subject(); @@ -84,6 +88,7 @@ export class SingleAutoCompleteComponent implements OnInit, MatFormFieldControl< constructor( private fm: FocusMonitor, private elRef: ElementRef, + private router: Router, @Optional() @Self() public ngControl: NgControl) { fm.monitor(elRef.nativeElement, true).subscribe((origin) => { @@ -136,6 +141,21 @@ export class SingleAutoCompleteComponent implements OnInit, MatFormFieldControl< return null; } + _iconFn(item: any): string { + if (this.configuration.iconFn && item) { return this.configuration.iconFn(item); } + return null; + } + + _linkFn(item: any): string { + if (this.configuration.linkFn && item) { return this.configuration.linkFn(item); } + return null; + } + + _disableOption(item: any): boolean { + if (this.configuration.disableOption && item) { return this.configuration.disableOption(item); } + return null; + } + _requestDelay(): number { return this.configuration.requestDelay || this.requestDelay; } @@ -153,6 +173,13 @@ export class SingleAutoCompleteComponent implements OnInit, MatFormFieldControl< //this._inputValue = " "; this.stateChanges.next(); this.optionSelected.emit(event.option.value); + if (this.configuration.removeAfterSelection) { + this.clearAutocomplete() + } + } + + private clearAutocomplete() { + this._setValue(null); } private _setValue(value: any) { @@ -218,6 +245,13 @@ export class SingleAutoCompleteComponent implements OnInit, MatFormFieldControl< chipRemove(): void { this._setValue(null); + this.optionRemoved.emit(); + } + + linkToOption(value: any): void { + if (this._linkFn(value)) { + this.router.navigate([]).then(result => { window.open(this._linkFn(value), '_blank'); }); + } } autoCompleteDisplayFn() { diff --git a/dmp-frontend/src/app/library/confirmation-dialog/confirmation-dialog.component.html b/dmp-frontend/src/app/library/confirmation-dialog/confirmation-dialog.component.html index 233425676..59b533a6d 100644 --- a/dmp-frontend/src/app/library/confirmation-dialog/confirmation-dialog.component.html +++ b/dmp-frontend/src/app/library/confirmation-dialog/confirmation-dialog.component.html @@ -1,17 +1,31 @@
-
-
- {{ data.message }} +
+
+ {{ data.icon }}
-
close
+
{{ data.warning }}
+
+ close +
+
+
+
{{ data.message }}
+
+ close +
+
+
+
{{ data.privacyPolicyNames }}
+ + {{'GENERAL.CONFIRMATION-DIALOG.ACTIONS.POLICY-AGREE' | translate}} + +
{{'GENERAL.CONFIRMATION-DIALOG.ACTIONS.REQUIRED' | translate}}
-
-
-
+
+
+
+
diff --git a/dmp-frontend/src/app/library/confirmation-dialog/confirmation-dialog.component.scss b/dmp-frontend/src/app/library/confirmation-dialog/confirmation-dialog.component.scss index 98a0908bc..025bfb9d5 100644 --- a/dmp-frontend/src/app/library/confirmation-dialog/confirmation-dialog.component.scss +++ b/dmp-frontend/src/app/library/confirmation-dialog/confirmation-dialog.component.scss @@ -1,26 +1,44 @@ .confirmation-dialog { - .confirmation-message { - padding-bottom: 20px; - } + .confirmation { + padding-bottom: 20px; + } - .close-btn { - margin-left: auto; - cursor: pointer; - } + .privacy-policy-names { + font-weight: 700; + padding: 1em; + } - .cancel { - background-color: #aaaaaa; - color: #ffffff; - } + .close-btn { + margin-left: auto; + cursor: pointer; + } - .confirm { - background-color: #2cba6c; - color: #ffffff; - } + .warn-text { + color: #f44336; + } - .delete { - background-color: #ba2c2c; - color: #ffffff; - } + .cancel { + background-color: #aaaaaa; + color: #ffffff; + } + .confirm { + background-color: #2cba6c; + color: #ffffff; + } + + .delete { + background-color: #ba2c2c; + color: #ffffff; + } + + .checkbox-privacy { + padding: 0em 1em; + } + + .required-policy { + padding: 0em 1.2em 1em; + font-size: smaller; + color: #f44336; + } } diff --git a/dmp-frontend/src/app/library/confirmation-dialog/confirmation-dialog.component.ts b/dmp-frontend/src/app/library/confirmation-dialog/confirmation-dialog.component.ts index 26e1e63f3..cfb0f0b40 100644 --- a/dmp-frontend/src/app/library/confirmation-dialog/confirmation-dialog.component.ts +++ b/dmp-frontend/src/app/library/confirmation-dialog/confirmation-dialog.component.ts @@ -1,5 +1,5 @@ import { Component, Inject } from '@angular/core'; -import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material'; +import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; @Component({ selector: 'app-confirmation-dialog', @@ -8,6 +8,8 @@ import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material'; }) export class ConfirmationDialogComponent { + agreePrivacyPolicyNames = false; + constructor( public dialogRef: MatDialogRef, @Inject(MAT_DIALOG_DATA) public data: any diff --git a/dmp-frontend/src/app/library/contact-dialog/contact-dialog.component.html b/dmp-frontend/src/app/library/contact-dialog/contact-dialog.component.html deleted file mode 100644 index 5bd3b5757..000000000 --- a/dmp-frontend/src/app/library/contact-dialog/contact-dialog.component.html +++ /dev/null @@ -1,33 +0,0 @@ -
-
- {{'CONTACT.SUPPORT.SUBTITLE' | translate}} -
-
- close -
-
- -
-
- - - - - {{data.get('subject').getError('backendError').message}} - - {{'GENERAL.VALIDATION.REQUIRED' | translate}} - - - - - - {{data.get('description').getError('backendError').message}} - - {{'GENERAL.VALIDATION.REQUIRED' | translate}} - -
-
-
-
-
-
diff --git a/dmp-frontend/src/app/library/contact-dialog/contact-dialog.module.ts b/dmp-frontend/src/app/library/contact-dialog/contact-dialog.module.ts deleted file mode 100644 index a0fe4ea9f..000000000 --- a/dmp-frontend/src/app/library/contact-dialog/contact-dialog.module.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { NgModule } from '@angular/core'; -import { CommonUiModule } from '../../common/ui/common-ui.module'; -import { ContactDialogComponent } from './contact-dialog.component'; -import { FormsModule, ReactiveFormsModule } from '@angular/forms'; - -@NgModule({ - imports: [CommonUiModule, FormsModule, ReactiveFormsModule], - declarations: [ContactDialogComponent], - exports: [ContactDialogComponent], - entryComponents: [ContactDialogComponent] -}) -export class ContactDialogModule { - constructor() { } -} diff --git a/dmp-frontend/src/app/library/deactivate/can-deactivate.guard.ts b/dmp-frontend/src/app/library/deactivate/can-deactivate.guard.ts new file mode 100644 index 000000000..aac88736e --- /dev/null +++ b/dmp-frontend/src/app/library/deactivate/can-deactivate.guard.ts @@ -0,0 +1,39 @@ +import { Injectable } from '@angular/core'; +import { MatDialog } from '@angular/material/dialog'; +import { CanDeactivate } from '@angular/router'; +import { Observable } from 'rxjs'; +import { TranslateService } from '@ngx-translate/core'; +import { map } from 'rxjs/operators'; +import { BaseComponent } from '../../core/common/base/base.component'; +import { CheckDeactivateBaseComponent } from './deactivate.component'; +import { ConfirmationDialogComponent } from '../confirmation-dialog/confirmation-dialog.component'; + +@Injectable() +export class CanDeactivateGuard extends BaseComponent implements CanDeactivate { + + constructor( + private dialog: MatDialog, + public language: TranslateService + ) { + super(); + } + + canDeactivate(component: CheckDeactivateBaseComponent): boolean | Observable { + + if (component.canDeactivate()) { + return true; + } else { + const dialogRef = this.dialog.open(ConfirmationDialogComponent, { + maxWidth: '700px', + data: { + message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.LEAVE-PAGE'), + warning: this.language.instant('GENERAL.CONFIRMATION-DIALOG.LEAVE-WARNING'), + cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL'), + confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.LEAVE'), + icon: 'error_outline' + } + }); + return dialogRef.afterClosed().pipe(map(x => x ? true : false)); + } + } +} diff --git a/dmp-frontend/src/app/library/deactivate/deactivate.component.ts b/dmp-frontend/src/app/library/deactivate/deactivate.component.ts new file mode 100644 index 000000000..ce05a6632 --- /dev/null +++ b/dmp-frontend/src/app/library/deactivate/deactivate.component.ts @@ -0,0 +1,16 @@ +import { BaseComponent } from '../../core/common/base/base.component'; +import { HostListener } from '@angular/core'; + +export abstract class CheckDeactivateBaseComponent extends BaseComponent { + + protected constructor() { super(); } + + abstract canDeactivate(): boolean; + + @HostListener('window:beforeunload', ['$event']) + unloadNotification($event: any) { + if (!this.canDeactivate()) { + $event.returnValue = true; + } + } +} diff --git a/dmp-frontend/src/app/library/export-method-dialog/export-method-dialog.component.scss b/dmp-frontend/src/app/library/export-method-dialog/export-method-dialog.component.scss index 953b1843e..df9136d68 100644 --- a/dmp-frontend/src/app/library/export-method-dialog/export-method-dialog.component.scss +++ b/dmp-frontend/src/app/library/export-method-dialog/export-method-dialog.component.scss @@ -10,7 +10,7 @@ button { // background-color: #aaaaaa; - background-color: #4687f0; + background-color: #00b29f; color: #ffffff; } } diff --git a/dmp-frontend/src/app/library/export-method-dialog/export-method-dialog.component.ts b/dmp-frontend/src/app/library/export-method-dialog/export-method-dialog.component.ts index 2658b3ba7..37406942a 100644 --- a/dmp-frontend/src/app/library/export-method-dialog/export-method-dialog.component.ts +++ b/dmp-frontend/src/app/library/export-method-dialog/export-method-dialog.component.ts @@ -1,5 +1,5 @@ import { Component, OnInit, Inject } from '@angular/core'; -import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material'; +import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; @Component({ diff --git a/dmp-frontend/src/app/library/notification/notification.component.ts b/dmp-frontend/src/app/library/notification/notification.component.ts index a42d08a62..20527fe02 100644 --- a/dmp-frontend/src/app/library/notification/notification.component.ts +++ b/dmp-frontend/src/app/library/notification/notification.component.ts @@ -1,5 +1,6 @@ import { Component, OnInit } from '@angular/core'; -import { MatDialog, MatSnackBar } from '@angular/material'; +import { MatDialog } from '@angular/material/dialog'; +import { MatSnackBar } from '@angular/material/snack-bar'; import { takeUntil } from 'rxjs/operators'; import { BaseComponent } from '../../core/common/base/base.component'; import { UiNotificationService, UiNotificationType, PopupNotification, SnackBarNotification, SnackBarNotificationLevel } from '../../core/services/notification/ui-notification-service'; diff --git a/dmp-frontend/src/app/library/notification/popup/popup-notification.component.html b/dmp-frontend/src/app/library/notification/popup/popup-notification.component.html index 47795943f..3e0877065 100644 --- a/dmp-frontend/src/app/library/notification/popup/popup-notification.component.html +++ b/dmp-frontend/src/app/library/notification/popup/popup-notification.component.html @@ -1,5 +1,5 @@

{{notification.title}}

{{notification.message}} - - + + diff --git a/dmp-frontend/src/app/library/notification/popup/popup-notification.component.ts b/dmp-frontend/src/app/library/notification/popup/popup-notification.component.ts index 84a11666a..b672e34f6 100644 --- a/dmp-frontend/src/app/library/notification/popup/popup-notification.component.ts +++ b/dmp-frontend/src/app/library/notification/popup/popup-notification.component.ts @@ -1,5 +1,5 @@ import { Component, Inject } from '@angular/core'; -import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material'; +import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; import { PopupNotification } from '../../../core/services/notification/ui-notification-service'; @Component({ diff --git a/dmp-frontend/src/app/library/notification/snack-bar/snack-bar-notification.component.html b/dmp-frontend/src/app/library/notification/snack-bar/snack-bar-notification.component.html index 75af56131..29e4f7ad5 100644 --- a/dmp-frontend/src/app/library/notification/snack-bar/snack-bar-notification.component.html +++ b/dmp-frontend/src/app/library/notification/snack-bar/snack-bar-notification.component.html @@ -1 +1 @@ -{{message}} +{{message}} diff --git a/dmp-frontend/src/app/library/notification/snack-bar/snack-bar-notification.component.scss b/dmp-frontend/src/app/library/notification/snack-bar/snack-bar-notification.component.scss new file mode 100644 index 000000000..bfbfa5beb --- /dev/null +++ b/dmp-frontend/src/app/library/notification/snack-bar/snack-bar-notification.component.scss @@ -0,0 +1,3 @@ +.snackBar { + color: white; +} diff --git a/dmp-frontend/src/app/library/notification/snack-bar/snack-bar-notification.component.ts b/dmp-frontend/src/app/library/notification/snack-bar/snack-bar-notification.component.ts index 2af227f3c..ff8745b38 100644 --- a/dmp-frontend/src/app/library/notification/snack-bar/snack-bar-notification.component.ts +++ b/dmp-frontend/src/app/library/notification/snack-bar/snack-bar-notification.component.ts @@ -1,10 +1,11 @@ import { Component, Inject } from '@angular/core'; -import { MAT_SNACK_BAR_DATA } from '@angular/material'; +import { MAT_SNACK_BAR_DATA } from '@angular/material/snack-bar'; import { SnackBarNotification } from '../../../core/services/notification/ui-notification-service'; @Component({ selector: 'app-snack-bar-notification', - templateUrl: './snack-bar-notification.component.html' + templateUrl: './snack-bar-notification.component.html', + styleUrls: ['./snack-bar-notification.component.scss'] }) export class SnackBarNotificationComponent { diff --git a/dmp-frontend/src/app/ui/admin/dataset-profile/admin/field-editor-model.ts b/dmp-frontend/src/app/ui/admin/dataset-profile/admin/field-editor-model.ts index ff076d543..d80d1ebbf 100644 --- a/dmp-frontend/src/app/ui/admin/dataset-profile/admin/field-editor-model.ts +++ b/dmp-frontend/src/app/ui/admin/dataset-profile/admin/field-editor-model.ts @@ -30,6 +30,7 @@ export class FieldEditorModel extends BaseFormModel { public visible: VisibilityEditorModel = new VisibilityEditorModel(); public data: FieldDataEditorModel; public validations: ValidationType[] = []; + public rdaCommonStandard: string; fromModel(item: Field): FieldEditorModel { this.id = item.id; @@ -39,6 +40,7 @@ export class FieldEditorModel extends BaseFormModel { this.validations = item.validations; this.viewStyle = new ViewStyleEditorModel().fromModel(item.viewStyle); this.visible = new VisibilityEditorModel().fromModel(item.visible); + this.rdaCommonStandard = item.rdaCommonStandard; if (item.data) { if (this.viewStyle.renderStyle === 'combobox') { @@ -66,7 +68,8 @@ export class FieldEditorModel extends BaseFormModel { // title: [this.title], page: [{ value: this.page, disabled: (disabled && !skipDisable.includes('FieldEditorModel.page')) }], ordinal: [{ value: this.ordinal, disabled: (disabled && !skipDisable.includes('FieldEditorModel.ordinal')) }], - validations: [{ value: this.validations, disabled: (disabled && !skipDisable.includes('FieldEditorModel.validations')) }] + validations: [{ value: this.validations, disabled: (disabled && !skipDisable.includes('FieldEditorModel.validations')) }], + rdaCommonStandard: [{value: this.rdaCommonStandard, disabled: (disabled && !skipDisable.includes('FieldSetEditorModel.rdaCommonStandard')) }] }); formGroup.addControl('defaultValue', this.defaultValue.buildForm(disabled, skipDisable)); diff --git a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/composite-field/dataset-profile-editor-composite-field.component.html b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/composite-field/dataset-profile-editor-composite-field.component.html index 5e3d64c3e..6de806122 100644 --- a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/composite-field/dataset-profile-editor-composite-field.component.html +++ b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/composite-field/dataset-profile-editor-composite-field.component.html @@ -4,7 +4,7 @@ {{'DATASET-PROFILE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.COMPOSITE-CHECKBOX' | translate}} {{'DATASET-PROFILE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.MULTIPLICITY-CHECKBOX' | translate}} - {{'DATASET-PROFILE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.COMMENT-CHECKBOX' | translate}} + {{'DATASET-PROFILE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.COMMENT-CHECKBOX' | translate}}
@@ -34,7 +34,7 @@ + [formControl]="this.form.get('ordinal')" required>
diff --git a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/composite-field/dataset-profile-editor-composite-field.component.ts b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/composite-field/dataset-profile-editor-composite-field.component.ts index 256a522fc..e0ed0479f 100644 --- a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/composite-field/dataset-profile-editor-composite-field.component.ts +++ b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/composite-field/dataset-profile-editor-composite-field.component.ts @@ -1,7 +1,7 @@ import { Component, Input, OnInit } from '@angular/core'; import { FormArray, FormControl, FormGroup } from '@angular/forms'; import { FieldEditorModel } from '../../../admin/field-editor-model'; -import { FieldSetEditorModel } from '../../../admin/field-set-editor-model'; +import { Guid } from '../../../../../../common/types/guid'; @Component({ selector: 'app-dataset-profile-editor-composite-field-component', @@ -27,6 +27,10 @@ export class DatasetProfileEditorCompositeFieldComponent implements OnInit { } } this.isComposite = (this.form.get('fields') as FormArray).length > 1; + + if (this.viewOnly) { + this.form.get('hasCommentField').disable(); + } } onIsCompositeChange(isComposite: boolean) { @@ -51,6 +55,7 @@ export class DatasetProfileEditorCompositeFieldComponent implements OnInit { addNewField() { const field: FieldEditorModel = new FieldEditorModel(); + field.id=Guid.create().toString(); (this.form.get('fields')).push(field.buildForm()); } diff --git a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/composite-profile-editor-default-value/component-profile-editor-default-value.component.html b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/composite-profile-editor-default-value/component-profile-editor-default-value.component.html index 446ad980a..b9c42bc35 100644 --- a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/composite-profile-editor-default-value/component-profile-editor-default-value.component.html +++ b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/composite-profile-editor-default-value/component-profile-editor-default-value.component.html @@ -1,84 +1,79 @@
- - - - {{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.DEFAULT-VALUES.NONE' | + + + + {{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.DEFAULT-VALUES.NONE' | translate}} - {{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.DEFAULT-VALUES.BOOLEAN-DECISION.YES' + {{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.DEFAULT-VALUES.BOOLEAN-DECISION.YES' | translate}} - {{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.DEFAULT-VALUES.BOOLEAN-DECISION.NO' + {{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.DEFAULT-VALUES.BOOLEAN-DECISION.NO' | translate}} - - {{'GENERAL.VALIDATION.REQUIRED' | translate}} - + + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + - - - - {{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.DEFAULT-VALUES.CHECK-BOX.CHECKED' | - translate}} - {{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.DEFAULT-VALUES.CHECK-BOX.UNCHECKED' - | - translate}} - - {{'GENERAL.VALIDATION.REQUIRED' | translate}} - + + + + {{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.DEFAULT-VALUES.CHECK-BOX.CHECKED' | translate}} + {{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.DEFAULT-VALUES.CHECK-BOX.UNCHECKED' | translate}} + + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + - - - - - - - {{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.DEFAULT-VALUES.NONE' | translate }} - {{opt.get('label').value}} - - {{'GENERAL.VALIDATION.REQUIRED' | translate}} - + + + + + + + {{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.DEFAULT-VALUES.NONE' | translate }} + {{opt.get('label').value}} + + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + - - + + - + - - + + - - - - {{'GENERAL.VALIDATION.REQUIRED' | translate}} - + + + + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + - - - - {{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.DEFAULT-VALUES.NONE' | translate}} - {{opt.get('label').value}} - - {{'GENERAL.VALIDATION.REQUIRED' | translate}} - + + + + {{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.DEFAULT-VALUES.NONE' | translate}} + {{opt.get('label').value}} + + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + - - - - {{'GENERAL.VALIDATION.REQUIRED' | translate}} - + + + + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + - - - - - - - {{'GENERAL.VALIDATION.REQUIRED' | translate}} - - + + + + + + + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
diff --git a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/field/dataset-profile-editor-field.component.html b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/field/dataset-profile-editor-field.component.html index 0e0547147..20c5d1371 100644 --- a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/field/dataset-profile-editor-field.component.html +++ b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/field/dataset-profile-editor-field.component.html @@ -11,18 +11,21 @@ required> {{enumUtils.toDatasetProfileFieldViewStyleString(viewStyleEnum.BooleanDecision)}} {{enumUtils.toDatasetProfileFieldViewStyleString(viewStyleEnum.CheckBox)}} + {{enumUtils.toDatasetProfileFieldViewStyleString(viewStyleEnum.TextArea)}} + {{enumUtils.toDatasetProfileFieldViewStyleString(viewStyleEnum.FreeText)}} {{enumUtils.toDatasetProfileFieldViewStyleString(viewStyleEnum.ComboBox)}} {{enumUtils.toDatasetProfileFieldViewStyleString(viewStyleEnum.InternalDmpEntities)}} - {{enumUtils.toDatasetProfileFieldViewStyleString(viewStyleEnum.FreeText)}} {{enumUtils.toDatasetProfileFieldViewStyleString(viewStyleEnum.RadioBox)}} - {{enumUtils.toDatasetProfileFieldViewStyleString(viewStyleEnum.TextArea)}} {{enumUtils.toDatasetProfileFieldViewStyleString(viewStyleEnum.DatePicker)}} {{'GENERAL.VALIDATION.REQUIRED' | translate}} + + - + + + @@ -37,6 +41,16 @@ + + {{'DATASET-PROFILE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.RDA-COMMON-STANDARDS' | translate}} + + -- + + {{property}} + + + +
diff --git a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/field/dataset-profile-editor-field.component.scss b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/field/dataset-profile-editor-field.component.scss index 946679a44..3db0dee74 100644 --- a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/field/dataset-profile-editor-field.component.scss +++ b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/field/dataset-profile-editor-field.component.scss @@ -1,3 +1,3 @@ -.full-width{ - width: 100%; -} \ No newline at end of file +.full-width { + width: 100%; +} diff --git a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/field/dataset-profile-editor-field.component.ts b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/field/dataset-profile-editor-field.component.ts index 1d109c26e..bdc243b73 100644 --- a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/field/dataset-profile-editor-field.component.ts +++ b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/field/dataset-profile-editor-field.component.ts @@ -16,6 +16,7 @@ import { RuleEditorModel } from '../../../admin/rule-editor-model'; import { DatePickerDataEditorModel } from '../../../admin/field-data/date-picker-data-editor-models'; import { ResearchersAutoCompleteFieldDataEditorModel } from '../../../admin/field-data/researchers-auto-complete-field-data-editor-model'; import { DatasetProfileInternalDmpEntitiesType } from '../../../../../../core/common/enum/dataset-profile-internal-dmp-entities-type'; +import { DatasetProfileService } from "../../../../../../core/services/dataset-profile/dataset-profile.service"; @Component({ selector: 'app-dataset-profile-editor-field-component', @@ -33,7 +34,8 @@ export class DatasetProfileEditorFieldComponent extends BaseComponent implements constructor( - public enumUtils: EnumUtils + public enumUtils: EnumUtils, + public datasetProfileService: DatasetProfileService ) { super(); } ngOnInit() { diff --git a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/section/dataset-profile-editor-section.component.ts b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/section/dataset-profile-editor-section.component.ts index 98b885051..92a3dc424 100644 --- a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/section/dataset-profile-editor-section.component.ts +++ b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/section/dataset-profile-editor-section.component.ts @@ -32,6 +32,7 @@ export class DatasetProfileEditorSectionComponent extends BaseComponent implemen addField() { const fieldSet: FieldSetEditorModel = new FieldSetEditorModel(); const field: FieldEditorModel = new FieldEditorModel(); + field.id=Guid.create().toString(); fieldSet.fields.push(field); if (this.dataModel.fieldSets) { fieldSet.id=Guid.create().toString(); diff --git a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/dataset-profile-editor.component.html b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/dataset-profile-editor.component.html index 65945f77d..18bce0c76 100644 --- a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/dataset-profile-editor.component.html +++ b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/dataset-profile-editor.component.html @@ -9,17 +9,20 @@ {{'DATASET-PROFILE-EDITOR.TITLE.NEW-PROFILE-VERSION' | translate}} {{form.get('label').value}} +

{{form.get('label').value}}

- + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + - + {{'GENERAL.VALIDATION.REQUIRED' | translate}} +
diff --git a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/dataset-profile-editor.component.ts b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/dataset-profile-editor.component.ts index 0f3b1ece8..1307ab4c7 100644 --- a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/dataset-profile-editor.component.ts +++ b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/dataset-profile-editor.component.ts @@ -1,7 +1,10 @@ -import { HttpErrorResponse } from '@angular/common/http'; + +import { of as observableOf, Observable } from 'rxjs'; +import { HttpErrorResponse } from '@angular/common/http'; import { Component, OnInit, ViewChild } from '@angular/core'; import { FormArray, FormControl, FormGroup } from '@angular/forms'; -import { MatHorizontalStepper, MatDialog } from '@angular/material'; +import { MatDialog } from '@angular/material/dialog'; +import { MatHorizontalStepper } from '@angular/material/stepper'; import { ActivatedRoute, ParamMap, Router } from '@angular/router'; import { TranslateService } from '@ngx-translate/core'; import { map, takeUntil } from 'rxjs/operators'; @@ -18,7 +21,6 @@ import { ConfirmationDialogComponent } from '../../../../library/confirmation-di import { DatasetProfileEnum } from '../../../../core/common/enum/dataset-profile'; import * as FileSaver from 'file-saver'; import { BreadcrumbItem } from '../../../misc/breadcrumb/definition/breadcrumb-item'; -import { Observable } from 'rxjs'; import { DatasetStatus } from '../../../../core/common/enum/dataset-status'; //import * as data from 'src/assets/resources/skipDisable.json'; @@ -42,7 +44,7 @@ export class DatasetProfileEditorComponent extends BaseComponent implements OnIn newVersionId: string; dataWizardModel: DatasetWizardModel; breadCrumbs: Observable; - @ViewChild('stepper') stepper: MatHorizontalStepper; + @ViewChild('stepper', { static: false }) stepper: MatHorizontalStepper; viewOnly = false; constructor( @@ -70,67 +72,68 @@ export class DatasetProfileEditorComponent extends BaseComponent implements OnIn this.datasetProfileService.getDatasetProfileById(this.datasetProfileId) .pipe(map(data => data as DatasetProfile), takeUntil(this._destroyed)) .subscribe( - data => { - try { - this.dataModel = new DatasetProfileEditorModel().fromModel(data); - // this.isDeleted = this.masterItem.isActive === IsActive.Inactive; - if (this.dataModel.status === DatasetProfileEnum.FINALIZED) { - this.form = this.dataModel.buildForm(true, skipDisable); - this.viewOnly = true; - } else { - this.form = this.dataModel.buildForm(); + data => { + try { + this.dataModel = new DatasetProfileEditorModel().fromModel(data); + // this.isDeleted = this.masterItem.isActive === IsActive.Inactive; + if (this.dataModel.status === DatasetProfileEnum.FINALIZED) { + this.form = this.dataModel.buildForm(true, skipDisable); + this.viewOnly = true; + } else { + this.form = this.dataModel.buildForm(); + } + this.prepareForm(); + } catch { + this.logger.error('Could not parse MasterItem: ' + data); + this.uiNotificationService.snackBarNotification(this.language.instant('NOTIFICATIONS.DEFAULT.ERROR'), SnackBarNotificationLevel.Error); } - this.prepareForm(); - } catch { - this.logger.error('Could not parse MasterItem: ' + data); - this.uiNotificationService.snackBarNotification(this.language.instant('NOTIFICATIONS.DEFAULT.ERROR'), SnackBarNotificationLevel.Error); - } - }, - error => this.onCallbackError(error) + }, + error => this.onCallbackError(error) ); - this.breadCrumbs = Observable.of([{ - parentComponentName: 'DatasetProfileListingComponent', - label: this.language.instant('NAV-BAR.TEMPLATE'), - url: '/dataset-profiles/' + this.datasetProfileId - }]); + this.breadCrumbs = observableOf([{ + parentComponentName: 'DatasetProfileListingComponent', + label: this.language.instant('NAV-BAR.TEMPLATE'), + url: '/dataset-profiles/' + this.datasetProfileId + }]); } else if (cloneId != null) { this.isClone = true; this.datasetProfileService.clone(cloneId) .pipe(map(data => data as DatasetProfile), takeUntil(this._destroyed)) .subscribe( - data => { - try { - this.dataModel = new DatasetProfileEditorModel().fromModel(data); - // this.isDeleted = this.masterItem.isActive === IsActive.Inactive; - this.dataModel.status = DatasetProfileEnum.SAVED; - this.form = this.dataModel.buildForm(); - this.prepareForm(); - } catch { - this.logger.error('Could not parse MasterItem: ' + data); - this.uiNotificationService.snackBarNotification(this.language.instant('NOTIFICATIONS.DEFAULT.ERROR'), SnackBarNotificationLevel.Error); - } - }, - error => this.onCallbackError(error) + data => { + try { + this.dataModel = new DatasetProfileEditorModel().fromModel(data); + // this.isDeleted = this.masterItem.isActive === IsActive.Inactive; + this.dataModel.status = DatasetProfileEnum.SAVED; + this.form = this.dataModel.buildForm(); + this.prepareForm(); + } catch { + this.logger.error('Could not parse MasterItem: ' + data); + this.uiNotificationService.snackBarNotification(this.language.instant('NOTIFICATIONS.DEFAULT.ERROR'), SnackBarNotificationLevel.Error); + } + }, + error => this.onCallbackError(error) ); } else if (this.newVersionId != null) { this.isNewVersion = true; this.datasetProfileService.getDatasetProfileById(this.newVersionId) .pipe(map(data => data as DatasetProfile), takeUntil(this._destroyed)) .subscribe( - data => { - try { - this.dataModel = new DatasetProfileEditorModel().fromModel(data); - // this.isDeleted = this.masterItem.isActive === IsActive.Inactive; - this.form = this.dataModel.buildForm(); - this.form.get('version').setValue(this.form.get('version').value + 1); - this.form.controls['label'].disable(); - this.prepareForm(); - } catch { - this.logger.error('Could not parse MasterItem: ' + data); - this.uiNotificationService.snackBarNotification(this.language.instant('NOTIFICATIONS.DEFAULT.ERROR'), SnackBarNotificationLevel.Error); - } - }, - error => this.onCallbackError(error) + data => { + try { + this.dataModel = new DatasetProfileEditorModel().fromModel(data); + // this.isDeleted = this.masterItem.isActive === IsActive.Inactive; + this.form = this.dataModel.buildForm(); + this.form.get('version').setValue(this.form.get('version').value + 1); + this.form.controls['label'].disable(); + this.form.controls['description'].disable(); + this.prepareForm(); + } catch { + this.logger.error('Could not parse MasterItem: ' + data); + this.uiNotificationService.snackBarNotification(this.language.instant('NOTIFICATIONS.DEFAULT.ERROR'), SnackBarNotificationLevel.Error); + } + }, + error => this.onCallbackError(error) ); } else { this.dataModel = new DatasetProfileEditorModel(); @@ -199,7 +202,7 @@ export class DatasetProfileEditorComponent extends BaseComponent implements OnIn .subscribe(() => { this.router.navigate(['/dataset-profiles']); }, - error => this.onCallbackErrorNewVersion(error) + error => this.onCallbackErrorNewVersion(error) ); } else { this.form.get('status').setValue(DatasetStatus.Draft); @@ -246,6 +249,7 @@ export class DatasetProfileEditorComponent extends BaseComponent implements OnIn public delete(): void { if (this.datasetProfileId && !this.isNew) { const dialogRef = this.dialog.open(ConfirmationDialogComponent, { + restoreFocus: false, data: { message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.DELETE-ITEM'), confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CONFIRM'), @@ -259,18 +263,18 @@ export class DatasetProfileEditorComponent extends BaseComponent implements OnIn this.datasetProfileService.delete(this.datasetProfileId, this.form.value) .pipe(takeUntil(this._destroyed)) .subscribe( - complete => { - this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-DATASET-PROFILE-DELETE'), SnackBarNotificationLevel.Success); - this.router.navigate(['/dataset-profiles']); - }, - error => { - this.onCallbackError(error); - if (error.error.statusCode == 674) { - this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-DATASET-PROFILE-DELETE'), SnackBarNotificationLevel.Error); - } else { - this.uiNotificationService.snackBarNotification(this.language.instant(error.message), SnackBarNotificationLevel.Error); + complete => { + this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-DATASET-PROFILE-DELETE'), SnackBarNotificationLevel.Success); + this.router.navigate(['/dataset-profiles']); + }, + error => { + this.onCallbackError(error); + if (error.error.statusCode == 674) { + this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-DATASET-PROFILE-DELETE'), SnackBarNotificationLevel.Error); + } else { + this.uiNotificationService.snackBarNotification(this.language.instant(error.message), SnackBarNotificationLevel.Error); + } } - } ); } }); diff --git a/dmp-frontend/src/app/ui/admin/dataset-profile/listing/criteria/dataset-profile.component.ts b/dmp-frontend/src/app/ui/admin/dataset-profile/listing/criteria/dataset-profile.component.ts index 645bbf351..3b39d931b 100644 --- a/dmp-frontend/src/app/ui/admin/dataset-profile/listing/criteria/dataset-profile.component.ts +++ b/dmp-frontend/src/app/ui/admin/dataset-profile/listing/criteria/dataset-profile.component.ts @@ -1,5 +1,5 @@ import { Component, OnInit } from '@angular/core'; -import { MatDialog } from '@angular/material'; +import { MatDialog } from '@angular/material/dialog'; import { TranslateService } from '@ngx-translate/core'; import { takeUntil } from 'rxjs/operators'; import { ValidationErrorModel } from '../../../../../common/forms/validation/error-model/validation-error-model'; @@ -49,6 +49,8 @@ export class DatasetProfileCriteriaComponent extends BaseCriteriaComponent imple openDialog(): void { const dialogRef = this.dialog.open(DialodConfirmationUploadDatasetProfiles, { + width: '500px', + restoreFocus: false, data: { message: this.language.instant('DATASET-WIZARD.UPLOAD.UPLOAD-XML-FILE-TITLE'), confirmButton: this.language.instant('DATASET-WIZARD.UPLOAD.UPLOAD-XML'), diff --git a/dmp-frontend/src/app/ui/admin/dataset-profile/listing/criteria/dialog-confirmation-upload-profile/dialog-confirmation-upload-profiles.component.html b/dmp-frontend/src/app/ui/admin/dataset-profile/listing/criteria/dialog-confirmation-upload-profile/dialog-confirmation-upload-profiles.component.html index e38401954..dec3649ac 100644 --- a/dmp-frontend/src/app/ui/admin/dataset-profile/listing/criteria/dialog-confirmation-upload-profile/dialog-confirmation-upload-profiles.component.html +++ b/dmp-frontend/src/app/ui/admin/dataset-profile/listing/criteria/dialog-confirmation-upload-profile/dialog-confirmation-upload-profiles.component.html @@ -15,7 +15,7 @@
- +
diff --git a/dmp-frontend/src/app/ui/admin/dataset-profile/listing/criteria/dialog-confirmation-upload-profile/dialog-confirmation-upload-profiles.component.ts b/dmp-frontend/src/app/ui/admin/dataset-profile/listing/criteria/dialog-confirmation-upload-profile/dialog-confirmation-upload-profiles.component.ts index e72e64e55..8db9791c4 100644 --- a/dmp-frontend/src/app/ui/admin/dataset-profile/listing/criteria/dialog-confirmation-upload-profile/dialog-confirmation-upload-profiles.component.ts +++ b/dmp-frontend/src/app/ui/admin/dataset-profile/listing/criteria/dialog-confirmation-upload-profile/dialog-confirmation-upload-profiles.component.ts @@ -1,4 +1,4 @@ -import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material'; +import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; import { Inject, Component } from '@angular/core'; diff --git a/dmp-frontend/src/app/ui/admin/dataset-profile/listing/dataset-profile-listing.component.scss b/dmp-frontend/src/app/ui/admin/dataset-profile/listing/dataset-profile-listing.component.scss index 6bf311012..2eb955561 100644 --- a/dmp-frontend/src/app/ui/admin/dataset-profile/listing/dataset-profile-listing.component.scss +++ b/dmp-frontend/src/app/ui/admin/dataset-profile/listing/dataset-profile-listing.component.scss @@ -33,7 +33,8 @@ mat-row:hover { // } mat-row:nth-child(odd) { - background-color: #eef0fb; + background-color: #0c748914; + // background-color: #eef0fb; } ::ng-deep .mat-paginator-container { diff --git a/dmp-frontend/src/app/ui/admin/dataset-profile/listing/dataset-profile-listing.component.ts b/dmp-frontend/src/app/ui/admin/dataset-profile/listing/dataset-profile-listing.component.ts index 5b6db04b5..ffa8c646b 100644 --- a/dmp-frontend/src/app/ui/admin/dataset-profile/listing/dataset-profile-listing.component.ts +++ b/dmp-frontend/src/app/ui/admin/dataset-profile/listing/dataset-profile-listing.component.ts @@ -1,9 +1,11 @@ import { DataSource } from '@angular/cdk/table'; import { Component, OnInit, ViewChild } from '@angular/core'; -import { MatPaginator, MatSort, PageEvent } from '@angular/material'; +import { MatPaginator, PageEvent } from '@angular/material/paginator'; +import { MatSort } from '@angular/material/sort'; import { ActivatedRoute, Params, Router } from '@angular/router'; -import { Observable } from 'rxjs'; -import { takeUntil } from 'rxjs/operators'; +import { TranslateService } from '@ngx-translate/core'; +import { merge as observableMerge, Observable, of as observableOf } from 'rxjs'; +import { map, startWith, switchMap, takeUntil } from 'rxjs/operators'; import { BaseComponent } from '../../../../core/common/base/base.component'; import { DataTableRequest } from '../../../../core/model/data-table/data-table-request'; import { DatasetListingModel } from '../../../../core/model/dataset/dataset-listing'; @@ -11,11 +13,9 @@ import { DmpModel } from '../../../../core/model/dmp/dmp'; import { DatasetProfileCriteria } from '../../../../core/query/dataset-profile/dataset-profile-criteria'; import { DatasetProfileService } from '../../../../core/services/dataset-profile/dataset-profile.service'; import { DmpService } from '../../../../core/services/dmp/dmp.service'; -import { DatasetProfileCriteriaComponent } from './criteria/dataset-profile.component'; -import { error } from 'selenium-webdriver'; -import { UiNotificationService, SnackBarNotificationLevel } from '../../../../core/services/notification/ui-notification-service'; -import { TranslateService } from '@ngx-translate/core'; +import { UiNotificationService } from '../../../../core/services/notification/ui-notification-service'; import { BreadcrumbItem } from '../../../misc/breadcrumb/definition/breadcrumb-item'; +import { DatasetProfileCriteriaComponent } from './criteria/dataset-profile.component'; @Component({ selector: 'app-dataset-profile-listing-component', @@ -24,9 +24,9 @@ import { BreadcrumbItem } from '../../../misc/breadcrumb/definition/breadcrumb-i }) export class DatasetProfileListingComponent extends BaseComponent implements OnInit { - @ViewChild(MatPaginator) _paginator: MatPaginator; - @ViewChild(MatSort) sort: MatSort; - @ViewChild(DatasetProfileCriteriaComponent) criteria: DatasetProfileCriteriaComponent; + @ViewChild(MatPaginator, { static: true }) _paginator: MatPaginator; + @ViewChild(MatSort, { static: true }) sort: MatSort; + @ViewChild(DatasetProfileCriteriaComponent, { static: true }) criteria: DatasetProfileCriteriaComponent; breadCrumbs: Observable; dataSource: DatasetDataSource | null; @@ -70,7 +70,7 @@ export class DatasetProfileListingComponent extends BaseComponent implements OnI this.criteria.setCriteria(this.getDefaultCriteria()); this.refresh(); this.criteria.setRefreshCallback(() => this.refresh()); - this.breadCrumbs = Observable.of([{ + this.breadCrumbs = observableOf([{ parentComponentName: null, label: this.language.instant('NAV-BAR.DATASET-TEMPLATES'), url: '/dataset-profiles' @@ -80,7 +80,7 @@ export class DatasetProfileListingComponent extends BaseComponent implements OnI } setDmpTitle(dmpId: String) { - this.dmpService.getSingle(dmpId).map(data => data as DmpModel) + this.dmpService.getSingle(dmpId).pipe(map(data => data as DmpModel)) .pipe(takeUntil(this._destroyed)) .subscribe(data => { this.titlePrefix = data.label; @@ -140,9 +140,9 @@ export class DatasetDataSource extends DataSource { //this._sort.matSortChange ]; - return Observable.merge(...displayDataChanges) - .startWith(null) - .switchMap(() => { + return observableMerge(...displayDataChanges).pipe( + startWith(null), + switchMap(() => { const startIndex = this._paginator.pageIndex * this._paginator.pageSize; let fields: Array = new Array(); if (this._sort.active) { fields = this._sort.direction === 'asc' ? ['+' + this._sort.active] : ['-' + this._sort.active]; } @@ -153,7 +153,7 @@ export class DatasetDataSource extends DataSource { request.criteria.allVersions = true; } return this._service.getPaged(request); - }) + }), /*.catch((error: any) => { this._snackBar.openFromComponent(SnackBarNotificationComponent, { data: { message: 'GENERAL.SNACK-BAR.FORMS-BAD-REQUEST', language: this._languageService }, @@ -163,14 +163,14 @@ export class DatasetDataSource extends DataSource { //this._criteria.criteria.onCallbackError(error); return Observable.of(null); })*/ - .map(result => { + map(result => { return result; - }) - .map(result => { + }), + map(result => { if (!result) { return []; } if (this._paginator.pageIndex === 0) { this.totalCount = result.totalCount; } return result.data; - }); + })); } disconnect() { diff --git a/dmp-frontend/src/app/ui/admin/dataset-profile/preview/dataset-profile-preview.component.ts b/dmp-frontend/src/app/ui/admin/dataset-profile/preview/dataset-profile-preview.component.ts index a8daf5820..97ea7d06d 100644 --- a/dmp-frontend/src/app/ui/admin/dataset-profile/preview/dataset-profile-preview.component.ts +++ b/dmp-frontend/src/app/ui/admin/dataset-profile/preview/dataset-profile-preview.component.ts @@ -1,6 +1,6 @@ import { Component, Inject, OnInit } from '@angular/core'; import { FormGroup } from '@angular/forms'; -import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material'; +import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; import { takeUntil } from 'rxjs/operators'; import { BaseComponent } from '../../../../core/common/base/base.component'; import { DatasetProfileService } from '../../../../core/services/dataset-profile/dataset-profile.service'; diff --git a/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-profile-editor.component.scss b/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-profile-editor.component.scss index 25d42604c..b0459dd25 100644 --- a/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-profile-editor.component.scss +++ b/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-profile-editor.component.scss @@ -16,7 +16,8 @@ } ::ng-deep .mat-checkbox-checked.mat-accent .mat-checkbox-background, .mat-checkbox-indeterminate.mat-accent .mat-checkbox-background { - background-color: #0070c0; + background-color: #00b29f; + // background-color: #0070c0; } ::ng-deep .mat-checkbox-disabled.mat-checkbox-checked .mat-checkbox-background, .mat-checkbox-disabled.mat-checkbox-indeterminate .mat-checkbox-background { diff --git a/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-profile-editor.component.ts b/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-profile-editor.component.ts index 0254b95a0..f56b1843f 100644 --- a/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-profile-editor.component.ts +++ b/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-profile-editor.component.ts @@ -1,9 +1,12 @@ + +import {of as observableOf, Observable } from 'rxjs'; + +import {map, takeUntil } from 'rxjs/operators'; import { AfterViewInit, Component, OnInit } from '@angular/core'; import { AbstractControl, FormArray, FormControl, FormGroup } from '@angular/forms'; import { ActivatedRoute, Params, Router } from '@angular/router'; import { TranslateService } from '@ngx-translate/core'; import * as FileSaver from 'file-saver'; -import { takeUntil } from 'rxjs/operators'; import { environment } from '../../../../../environments/environment'; import { ValidationErrorModel } from '../../../../common/forms/validation/error-model/validation-error-model'; import { BaseComponent } from '../../../../core/common/base/base.component'; @@ -16,7 +19,6 @@ import { SnackBarNotificationLevel, UiNotificationService } from '../../../../co import { EnumUtils } from '../../../../core/services/utilities/enum-utils.service'; import { DmpProfileEditorModel, DmpProfileFieldEditorModel } from './dmp-profile-editor.model'; import { BreadcrumbItem } from '../../../misc/breadcrumb/definition/breadcrumb-item'; -import { Observable } from 'rxjs'; import { DmpProfileExternalAutoCompleteFieldDataEditorModel } from './external-autocomplete/dmp-profile-external-autocomplete-field-editor.model'; @Component({ @@ -53,7 +55,7 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie if (this.dmpProfileId != null) { this.isNew = false; - this.dmpProfileService.getSingle(this.dmpProfileId).map(data => data as DmpProfile) + this.dmpProfileService.getSingle(this.dmpProfileId).pipe(map(data => data as DmpProfile)) .pipe(takeUntil(this._destroyed)) .subscribe(data => { this.dmpProfileModel = new DmpProfileEditorModel().fromModel(data); @@ -62,7 +64,7 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie this.formGroup.disable(); this.viewOnly = true } - this.breadCrumbs = Observable.of([{ + this.breadCrumbs = observableOf([{ parentComponentName: 'DmpProfileListingComponent', label: this.language.instant('NAV-BAR.TEMPLATE'), url: '/dmp-profiles/' + this.dmpProfileId @@ -74,7 +76,7 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie this.formGroup = this.dmpProfileModel.buildForm(); this.addField(); }); - this.breadCrumbs = Observable.of([{ + this.breadCrumbs = observableOf([{ parentComponentName: 'DmpProfileListingComponent', label: this.language.instant('NAV-BAR.TEMPLATE'), url: '/dmp-profiles/' + this.dmpProfileId diff --git a/dmp-frontend/src/app/ui/admin/dmp-profile/listing/criteria/dialog-confirmation-upload-profile/dialog-confirmation-upload-profiles.component.html b/dmp-frontend/src/app/ui/admin/dmp-profile/listing/criteria/dialog-confirmation-upload-profile/dialog-confirmation-upload-profiles.component.html index 0f3cf0408..83c70604d 100644 --- a/dmp-frontend/src/app/ui/admin/dmp-profile/listing/criteria/dialog-confirmation-upload-profile/dialog-confirmation-upload-profiles.component.html +++ b/dmp-frontend/src/app/ui/admin/dmp-profile/listing/criteria/dialog-confirmation-upload-profile/dialog-confirmation-upload-profiles.component.html @@ -15,7 +15,7 @@
- +
diff --git a/dmp-frontend/src/app/ui/admin/dmp-profile/listing/criteria/dialog-confirmation-upload-profile/dialog-confirmation-upload-profiles.component.ts b/dmp-frontend/src/app/ui/admin/dmp-profile/listing/criteria/dialog-confirmation-upload-profile/dialog-confirmation-upload-profiles.component.ts index 0846e2896..42a7dfa61 100644 --- a/dmp-frontend/src/app/ui/admin/dmp-profile/listing/criteria/dialog-confirmation-upload-profile/dialog-confirmation-upload-profiles.component.ts +++ b/dmp-frontend/src/app/ui/admin/dmp-profile/listing/criteria/dialog-confirmation-upload-profile/dialog-confirmation-upload-profiles.component.ts @@ -1,4 +1,4 @@ -import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material'; +import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; import { Inject, Component } from '@angular/core'; diff --git a/dmp-frontend/src/app/ui/admin/dmp-profile/listing/criteria/dmp-profile-criteria.component.ts b/dmp-frontend/src/app/ui/admin/dmp-profile/listing/criteria/dmp-profile-criteria.component.ts index 466097b9e..def43eae6 100644 --- a/dmp-frontend/src/app/ui/admin/dmp-profile/listing/criteria/dmp-profile-criteria.component.ts +++ b/dmp-frontend/src/app/ui/admin/dmp-profile/listing/criteria/dmp-profile-criteria.component.ts @@ -5,7 +5,7 @@ import { DmpCriteria } from '../../../../../core/query/dmp/dmp-criteria'; import { DmpProfileCriteria } from '../../../../../core/query/dmp/dmp-profile-criteria'; import { BaseCriteriaComponent } from '../../../../misc/criteria/base-criteria.component'; import { DialodConfirmationUploadDmpProfiles } from './dialog-confirmation-upload-profile/dialog-confirmation-upload-profiles.component'; -import { MatDialog } from '@angular/material'; +import { MatDialog } from '@angular/material/dialog'; import { TranslateService } from '@ngx-translate/core'; import { takeUntil } from 'rxjs/operators'; import { DmpProfileService } from '../../../../../core/services/dmp/dmp-profile.service'; @@ -55,6 +55,7 @@ export class DmpProfileCriteriaComponent extends BaseCriteriaComponent implement openDialog(): void { const dialogRef = this.dialog.open(DialodConfirmationUploadDmpProfiles, { + restoreFocus: false, data: { message: this.language.instant('DMP-PROFILE-LISTING.UPLOAD.UPLOAD-XML-FILE-TITLE'), confirmButton: this.language.instant('DMP-PROFILE-LISTING.UPLOAD.UPLOAD-XML'), diff --git a/dmp-frontend/src/app/ui/admin/dmp-profile/listing/dmp-profile-listing.component.scss b/dmp-frontend/src/app/ui/admin/dmp-profile/listing/dmp-profile-listing.component.scss index 772182938..fe822c9c8 100644 --- a/dmp-frontend/src/app/ui/admin/dmp-profile/listing/dmp-profile-listing.component.scss +++ b/dmp-frontend/src/app/ui/admin/dmp-profile/listing/dmp-profile-listing.component.scss @@ -16,7 +16,8 @@ } mat-row:nth-child(odd) { - background-color: #eef0fb; + background-color: #0c748914; + // background-color: #eef0fb; } .mat-fab-bottom-right { diff --git a/dmp-frontend/src/app/ui/admin/dmp-profile/listing/dmp-profile-listing.component.ts b/dmp-frontend/src/app/ui/admin/dmp-profile/listing/dmp-profile-listing.component.ts index 4353d5e7f..856548bc0 100644 --- a/dmp-frontend/src/app/ui/admin/dmp-profile/listing/dmp-profile-listing.component.ts +++ b/dmp-frontend/src/app/ui/admin/dmp-profile/listing/dmp-profile-listing.component.ts @@ -1,10 +1,14 @@ + +import {merge as observableMerge, of as observableOf, Observable } from 'rxjs'; + +import {map, switchMap, startWith, takeUntil } from 'rxjs/operators'; import { DataSource } from '@angular/cdk/table'; import { Component, OnInit, ViewChild } from '@angular/core'; -import { MatPaginator, MatSnackBar, MatSort, PageEvent } from '@angular/material'; +import { MatPaginator, PageEvent } from '@angular/material/paginator'; +import { MatSnackBar } from '@angular/material/snack-bar'; +import { MatSort } from '@angular/material/sort'; import { ActivatedRoute, Params, Router } from '@angular/router'; import { TranslateService } from '@ngx-translate/core'; -import { Observable } from 'rxjs'; -import { takeUntil } from 'rxjs/operators'; import { BaseComponent } from '../../../../core/common/base/base.component'; import { DmpProfileListing } from '../../../../core/model/dmp-profile/dmp-profile-listing'; import { DmpProfileCriteria } from '../../../../core/query/dmp/dmp-profile-criteria'; @@ -20,9 +24,9 @@ import { BreadcrumbItem } from '../../../misc/breadcrumb/definition/breadcrumb-i }) export class DmpProfileListingComponent extends BaseComponent implements OnInit { - @ViewChild(MatPaginator) _paginator: MatPaginator; - @ViewChild(MatSort) sort: MatSort; - @ViewChild(DmpProfileCriteriaComponent) criteria: DmpProfileCriteriaComponent; + @ViewChild(MatPaginator, { static: true }) _paginator: MatPaginator; + @ViewChild(MatSort, { static: true }) sort: MatSort; + @ViewChild(DmpProfileCriteriaComponent, { static: true }) criteria: DmpProfileCriteriaComponent; dataSource: DatasetDataSource | null; displayedColumns: String[] = ['label', 'status', 'created']; @@ -54,7 +58,7 @@ export class DmpProfileListingComponent extends BaseComponent implements OnInit this.criteria.setCriteria(this.getDefaultCriteria()); this.refresh(); this.criteria.setRefreshCallback(() => this.refresh()); - this.breadCrumbs = Observable.of([{ + this.breadCrumbs = observableOf([{ parentComponentName: null, label: this.languageService.instant('NAV-BAR.DMP-TEMPLATES'), url: '/dmp-profiles' @@ -101,16 +105,16 @@ export class DatasetDataSource extends DataSource { //this._sort.matSortChange ]; - return Observable.merge(...displayDataChanges) - .startWith(null) - .switchMap(() => { + return observableMerge(...displayDataChanges).pipe( + startWith(null), + switchMap(() => { const startIndex = this._paginator.pageIndex * this._paginator.pageSize; let fields: Array = new Array(); if (this._sort.active) { fields = this._sort.direction === 'asc' ? ['+' + this._sort.active] : ['-' + this._sort.active]; } const request = new DataTableRequest(startIndex, this._paginator.pageSize, { fields: fields }); request.criteria = this._criteria.criteria; return this._service.getPaged(request); - }) + }), /*.catch((error: any) => { this._snackBar.openFromComponent(SnackBarNotificationComponent, { data: { message: 'GENERAL.SNACK-BAR.FORMS-BAD-REQUEST', language: this._languageService }, @@ -120,14 +124,14 @@ export class DatasetDataSource extends DataSource { //this._criteria.criteria.onCallbackError(error); return Observable.of(null); })*/ - .map(result => { + map(result => { return result; - }) - .map(result => { + }), + map(result => { if (!result) { return []; } if (this._paginator.pageIndex === 0) { this.totalCount = result.totalCount; } return result.data; - }); + }),); } disconnect() { diff --git a/dmp-frontend/src/app/ui/admin/user/listing/user-listing.component.scss b/dmp-frontend/src/app/ui/admin/user/listing/user-listing.component.scss index ed359a1d6..4f28a0670 100644 --- a/dmp-frontend/src/app/ui/admin/user/listing/user-listing.component.scss +++ b/dmp-frontend/src/app/ui/admin/user/listing/user-listing.component.scss @@ -12,7 +12,8 @@ } mat-row:nth-child(odd) { - background-color: #eef0fb; + background-color: #0c748914; + // background-color: #eef0fb; } } diff --git a/dmp-frontend/src/app/ui/admin/user/listing/user-listing.component.ts b/dmp-frontend/src/app/ui/admin/user/listing/user-listing.component.ts index 13b8e43bd..36e12bdad 100644 --- a/dmp-frontend/src/app/ui/admin/user/listing/user-listing.component.ts +++ b/dmp-frontend/src/app/ui/admin/user/listing/user-listing.component.ts @@ -1,8 +1,13 @@ + +import {of as observableOf, merge as observableMerge, Observable } from 'rxjs'; + +import {map, catchError, switchMap, startWith} from 'rxjs/operators'; import { DataSource } from '@angular/cdk/table'; import { AfterViewInit, Component, OnInit, ViewChild } from '@angular/core'; -import { MatPaginator, MatSnackBar, MatSort } from '@angular/material'; +import { MatPaginator } from '@angular/material/paginator'; +import { MatSnackBar } from '@angular/material/snack-bar'; +import { MatSort } from '@angular/material/sort'; import { TranslateService } from '@ngx-translate/core'; -import { Observable } from 'rxjs'; import { UserListingModel } from '../../../../core/model/user/user-listing'; import { UserCriteria } from '../../../../core/query/user/user-criteria'; import { UserService } from '../../../../core/services/user/user.service'; @@ -41,28 +46,28 @@ export class UsersDataSource extends DataSource { // this._paginator.pageIndex = 0; //}) - return Observable.merge(...displayDataChanges) - .startWith(null) - .switchMap(() => { + return observableMerge(...displayDataChanges).pipe( + startWith(null), + switchMap(() => { const startIndex = this._paginator.pageIndex * this._paginator.pageSize; let fields: Array = new Array(); if (this._sort.active) { fields = this._sort.direction === 'asc' ? ['+' + this._sort.active] : ['-' + this._sort.active]; } const request = new DataTableRequest(startIndex, this._paginator.pageSize, { fields: fields }); request.criteria = this._criteria.getFormData(); return this._service.getPaged(request); - }) - .catch((error: any) => { + }), + catchError((error: any) => { this._snackBar.openFromComponent(SnackBarNotificationComponent, { data: { message: 'GENERAL.SNACK-BAR.FORMS-BAD-REQUEST', language: this._languageService }, duration: 3000, }); this._criteria.onCallbackError(error); - return Observable.of(null); - }) - .map(result => { + return observableOf(null); + }), + map(result => { return result; - }) - .map(result => { + }), + map(result => { if (!result) { return []; } if (this._paginator.pageIndex === 0) { this.totalCount = result.totalCount; } //result.data.forEach((element: any) => { @@ -75,7 +80,7 @@ export class UsersDataSource extends DataSource { // element.roles = roles; //}); return result.data; - }); + }),); } disconnect() { @@ -90,9 +95,9 @@ export class UsersDataSource extends DataSource { }) export class UserListingComponent implements OnInit, AfterViewInit { - @ViewChild(MatPaginator) _paginator: MatPaginator; - @ViewChild(MatSort) sort: MatSort; - @ViewChild(UserCriteriaComponent) criteria: UserCriteriaComponent; + @ViewChild(MatPaginator, { static: true }) _paginator: MatPaginator; + @ViewChild(MatSort, { static: true }) sort: MatSort; + @ViewChild(UserCriteriaComponent, { static: true }) criteria: UserCriteriaComponent; breadCrumbs: Observable; dataSource: UsersDataSource | null; @@ -107,7 +112,7 @@ export class UserListingComponent implements OnInit, AfterViewInit { } ngOnInit() { - this.breadCrumbs = Observable.of([{ + this.breadCrumbs = observableOf([{ parentComponentName: null, label: this.languageService.instant('NAV-BAR.USERS-BREADCRUMB'), url: "/users" diff --git a/dmp-frontend/src/app/ui/auth/login/b2access/b2access-login.component.ts b/dmp-frontend/src/app/ui/auth/login/b2access/b2access-login.component.ts index 32a1cba27..a0c38b6ec 100644 --- a/dmp-frontend/src/app/ui/auth/login/b2access/b2access-login.component.ts +++ b/dmp-frontend/src/app/ui/auth/login/b2access/b2access-login.component.ts @@ -36,7 +36,11 @@ export class B2AccessLoginComponent extends BaseComponent implements OnInit { } public b2AccessGetAuthCode() { - window.location.href = environment.loginProviders.b2accessConfiguration.oauthUrl + '?response_type=code&client_id=' + environment.loginProviders.b2accessConfiguration.clientId + '&redirect_uri=' + environment.loginProviders.b2accessConfiguration.redirectUri + '&state=987654321&scope=USER_PROFILE'; + window.location.href = environment.loginProviders.b2accessConfiguration.oauthUrl + + '?response_type=code&client_id=' + environment.loginProviders.b2accessConfiguration.clientId + + '&redirect_uri=' + environment.loginProviders.b2accessConfiguration.redirectUri + + '&state=' + environment.loginProviders.b2accessConfiguration.state + + '&scope=USER_PROFILE'; } public b2AccessLogin(code: String) { diff --git a/dmp-frontend/src/app/ui/auth/login/configurable-login/configurable-login.component.html b/dmp-frontend/src/app/ui/auth/login/configurable-login/configurable-login.component.html new file mode 100644 index 000000000..e69de29bb diff --git a/dmp-frontend/src/app/ui/auth/login/configurable-login/configurable-login.component.ts b/dmp-frontend/src/app/ui/auth/login/configurable-login/configurable-login.component.ts new file mode 100644 index 000000000..dfeef2274 --- /dev/null +++ b/dmp-frontend/src/app/ui/auth/login/configurable-login/configurable-login.component.ts @@ -0,0 +1,94 @@ +import { Component, OnInit, Input } from "@angular/core"; +import { BaseComponent } from "../../../../core/common/base/base.component"; +import { ActivatedRoute, Router, Params } from "@angular/router"; +import { HttpClient } from "@angular/common/http"; +import { LoginService } from "../utilities/login.service"; +import { AuthService } from "../../../../core/services/auth/auth.service"; +import { takeUntil } from "rxjs/operators"; +import { environment } from "../../../../../environments/environment"; +import { AuthProvider } from "../../../../core/common/enum/auth-provider"; +import { ConfigurableProvider } from "../../../../core/model/configurable-provider/configurableProvider"; +import { ConfigurableProvidersService } from "../utilities/configurableProviders.service"; + +@Component({ + selector: 'app-configurable-login', + templateUrl: './configurable-login.component.html', +}) +export class ConfigurableLoginComponent extends BaseComponent implements OnInit { + private returnUrl: string; + + // private configurableLoginId: string; + // private clientId: string; + // private oauthUrl: string; + // private redirectUri: string; + // private state: string; + // @Input() scope: string; + + private provider: ConfigurableProvider; + private providerId: string; + + constructor( + private route: ActivatedRoute, + private loginService: LoginService, + private authService: AuthService, + private router: Router, + private httpClient: HttpClient, + private providers: ConfigurableProvidersService + ) { + super(); + } + + ngOnInit(): void { + const params = this.route.snapshot.params; + this.providerId = params['id']; + if (this.providers.providers === undefined) { + this.authService.getConfigurableProviders() + .pipe(takeUntil(this._destroyed)) + .subscribe((data) => { + this.providers.providers = data; + this.provider = this.providers.providers.find(item => item.configurableLoginId == this.providerId) + this.route.queryParams + .pipe(takeUntil(this._destroyed)) + .subscribe((params: Params) => { + const returnUrlFromParams = params['returnUrl']; + if (returnUrlFromParams) { this.returnUrl = returnUrlFromParams; } + if (!params['code']) { this.configurableAuthorize(); } else { this.configurableLoginUser(params['code'], params['state']) } + }) + }); + } else { + this.provider = this.providers.providers.find(item => item.configurableLoginId == this.providerId) + this.route.queryParams + .pipe(takeUntil(this._destroyed)) + .subscribe((params: Params) => { + const returnUrlFromParams = params['returnUrl']; + if (returnUrlFromParams) { this.returnUrl = returnUrlFromParams; } + if (!params['code']) { this.configurableAuthorize(); } else { this.configurableLoginUser(params['code'], params['state']) } + }) + } + } + + public configurableAuthorize() { + let authUrl = this.provider.oauthUrl + + '?response_type=code&client_id=' + this.provider.clientId + + '&redirect_uri=' + this.provider.redirect_uri + + '&scope=' + this.provider.scope; + if (this.provider.state.length > 0) authUrl = authUrl + '&state=' + this.provider.state + window.location.href = authUrl; + } + + public configurableLoginUser(code: string, state: string) { + if (state !== this.provider.state) { + this.router.navigate(['/login']) + } + this.httpClient.post(environment.Server + 'auth/configurableProviderRequestToken', { code: code, provider: AuthProvider.Configurable, configurableLoginId: this.providerId }) + .pipe(takeUntil(this._destroyed)) + .subscribe((data: any) => { + this.authService.login({ ticket: data.payload.accessToken, provider: AuthProvider.Configurable, data: { configurableLoginId: this.provider.configurableLoginId } }) + .pipe(takeUntil(this._destroyed)) + .subscribe( + res => this.loginService.onLogInSuccess(res, this.returnUrl), + error => this.loginService.onLogInError(error) + ) + }) + } +} diff --git a/dmp-frontend/src/app/ui/auth/login/img/openaire.png b/dmp-frontend/src/app/ui/auth/login/img/openaire.png new file mode 100644 index 000000000..473bb3f59 Binary files /dev/null and b/dmp-frontend/src/app/ui/auth/login/img/openaire.png differ diff --git a/dmp-frontend/src/app/ui/auth/login/img/openaire_small.png b/dmp-frontend/src/app/ui/auth/login/img/openaire_small.png new file mode 100644 index 000000000..b4c2a3df3 Binary files /dev/null and b/dmp-frontend/src/app/ui/auth/login/img/openaire_small.png differ diff --git a/dmp-frontend/src/app/ui/auth/login/linkedin-login/linkedin-login.component.ts b/dmp-frontend/src/app/ui/auth/login/linkedin-login/linkedin-login.component.ts index 5af22cde4..bf2981f99 100644 --- a/dmp-frontend/src/app/ui/auth/login/linkedin-login/linkedin-login.component.ts +++ b/dmp-frontend/src/app/ui/auth/login/linkedin-login/linkedin-login.component.ts @@ -1,11 +1,12 @@ import { Component, OnInit } from '@angular/core'; -import { ActivatedRoute, Params } from '@angular/router'; +import { ActivatedRoute, Params, Router } from '@angular/router'; import { takeUntil } from 'rxjs/operators'; import { environment } from '../../../../../environments/environment'; import { BaseComponent } from '../../../../core/common/base/base.component'; import { AuthProvider } from '../../../../core/common/enum/auth-provider'; import { AuthService } from '../../../../core/services/auth/auth.service'; import { LoginService } from '../utilities/login.service'; +import { HttpClient } from "@angular/common/http"; @Component({ selector: 'app-linkedin-login', @@ -18,7 +19,9 @@ export class LinkedInLoginComponent extends BaseComponent implements OnInit { constructor( private route: ActivatedRoute, private loginService: LoginService, - private authService: AuthService + private authService: AuthService, + private router: Router, + private httpClient: HttpClient ) { super(); } @@ -29,21 +32,31 @@ export class LinkedInLoginComponent extends BaseComponent implements OnInit { .subscribe((params: Params) => { const returnUrl = params['returnUrl']; if (returnUrl) { this.returnUrl = returnUrl; } - if (!params['code']) { this.linkedinAuthorize(); } else { this.linkedInLoginUser(params['code']); } + if (!params['code']) { this.linkedinAuthorize(); } else { this.linkedInLoginUser(params['code'], params['state']); } }); } public linkedinAuthorize() { - window.location.href = environment.loginProviders.linkedInConfiguration.oauthUrl + '?response_type=code&client_id=' + environment.loginProviders.linkedInConfiguration.clientId + '&redirect_uri=' + environment.loginProviders.linkedInConfiguration.redirectUri + '&state=987654321'; + window.location.href = environment.loginProviders.linkedInConfiguration.oauthUrl + + '?response_type=code&client_id=' + environment.loginProviders.linkedInConfiguration.clientId + + '&redirect_uri=' + environment.loginProviders.linkedInConfiguration.redirectUri + + '&state=' + environment.loginProviders.linkedInConfiguration.state + + '&scope=r_emailaddress'; } - - public linkedInLoginUser(code: string) { - this.authService.login({ ticket: code, provider: AuthProvider.LinkedIn }) + public linkedInLoginUser(code: string, state: string) { + if (state !== environment.loginProviders.linkedInConfiguration.state) { + this.router.navigate(['/login']); + } + this.httpClient.post(environment.Server + 'auth/linkedInRequestToken', { code: code, provider: AuthProvider.LinkedIn }) .pipe(takeUntil(this._destroyed)) - .subscribe( - res => this.loginService.onLogInSuccess(res, this.returnUrl), - error => this.loginService.onLogInError(error) - ); + .subscribe((data: any) => { + this.authService.login({ ticket: data.payload.accessToken, provider: AuthProvider.LinkedIn, data: null }) + .pipe(takeUntil(this._destroyed)) + .subscribe( + res => this.loginService.onLogInSuccess(res, this.returnUrl), + error => this.loginService.onLogInError(error) + ); + }); } } diff --git a/dmp-frontend/src/app/ui/auth/login/login.component.html b/dmp-frontend/src/app/ui/auth/login/login.component.html index da8ce40e0..7b674a5c4 100644 --- a/dmp-frontend/src/app/ui/auth/login/login.component.html +++ b/dmp-frontend/src/app/ui/auth/login/login.component.html @@ -7,28 +7,52 @@ +
+
+
+
+
+
-
-
+
+
+ + + + + +
+
+