From 01c5166bb9e104a16b9b61ba5a10920725e9bd57 Mon Sep 17 00:00:00 2001 From: gkolokythas Date: Fri, 2 Aug 2019 11:27:12 +0300 Subject: [PATCH] Adds "Project" entity and its respected needed properties for external fetching. (Issue #145) --- .../data/dao/criteria/ProjectCriteria.java | 14 + .../eudat/data/dao/entities/ProjectDao.java | 16 ++ .../data/dao/entities/ProjectDaoImpl.java | 69 +++++ .../main/java/eu/eudat/data/entities/DMP.java | 14 +- .../java/eu/eudat/data/entities/Project.java | 272 ++++++++++++++++++ .../item/project/ProjectCriteriaRequest.java | 17 ++ .../java/eu/eudat/controllers/Projects.java | 37 +++ .../logic/builders/BuilderFactoryImpl.java | 1 + .../builders/model/models/ProjectBuilder.java | 125 ++++++++ .../managers/DataManagementPlanManager.java | 17 ++ .../eudat/logic/managers/ProjectManager.java | 51 ++++ .../logic/proxy/config/ExternalUrls.java | 27 +- .../proxy/config/entities/ProjectUrls.java | 32 +++ .../logic/proxy/fetching/RemoteFetcher.java | 7 + .../operations/DatabaseRepository.java | 2 + .../operations/DatabaseRepositoryImpl.java | 10 + .../models/data/dmp/DataManagementPlan.java | 14 + .../dmp/DataManagementPlanEditorModel.java | 11 + .../ProjectsExternalSourcesModel.java | 19 ++ .../eu/eudat/models/data/project/Project.java | 186 ++++++++++++ .../data/project/ProjectDMPEditorModel.java | 28 ++ .../web/src/main/resources/ExternalUrls.xml | 42 +++ 22 files changed, 1003 insertions(+), 8 deletions(-) create mode 100644 dmp-backend/data/src/main/java/eu/eudat/data/dao/criteria/ProjectCriteria.java create mode 100644 dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/ProjectDao.java create mode 100644 dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/ProjectDaoImpl.java create mode 100644 dmp-backend/data/src/main/java/eu/eudat/data/entities/Project.java create mode 100644 dmp-backend/data/src/main/java/eu/eudat/data/query/items/item/project/ProjectCriteriaRequest.java create mode 100644 dmp-backend/web/src/main/java/eu/eudat/controllers/Projects.java create mode 100644 dmp-backend/web/src/main/java/eu/eudat/logic/builders/model/models/ProjectBuilder.java create mode 100644 dmp-backend/web/src/main/java/eu/eudat/logic/managers/ProjectManager.java create mode 100644 dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/entities/ProjectUrls.java create mode 100644 dmp-backend/web/src/main/java/eu/eudat/models/data/external/ProjectsExternalSourcesModel.java create mode 100644 dmp-backend/web/src/main/java/eu/eudat/models/data/project/Project.java create mode 100644 dmp-backend/web/src/main/java/eu/eudat/models/data/project/ProjectDMPEditorModel.java diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/criteria/ProjectCriteria.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/criteria/ProjectCriteria.java new file mode 100644 index 000000000..1450c8661 --- /dev/null +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/criteria/ProjectCriteria.java @@ -0,0 +1,14 @@ +package eu.eudat.data.dao.criteria; + +import eu.eudat.data.entities.Project; + +public class ProjectCriteria extends Criteria { + private String reference; + + public String getReference() { + return reference; + } + public void setReference(String reference) { + this.reference = reference; + } +} diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/ProjectDao.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/ProjectDao.java new file mode 100644 index 000000000..1c82fc0ed --- /dev/null +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/ProjectDao.java @@ -0,0 +1,16 @@ +package eu.eudat.data.dao.entities; + +import eu.eudat.data.dao.DatabaseAccessLayer; +import eu.eudat.data.dao.criteria.ProjectCriteria; +import eu.eudat.data.entities.Project; +import eu.eudat.data.entities.UserInfo; +import eu.eudat.queryable.QueryableList; + +import java.util.UUID; + +public interface ProjectDao extends DatabaseAccessLayer { + + QueryableList getWithCritetia(ProjectCriteria criteria); + + QueryableList getAuthenticated(QueryableList query, UserInfo principal); +} diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/ProjectDaoImpl.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/ProjectDaoImpl.java new file mode 100644 index 000000000..74b1ce108 --- /dev/null +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/ProjectDaoImpl.java @@ -0,0 +1,69 @@ +package eu.eudat.data.dao.entities; + +import eu.eudat.data.dao.DatabaseAccess; +import eu.eudat.data.dao.criteria.ProjectCriteria; +import eu.eudat.data.dao.databaselayer.service.DatabaseService; +import eu.eudat.data.entities.Project; +import eu.eudat.data.entities.UserInfo; +import eu.eudat.queryable.QueryableList; +import org.springframework.stereotype.Service; + +import javax.persistence.criteria.JoinType; +import java.util.UUID; +import java.util.concurrent.CompletableFuture; + +@Service("ProjectDao") +public class ProjectDaoImpl extends DatabaseAccess implements ProjectDao { + + @Override + public QueryableList getWithCritetia(ProjectCriteria criteria) { + QueryableList query = getDatabaseService().getQueryable(Project.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.or(builder.like(builder.upper(root.get("description")), "%" + criteria.getLike().toUpperCase() + "%")))); + if (criteria.getReference() != null) + query.where((builder, root) -> builder.equal(root.get("reference"), criteria.getReference())); + query.where((builder, root) -> builder.notEqual(root.get("status"), Project.Status.DELETED.getValue())); + return query; + } + + public QueryableList getAuthenticated(QueryableList query, UserInfo principal) { + query.where((builder, root) -> builder.or(builder.equal(root.get("creationUser"), principal), builder.equal(root.join("dmps", JoinType.LEFT).join("users", JoinType.LEFT).join("user", JoinType.LEFT).get("id"), principal.getId()))).distinct(); + return query; + } + + public ProjectDaoImpl(DatabaseService databaseService) { + super(databaseService); + } + + @Override + public Project createOrUpdate(Project item) { + return this.getDatabaseService().createOrUpdate(item, Project.class); + } + + @Override + public CompletableFuture createOrUpdateAsync(Project item) { + return null; + } + + @Override + public Project find(UUID id) { + return this.getDatabaseService().getQueryable(Project.class).where((builder, root) -> builder.equal(root.get("id"), id)).getSingle(); + } + + @Override + public Project find(UUID id, String hint) { + throw new UnsupportedOperationException(); + } + + @Override + public void delete(Project item) { + throw new UnsupportedOperationException(); + } + + @Override + public QueryableList asQueryable() { + return this.getDatabaseService().getQueryable(Project.class); + } +} diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/entities/DMP.java b/dmp-backend/data/src/main/java/eu/eudat/data/entities/DMP.java index af3feef88..58ecc4922 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/entities/DMP.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/entities/DMP.java @@ -170,6 +170,10 @@ public class DMP implements DataEntity { @Column(name = "\"DOI\"") private String doi; + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "\"Project\"") + private Project project; + public String getDescription() { return description; @@ -325,7 +329,14 @@ public class DMP implements DataEntity { this.doi = doi; } - @Override + public Project getProject() { + return project; + } + public void setProject(Project project) { + this.project = project; + } + + @Override public void update(DMP entity) { this.associatedDmps = entity.associatedDmps; this.label = entity.getLabel(); @@ -339,6 +350,7 @@ public class DMP implements DataEntity { this.organisations = entity.getOrganisations(); this.dmpProperties = entity.getDmpProperties(); this.isPublic = entity.isPublic; + this.project = entity.getProject(); this.setModified(new Date()); if (entity.getStatus().equals(DMPStatus.FINALISED.getValue())) this.setFinalizedAt(new Date()); if (entity.isPublic) this.setPublishedAt(new Date()); diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/entities/Project.java b/dmp-backend/data/src/main/java/eu/eudat/data/entities/Project.java new file mode 100644 index 000000000..7f0e737b4 --- /dev/null +++ b/dmp-backend/data/src/main/java/eu/eudat/data/entities/Project.java @@ -0,0 +1,272 @@ +package eu.eudat.data.entities; + +import eu.eudat.data.converters.DateToUTCConverter; +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.*; +import java.util.*; +import java.util.stream.Collectors; + +@Entity +@Table(name = "\"Project\"") +public class Project implements DataEntity { + + public enum Status { + ACTIVE((short) 1), INACTIVE((short) 0), DELETED((short) 99); + + private short value; + + Status(short value) { + this.value = value; + } + + public short getValue() { + return value; + } + + public static Status fromInteger(int value) { + switch (value) { + case 0: + return INACTIVE; + case 1: + return ACTIVE; + case 99: + return DELETED; + default: + throw new RuntimeException("Unsupported Grant Status"); + } + } + } + + public enum ProjectType { + EXTERNAL(0), INTERNAL(1); + + private Integer value; + + ProjectType(Integer value) { + this.value = value; + } + + public Integer getValue() { + return value; + } + + public static ProjectType fromInteger(int value) { + switch (value) { + case 0: + return EXTERNAL; + case 1: + return INTERNAL; + default: + throw new RuntimeException("Unsupported Grant Type"); + } + } + } + + @Id + @GeneratedValue + @GenericGenerator(name = "uuid2", strategy = "uuid2") + @Column(name = "\"ID\"", updatable = false, nullable = false, columnDefinition = "BINARY(16)") + private UUID id; + + @OneToMany(mappedBy = "project") + private Set dmps; + + @Column(name = "\"Label\"") + private String label; + + @Column(name = "\"Abbreviation\"") + private String abbreviation; + + @Column(name = "\"Reference\"", columnDefinition = "xml", nullable = true) + private String reference; + + @Column(name = "\"Uri\"") + private String uri; + + @Type(type = "eu.eudat.configurations.typedefinition.XMLType") + @Column(name = "\"Definition\"", columnDefinition = "xml", nullable = true) + private String definition; + + @Column(name = "\"StartDate\"", nullable = false) + @Convert(converter = DateToUTCConverter.class) + private Date startdate = null; + + @Column(name = "\"EndDate\"", nullable = false) + @Convert(converter = DateToUTCConverter.class) + private Date enddate = null; + + @Column(name = "\"Status\"", nullable = false) + private Short status; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "\"CreationUser\"", nullable = true) + private UserInfo creationUser; + + @Column(name = "\"Created\"") + private Date created = null; + + @Column(name = "\"Modified\"") + private Date modified = new Date(); + + @Column(name = "\"Description\"") + private String description; + + @Column(name = "\"Type\"") + private Integer type; + + @OneToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "\"Content\"") + private Content content; + + public Project() { + } + + public Project(Project project) {this.id = project.getId();} + + public UUID getId() { + return id; + } + public void setId(UUID id) { + this.id = id; + } + + public Set getDmps() { + return dmps; + } + public void setDmps(Set dmps) { + this.dmps = dmps; + } + + public String getLabel() { + return label; + } + public void setLabel(String label) { + this.label = label; + } + + public String getAbbreviation() { + return abbreviation; + } + public void setAbbreviation(String abbreviation) { + this.abbreviation = abbreviation; + } + + public String getReference() { + return reference; + } + public void setReference(String reference) { + this.reference = reference; + } + + public String getUri() { + return uri; + } + public void setUri(String uri) { + this.uri = uri; + } + + public String getDefinition() { + return definition; + } + public void setDefinition(String definition) { + this.definition = definition; + } + + public Date getStartdate() { + return startdate; + } + public void setStartdate(Date startdate) { + this.startdate = startdate; + } + + public Date getEnddate() { + return enddate; + } + public void setEnddate(Date enddate) { + this.enddate = enddate; + } + + public Short getStatus() { + return status; + } + public void setStatus(Short status) { + this.status = status; + } + + public UserInfo getCreationUser() { + return creationUser; + } + public void setCreationUser(UserInfo creationUser) { + this.creationUser = creationUser; + } + + 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 String getDescription() { + return description; + } + public void setDescription(String description) { + this.description = description; + } + + public Integer getType() { + return type; + } + public void setType(Integer type) { + this.type = type; + } + + public Content getContent() { + return content; + } + public void setContent(Content content) { + this.content = content; + } + + @Override + public void update(Project entity) { + this.description = entity.getDescription(); + this.label = entity.getLabel(); + this.abbreviation = entity.getAbbreviation(); + this.created = entity.getCreated(); + this.definition = entity.getDefinition(); + this.dmps = entity.getDmps(); + this.startdate = entity.getStartdate(); + this.enddate = entity.getEnddate(); + this.modified = new Date(); + this.uri = entity.getUri(); + if (entity.getContent() != null) this.content = entity.getContent(); + } + + @Override + public UUID getKeys() { + return this.id; + } + + @Override + public Project buildFromTuple(List tuple, List fields, String base) { + String currentBase = base.isEmpty() ? "" : base + "."; + if (fields.contains(currentBase + "id")) this.id = EntityBinder.fromTuple(tuple, currentBase + "id"); + if (fields.contains(currentBase + "dmps")) + this.dmps = tuple.stream().map(x -> new DMP().buildFromTuple(Arrays.asList(x), fields, currentBase + "dmps")).collect(Collectors.toSet()); + if (fields.contains(currentBase + "creationUser")) + this.creationUser = tuple.stream().map(x -> new UserInfo().buildFromTuple(Arrays.asList(x), fields, currentBase + "creationUser")).collect(Collectors.toList()).get(0); + return this; + } +} diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/query/items/item/project/ProjectCriteriaRequest.java b/dmp-backend/data/src/main/java/eu/eudat/data/query/items/item/project/ProjectCriteriaRequest.java new file mode 100644 index 000000000..5a66ebcd5 --- /dev/null +++ b/dmp-backend/data/src/main/java/eu/eudat/data/query/items/item/project/ProjectCriteriaRequest.java @@ -0,0 +1,17 @@ +package eu.eudat.data.query.items.item.project; + +import eu.eudat.data.dao.criteria.ProjectCriteria; +import eu.eudat.data.entities.Project; +import eu.eudat.data.query.definition.Query; +import eu.eudat.queryable.QueryableList; + +public class ProjectCriteriaRequest extends Query { + @Override + public QueryableList applyCriteria() { + QueryableList query = this.getQuery(); + if (this.getCriteria().getLike() != null && !this.getCriteria().getLike().isEmpty()) + query.where((builder, root) -> builder.like(builder.upper(root.get("label")), "%" + this.getCriteria().getLike().toUpperCase() + "%")); + query.where((builder, root) -> builder.notEqual(root.get("status"), Project.Status.DELETED.getValue())); + return query; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/Projects.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/Projects.java new file mode 100644 index 000000000..50eba0581 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/Projects.java @@ -0,0 +1,37 @@ +package eu.eudat.controllers; + +import eu.eudat.data.query.items.item.project.ProjectCriteriaRequest; +import eu.eudat.logic.managers.ProjectManager; +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.helpers.responses.ResponseItem; +import eu.eudat.models.data.project.Project; +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.web.bind.annotation.*; + +import java.util.List; + +@RestController +@CrossOrigin +@RequestMapping(value = {"/api/projects/"}) +public class Projects extends BaseController{ + private ProjectManager projectManager; + + @Autowired + public Projects(ApiContext apiContext, ProjectManager projectManager) { + super(apiContext); + this.projectManager = projectManager; + } + + @RequestMapping(method = RequestMethod.POST, value = {"/external"}, consumes = "application/json", produces = "application/json") + public @ResponseBody + ResponseEntity>> getWithExternal(@RequestBody ProjectCriteriaRequest grantCriteria, Principal principal) throws NoURLFound, InstantiationException, HugeResultSet, IllegalAccessException { + List dataTable = this.projectManager.getCriteriaWithExternal(grantCriteria, principal); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem>().payload(dataTable).status(ApiMessageCode.NO_MESSAGE)); + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/builders/BuilderFactoryImpl.java b/dmp-backend/web/src/main/java/eu/eudat/logic/builders/BuilderFactoryImpl.java index 04cf51673..575c474b9 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/builders/BuilderFactoryImpl.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/builders/BuilderFactoryImpl.java @@ -20,6 +20,7 @@ public class BuilderFactoryImpl implements BuilderFactory { if (tClass.equals(DataTableDataBuilder.class)) return (T) new DataTableDataBuilder<>(); if (tClass.equals(PrincipalBuilder.class)) return (T) new PrincipalBuilder(); if (tClass.equals(GrantBuilder.class)) return (T) new GrantBuilder(); + if (tClass.equals(ProjectBuilder.class)) return (T) new ProjectBuilder(); if (tClass.equals(RegistryCriteriaBuilder.class)) return (T) new RegistryCriteriaBuilder(); if (tClass.equals(UserInfoBuilder.class)) return (T) new UserInfoBuilder(); if (tClass.equals(UserRoleBuilder.class)) return (T) new UserRoleBuilder(); diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/builders/model/models/ProjectBuilder.java b/dmp-backend/web/src/main/java/eu/eudat/logic/builders/model/models/ProjectBuilder.java new file mode 100644 index 000000000..83d50731d --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/builders/model/models/ProjectBuilder.java @@ -0,0 +1,125 @@ +package eu.eudat.logic.builders.model.models; + + +import eu.eudat.data.entities.UserInfo; +import eu.eudat.logic.builders.Builder; +import eu.eudat.models.data.dmp.DataManagementPlan; +import eu.eudat.models.data.project.Project; + +import java.util.Date; +import java.util.List; +import java.util.UUID; + +public class ProjectBuilder extends Builder { + + private UUID id; + private List dmps; + private String label; + private int type; + private String abbreviation; + private String reference; + private String uri; + private String definition; + private Date startDate; + private Date endDate; + private eu.eudat.data.entities.Project.Status status; + private UserInfo creationUser; + private Date created; + private Date modified; + private String description; + + public ProjectBuilder id(UUID id) { + this.id = id; + return this; + } + + public ProjectBuilder dmps(List dmps) { + this.dmps = dmps; + return this; + } + + public ProjectBuilder label(String label) { + this.label = label; + return this; + } + + public ProjectBuilder type(int type) { + this.type = type; + return this; + } + + public ProjectBuilder abbreviation(String abbreviation) { + this.abbreviation = abbreviation; + return this; + } + + public ProjectBuilder reference(String reference) { + this.reference = reference; + return this; + } + + public ProjectBuilder uri(String uri) { + this.uri = uri; + return this; + } + + public ProjectBuilder definition(String definition) { + this.definition = definition; + return this; + } + + public ProjectBuilder startDate(Date startDate) { + this.startDate = startDate; + return this; + } + + public ProjectBuilder endDate(Date endDate) { + this.endDate = endDate; + return this; + } + + public ProjectBuilder status(eu.eudat.data.entities.Project.Status status) { + this.status = status; + return this; + } + + public ProjectBuilder creationUser(UserInfo creationUser) { + this.creationUser = creationUser; + return this; + } + + public ProjectBuilder created(Date created) { + this.created = created; + return this; + } + + public ProjectBuilder modified(Date modified) { + this.modified = modified; + return this; + } + + public ProjectBuilder description(String description) { + this.description = description; + return this; + } + + @Override + public Project build() { + Project project = new Project(); + project.setStatus(status.getValue()); + project.setAbbreviation(abbreviation); + project.setCreated(created); + project.setCreationUser(creationUser); + project.setDefinition(definition); + project.setDescription(description); + project.setDmps(dmps); + project.setEndDate(endDate); + project.setId(id); + project.setLabel(label); + project.setModified(modified); + project.setReference(reference); + project.setCreationUser(creationUser); + project.setStartDate(startDate); + return project; + } +} 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 46cbe9880..68e4801b0 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 @@ -428,6 +428,7 @@ public class DataManagementPlanManager { createOrganisationsIfTheyDontExist(newDmp, apiContext.getOperationsContext().getDatabaseRepository().getOrganisationDao()); createResearchersIfTheyDontExist(newDmp, apiContext.getOperationsContext().getDatabaseRepository().getResearcherDao()); createGrantIfItDoesntExist(newDmp, apiContext.getOperationsContext().getDatabaseRepository().getGrantDao(), user); + createProjectIfItDoesntExist(newDmp, apiContext.getOperationsContext().getDatabaseRepository().getProjectDao()); DMP dmp; if (dataManagementPlan.getId() != null) { @@ -511,6 +512,7 @@ public class DataManagementPlanManager { createResearchersIfTheyDontExist(newDmp, apiContext.getOperationsContext().getDatabaseRepository().getResearcherDao()); UserInfo user = apiContext.getOperationsContext().getBuilderFactory().getBuilder(UserInfoBuilder.class).id(principal.getId()).build(); createGrantIfItDoesntExist(newDmp, apiContext.getOperationsContext().getDatabaseRepository().getGrantDao(), user); + createProjectIfItDoesntExist(newDmp, apiContext.getOperationsContext().getDatabaseRepository().getProjectDao()); newDmp.setGroupId(oldDmp.getGroupId()); newDmp.setVersion(oldDmp.getVersion() + 1); @@ -536,6 +538,7 @@ public class DataManagementPlanManager { createResearchersIfTheyDontExist(newDmp, apiContext.getOperationsContext().getDatabaseRepository().getResearcherDao()); UserInfo user = apiContext.getOperationsContext().getBuilderFactory().getBuilder(UserInfoBuilder.class).id(principal.getId()).build(); createGrantIfItDoesntExist(newDmp, apiContext.getOperationsContext().getDatabaseRepository().getGrantDao(), user); + createProjectIfItDoesntExist(newDmp, apiContext.getOperationsContext().getDatabaseRepository().getProjectDao()); newDmp.setGroupId(UUID.randomUUID()); newDmp.setVersion(0); @@ -600,6 +603,20 @@ public class DataManagementPlanManager { } } + private void createProjectIfItDoesntExist(DMP newDmp, ProjectDao projectDao) { + if (newDmp.getProject() != null) { + Project project = newDmp.getProject(); + ProjectCriteria criteria = new ProjectCriteria(); + criteria.setReference(project.getReference()); + eu.eudat.data.entities.Project projectEntity = projectDao.getWithCritetia(criteria).getSingleOrDefault(); + if (projectEntity != null) project.setId(projectEntity.getId()); + else { + project.setType(Project.ProjectType.EXTERNAL.getValue()); + projectDao.createOrUpdate(project); + } + } + } + private void copyDatasets(DMP newDmp, DatasetDao datasetDao) { List> futures = new LinkedList<>(); for (Dataset dataset : newDmp.getDataset()) { 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 new file mode 100644 index 000000000..b4024fe5b --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/ProjectManager.java @@ -0,0 +1,51 @@ +package eu.eudat.logic.managers; + +import eu.eudat.models.data.external.ProjectsExternalSourcesModel; +import eu.eudat.models.data.project.Project; +import eu.eudat.data.query.items.item.project.ProjectCriteriaRequest; +import eu.eudat.logic.builders.model.models.ProjectBuilder; +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.models.data.external.ExternalSourcesItemModel; +import eu.eudat.models.data.security.Principal; +import eu.eudat.queryable.QueryableList; +import org.springframework.stereotype.Component; + +import java.util.Comparator; +import java.util.List; +import java.util.Map; + +@Component +public class ProjectManager { + + private ApiContext apiContext; + private RemoteFetcher remoteFetcher; + + public ProjectManager(ApiContext apiContext) { + this.apiContext = apiContext; + this.remoteFetcher = apiContext.getOperationsContext().getRemoteFetcher(); + } + + public List getCriteriaWithExternal(ProjectCriteriaRequest projectCriteria, Principal principal) throws IllegalAccessException, InstantiationException, HugeResultSet, NoURLFound { + eu.eudat.data.entities.UserInfo userInfo = new eu.eudat.data.entities.UserInfo(); + userInfo.setId(principal.getId()); + QueryableList items = apiContext.getOperationsContext().getDatabaseRepository().getProjectDao().getWithCritetia(projectCriteria.getCriteria()); + QueryableList authItems = apiContext.getOperationsContext().getDatabaseRepository().getProjectDao().getAuthenticated(items, userInfo); + List projects = authItems.select(item -> new eu.eudat.models.data.project.Project().fromDataModel(item)); + List> remoteRepos = remoteFetcher.getProjects(projectCriteria.getCriteria().getLike()); + ProjectsExternalSourcesModel projectsExternalSourcesModel = new ProjectsExternalSourcesModel().fromExternalItem(remoteRepos); + for (ExternalSourcesItemModel externalListingItem : projectsExternalSourcesModel) { + eu.eudat.models.data.project.Project project = apiContext.getOperationsContext().getBuilderFactory().getBuilder(ProjectBuilder.class) + .reference(externalListingItem.getRemoteId()).label(externalListingItem.getName()) + .description(externalListingItem.getDescription()).uri(externalListingItem.getUri()) + .abbreviation(externalListingItem.getAbbreviation()).status(eu.eudat.data.entities.Project.Status.fromInteger(0)) + .build(); + + projects.add(project); + } + projects.sort(Comparator.comparing(x -> x.getLabel())); + return projects; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/ExternalUrls.java b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/ExternalUrls.java index ac1a901f7..5d461a5aa 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/ExternalUrls.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/ExternalUrls.java @@ -10,13 +10,12 @@ import java.io.Serializable; @XmlRootElement public class ExternalUrls implements Serializable { - private static final long serialVersionUID = -5076364662014107275L; - Long maxresults; GrantUrls grants; + ProjectUrls projects; RegistryUrls registries; RepositoryUrls repositories; ServiceUrls services; @@ -60,6 +59,12 @@ public class ExternalUrls implements Serializable { return researchers; } + @XmlElement(name = "researchers") + public void setResearchers(ResearcherUrls researchers) { + this.researchers = researchers; + } + + public TagUrls getTags() { return tags; } @@ -69,11 +74,6 @@ public class ExternalUrls implements Serializable { this.tags = tags; } - @XmlElement(name = "researchers") - public void setResearchers(ResearcherUrls researchers) { - this.researchers = researchers; - } - public OrganisationUrls getOrganisations() { return organisations; @@ -84,6 +84,7 @@ public class ExternalUrls implements Serializable { this.organisations = organisations; } + public GrantUrls getGrants() { return grants; } @@ -93,6 +94,17 @@ public class ExternalUrls implements Serializable { this.grants = grants; } + + public ProjectUrls getProjects() { + return projects; + } + + @XmlElement(name = "projects") + public void setProjects(ProjectUrls projects) { + this.projects = projects; + } + + public Long getMaxresults() { return maxresults; } @@ -102,6 +114,7 @@ public class ExternalUrls implements Serializable { this.maxresults = maxresults; } + public DatasetUrls getDatasets() { return datasets; } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/entities/ProjectUrls.java b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/entities/ProjectUrls.java new file mode 100644 index 000000000..1a0faab5a --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/entities/ProjectUrls.java @@ -0,0 +1,32 @@ +package eu.eudat.logic.proxy.config.entities; + +import eu.eudat.logic.proxy.config.FetchStrategy; +import eu.eudat.logic.proxy.config.UrlConfiguration; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlElementWrapper; +import java.util.List; + +public class ProjectUrls { + List urls; + FetchStrategy fetchMode; + + public List getUrls() { + return urls; + } + + @XmlElementWrapper + @XmlElement(name = "urlConfig") + public void setUrls(List urls) { + this.urls = urls; + } + + public FetchStrategy getFetchMode() { + return fetchMode; + } + + @XmlElement(name = "fetchMode") + public void setFetchMode(FetchStrategy fetchMode) { + this.fetchMode = fetchMode; + } +} 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 f1a8e40c0..9788f4dc3 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 @@ -49,6 +49,13 @@ public class RemoteFetcher { return getAll(urlConfigs, fetchStrategy, query); } + @Cacheable("projects") + public List> getProjects(String query) throws NoURLFound, HugeResultSet { + List urlConfigs = Arrays.asList(this.dynamicGrantConfiguration.getConfiguration().getMainExternalField().getUrlConfig()); + FetchStrategy fetchStrategy = configLoader.getExternalUrls().getProjects().getFetchMode(); + return getAll(urlConfigs, fetchStrategy, query); + } + @Cacheable("organisations") public List> getOrganisations(String query, String key) throws NoURLFound, HugeResultSet { List urlConfigs = diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/DatabaseRepository.java b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/DatabaseRepository.java index 98f66e9c7..b0d0732ac 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/DatabaseRepository.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/DatabaseRepository.java @@ -48,5 +48,7 @@ public interface DatabaseRepository { LoginConfirmationEmailDao getLoginConfirmationEmailDao(); + ProjectDao getProjectDao(); + void detachEntity(T entity); } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/DatabaseRepositoryImpl.java b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/DatabaseRepositoryImpl.java index c5fae0c32..1c6cbbbfa 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/DatabaseRepositoryImpl.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/DatabaseRepositoryImpl.java @@ -33,6 +33,7 @@ public class DatabaseRepositoryImpl implements DatabaseRepository { private DatasetExternalDatasetDao datasetExternalDatasetDao; private DatasetServiceDao datasetServiceDao; private LoginConfirmationEmailDao loginConfirmationEmailDao; + private ProjectDao projectDao; private EntityManager entityManager; @@ -251,6 +252,15 @@ public class DatabaseRepositoryImpl implements DatabaseRepository { this.loginConfirmationEmailDao = loginConfirmationEmailDao; } + @Override + public ProjectDao getProjectDao() { + return projectDao; + } + + public void setProjectDao(ProjectDao projectDao) { + this.projectDao = projectDao; + } + public void detachEntity(T entity) { this.entityManager.detach(entity); } diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/DataManagementPlan.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/DataManagementPlan.java index 5540f518b..1f02303e9 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/DataManagementPlan.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/DataManagementPlan.java @@ -9,6 +9,7 @@ import eu.eudat.models.data.helpermodels.Tuple; import eu.eudat.models.data.listingmodels.DatasetListingModel; import eu.eudat.models.data.listingmodels.UserInfoListingModel; import eu.eudat.models.data.grant.Grant; +import eu.eudat.models.data.project.Project; import eu.eudat.models.data.userinfo.UserListingModel; import net.minidev.json.JSONObject; @@ -38,6 +39,7 @@ public class DataManagementPlan implements DataModel { private Map properties; private List users; private String doi; + private Project project; public UUID getId() { return id; @@ -193,6 +195,13 @@ public class DataManagementPlan implements DataModel { this.doi = doi; } + public Project getProject() { + return project; + } + public void setProject(Project project) { + this.project = project; + } + @Override public DataManagementPlan fromDataModel(DMP entity) { this.id = entity.getId(); @@ -233,6 +242,11 @@ public class DataManagementPlan implements DataModel { this.associatedUsers = entity.getUsers().stream().map(item -> new UserListingModel().fromDataModel(item.getUser())).collect(Collectors.toList()); this.users = entity.getUsers().stream().map(item -> new UserInfoListingModel().fromDataModel(item)).collect(Collectors.toList()); this.doi = entity.getDoi(); + if (entity.getProject() != null) { + this.project = new Project().fromDataModel(entity.getProject()); + } else { + this.project = null; + } return this; } 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 cc8c47d33..081339db0 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 @@ -9,6 +9,7 @@ import eu.eudat.models.data.helpermodels.Tuple; import eu.eudat.models.data.listingmodels.DatasetListingModel; import eu.eudat.models.data.listingmodels.UserInfoListingModel; import eu.eudat.models.data.grant.GrantDMPEditorModel; +import eu.eudat.models.data.project.ProjectDMPEditorModel; import eu.eudat.models.data.userinfo.UserListingModel; import net.minidev.json.JSONObject; @@ -38,6 +39,7 @@ public class DataManagementPlanEditorModel implements DataModel properties; private List users; private List datasetsToBeFinalized; + private ProjectDMPEditorModel project; public UUID getId() { return id; @@ -193,6 +195,13 @@ public class DataManagementPlanEditorModel implements DataModel new UserListingModel().fromDataModel(item.getUser())).collect(Collectors.toList()); this.users = entity.getUsers().stream().map(item -> new UserInfoListingModel().fromDataModel(item)).collect(Collectors.toList()); return this; diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/external/ProjectsExternalSourcesModel.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/external/ProjectsExternalSourcesModel.java new file mode 100644 index 000000000..37cd4e878 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/external/ProjectsExternalSourcesModel.java @@ -0,0 +1,19 @@ +package eu.eudat.models.data.external; + +import java.util.List; +import java.util.Map; + +public class ProjectsExternalSourcesModel extends ExternalListingItem{ + @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")); + this.add(model); + } + 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 new file mode 100644 index 000000000..7b238e0db --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/project/Project.java @@ -0,0 +1,186 @@ +package eu.eudat.models.data.project; + +import eu.eudat.data.entities.UserInfo; +import eu.eudat.models.DataModel; +import eu.eudat.models.data.dmp.DataManagementPlan; +import eu.eudat.models.data.files.ContentFile; + +import java.util.Arrays; +import java.util.Date; +import java.util.List; +import java.util.UUID; + +public class Project implements DataModel { + + private UUID id; + private List dmps; + private String label; + private int type; + private String abbreviation; + private String reference; + private String uri; + private String definition; + private Date startDate; + private Date endDate; + private eu.eudat.data.entities.Project.Status status; + private UserInfo creationUser; + private Date created; + private Date modified; + private String description; + private List files; + + public UUID getId() { + return id; + } + public void setId(UUID id) { + this.id = id; + } + + public List getDmps() { + return dmps; + } + public void setDmps(List dmps) { + this.dmps = dmps; + } + + public String getLabel() { + return label; + } + public void setLabel(String label) { + this.label = label; + } + + public int getType() { + return type; + } + public void setType(int type) { + this.type = type; + } + + public String getAbbreviation() { + return abbreviation; + } + public void setAbbreviation(String abbreviation) { + this.abbreviation = abbreviation; + } + + public String getReference() { + return reference; + } + public void setReference(String reference) { + this.reference = reference; + } + + public String getUri() { + return uri; + } + public void setUri(String uri) { + this.uri = uri; + } + + public String getDefinition() { + return definition; + } + public void setDefinition(String definition) { + this.definition = definition; + } + + public Date getStartDate() { + return startDate; + } + public void setStartDate(Date startDate) { + this.startDate = startDate; + } + + public Date getEndDate() { + return endDate; + } + public void setEndDate(Date endDate) { + this.endDate = endDate; + } + + public short getStatus() { + return status.getValue(); + } + public void setStatus(Short status) { + this.status = eu.eudat.data.entities.Project.Status.fromInteger(status); + } + + public UserInfo getCreationUser() { + return creationUser; + } + public void setCreationUser(UserInfo creationUser) { + this.creationUser = creationUser; + } + + 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 String getDescription() { + return description; + } + public void setDescription(String description) { + this.description = description; + } + + public List getFiles() { + return files; + } + public void setFiles(List files) { + this.files = files; + } + + @Override + public Project fromDataModel(eu.eudat.data.entities.Project entity) { + this.id = entity.getId(); + this.label = entity.getLabel(); + this.abbreviation = entity.getAbbreviation(); + this.reference = entity.getReference(); + this.uri = entity.getUri(); + this.type = entity.getType(); + this.definition = entity.getDefinition(); + this.startDate = entity.getStartdate(); + this.endDate = entity.getEnddate(); + this.setStatus(entity.getStatus()); + this.created = entity.getCreated(); + this.modified = entity.getModified(); + this.description = entity.getDescription(); + this.files = entity.getContent() != null ? Arrays.asList(new ContentFile(entity.getContent().getLabel(), UUID.fromString(entity.getContent().getUri().split(":")[1]), "final", entity.getContent().getExtension())) : Arrays.asList(new ContentFile("default.png", null, null, null)); + return this; + } + + @Override + public eu.eudat.data.entities.Project toDataModel() throws Exception { + eu.eudat.data.entities.Project entity = new eu.eudat.data.entities.Project(); + entity.setId(this.id); + entity.setAbbreviation(this.abbreviation); + entity.setLabel(this.label); + entity.setType(this.type); + entity.setReference(this.reference == null ? "dmp:" + this.label : this.reference); + entity.setUri(this.uri); + entity.setDefinition(this.definition); + entity.setStartdate(this.startDate); + entity.setCreated(this.created == null ? new Date() : this.created); + entity.setEnddate(this.endDate); + entity.setStatus(this.status != null ? this.getStatus() : eu.eudat.data.entities.Grant.Status.ACTIVE.getValue()); + entity.setModified(new Date()); + entity.setDescription(this.description); + return entity; + } + + @Override + public String getHint() { + return null; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/project/ProjectDMPEditorModel.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/project/ProjectDMPEditorModel.java new file mode 100644 index 000000000..d36b73594 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/project/ProjectDMPEditorModel.java @@ -0,0 +1,28 @@ +package eu.eudat.models.data.project; + +public class ProjectDMPEditorModel { + private Project existProject; + private String label; + private String description; + + public Project getExistProject() { + return existProject; + } + public void setExistProject(Project existProject) { + this.existProject = existProject; + } + + public String getLabel() { + return label; + } + public void setLabel(String label) { + this.label = label; + } + + public String getDescription() { + return description; + } + public void setDescription(String description) { + this.description = description; + } +} diff --git a/dmp-backend/web/src/main/resources/ExternalUrls.xml b/dmp-backend/web/src/main/resources/ExternalUrls.xml index 64ebb9ced..2c17ce6f6 100644 --- a/dmp-backend/web/src/main/resources/ExternalUrls.xml +++ b/dmp-backend/web/src/main/resources/ExternalUrls.xml @@ -126,6 +126,48 @@ + + + + + cristin + + 1 + https://eestore.paas2.uninett.no/api/projectrepo/ + + $['data'][*]['attributes'] + + 'pid' + 'name' + 'uri' + 'description' + + + $['meta']['pagination']['page','pages','count'] + + + openAire + + 1 + https://eestore.paas2.uninett.no/api/projectrepo/ + + $['data'][*]['attributes'] + + 'pid' + 'name' + 'uri' + 'description' + + + $['meta']['pagination']['page','pages','count'] + + + + + FIRST + + +