diff --git a/dmp-backend/src/main/java/eu/eudat/controllers/DMPs.java b/dmp-backend/src/main/java/eu/eudat/controllers/DMPs.java index 4601d0988..71b9b3a36 100644 --- a/dmp-backend/src/main/java/eu/eudat/controllers/DMPs.java +++ b/dmp-backend/src/main/java/eu/eudat/controllers/DMPs.java @@ -88,6 +88,17 @@ public class DMPs extends BaseController { } } + @RequestMapping(method = RequestMethod.POST, value = {"/dmps/clone/{id}"}, consumes = "application/json", produces = "application/json") + public @ResponseBody + ResponseEntity> clone(@PathVariable UUID id, @RequestBody eu.eudat.models.dmp.DataManagementPlanNewVersionModel dataManagementPlan, Principal principal) { + try { + DataManagementPlanManager.clone(this.getApiContext(), id, dataManagementPlan, principal); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.NO_MESSAGE)); + } catch (Exception ex) { + ex.printStackTrace(); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem().status(ApiMessageCode.DEFAULT_ERROR_MESSAGE).message(ex.getMessage())); + } + } @RequestMapping(method = RequestMethod.POST, value = {"/dmps/get"}, consumes = "application/json", produces = "application/json") public @ResponseBody diff --git a/dmp-backend/src/main/java/eu/eudat/controllers/DatasetProfiles.java b/dmp-backend/src/main/java/eu/eudat/controllers/DatasetProfiles.java index fd5752dfc..6b249de2c 100644 --- a/dmp-backend/src/main/java/eu/eudat/controllers/DatasetProfiles.java +++ b/dmp-backend/src/main/java/eu/eudat/controllers/DatasetProfiles.java @@ -31,7 +31,7 @@ public class DatasetProfiles extends BaseController { super(apiContext); } - @RequestMapping(method = RequestMethod.POST, value = {"/admin/datasetprofiles/get"}, produces = "application/json") + @RequestMapping(method = RequestMethod.POST, value = {"/dmps/datasetprofiles/get"}, produces = "application/json") public @ResponseBody ResponseEntity>> get(@RequestBody DatasetProfileAutocompleteRequest datasetProfileAutocompleteRequest) { try { diff --git a/dmp-backend/src/main/java/eu/eudat/dao/entities/DMPDaoImpl.java b/dmp-backend/src/main/java/eu/eudat/dao/entities/DMPDaoImpl.java index 47bb43cc1..16d14c9c6 100644 --- a/dmp-backend/src/main/java/eu/eudat/dao/entities/DMPDaoImpl.java +++ b/dmp-backend/src/main/java/eu/eudat/dao/entities/DMPDaoImpl.java @@ -1,5 +1,6 @@ package eu.eudat.dao.entities; +import java.lang.reflect.Array; import java.util.Arrays; import java.util.UUID; @@ -13,6 +14,8 @@ import eu.eudat.models.datasetwizard.DatasetWizardAutocompleteRequest; import eu.eudat.queryable.QueryableList; import eu.eudat.entities.DMP; +import eu.eudat.queryable.types.FieldSelectionType; +import eu.eudat.queryable.types.SelectionField; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -36,8 +39,11 @@ public class DMPDaoImpl extends DatabaseAccess implements DMPDao { query.where((builder, root) -> builder.greaterThan(root.get("created"), criteria.getPeriodStart())); if (criteria.getProjects() != null && !criteria.getProjects().isEmpty()) query.where(((builder, root) -> root.get("project").in(criteria.getProjectEntities()))); + if (!criteria.getAllVersions()) + query.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())); query.where((builder, root) -> builder.notEqual(root.get("status"), DMP.DMPStatus.DELETED.getValue())); - query.where((builder, root) -> builder.not(root.get("id").in(query.subQuery((builder1, root1) -> root1.get("previous").isNotNull(), Arrays.asList("previous"))))); return query; } diff --git a/dmp-backend/src/main/java/eu/eudat/dao/entities/DatasetDaoImpl.java b/dmp-backend/src/main/java/eu/eudat/dao/entities/DatasetDaoImpl.java index fe736e4a3..7690ee303 100644 --- a/dmp-backend/src/main/java/eu/eudat/dao/entities/DatasetDaoImpl.java +++ b/dmp-backend/src/main/java/eu/eudat/dao/entities/DatasetDaoImpl.java @@ -48,8 +48,8 @@ public class DatasetDaoImpl extends DatabaseAccess implements DatasetDa } @Override - public Dataset find(UUID id,String hint) { - return getDatabaseService().getQueryable(Dataset.getHints(),Dataset.class).withHint(hint).where((builder, root) -> builder.equal((root.get("id")), id)).getSingle(); + public Dataset find(UUID id, String hint) { + return getDatabaseService().getQueryable(Dataset.getHints(), Dataset.class).withHint(hint).where((builder, root) -> builder.equal((root.get("id")), id)).getSingle(); } @Override diff --git a/dmp-backend/src/main/java/eu/eudat/entities/DMP.java b/dmp-backend/src/main/java/eu/eudat/entities/DMP.java index d08e8c6c4..29cac995d 100644 --- a/dmp-backend/src/main/java/eu/eudat/entities/DMP.java +++ b/dmp-backend/src/main/java/eu/eudat/entities/DMP.java @@ -67,9 +67,8 @@ public class DMP implements Serializable, DataEntity { @Column(name = "\"ID\"", updatable = false, nullable = false, columnDefinition = "BINARY(16)") private UUID id; - @OneToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "\"Previous\"") - private DMP previous; + @Column(name = "\"GroupId\"", columnDefinition = "BINARY(16)") + private UUID groupId; @Column(name = "\"Label\"") private String label; @@ -206,12 +205,12 @@ public class DMP implements Serializable, DataEntity { this.id = id; } - public DMP getPrevious() { - return previous; + public UUID getGroupId() { + return groupId; } - public void setPrevious(DMP previous) { - this.previous = previous; + public void setGroupId(UUID groupId) { + this.groupId = groupId; } public String getLabel() { diff --git a/dmp-backend/src/main/java/eu/eudat/managers/DataManagementPlanManager.java b/dmp-backend/src/main/java/eu/eudat/managers/DataManagementPlanManager.java index 42ece615f..7709097de 100644 --- a/dmp-backend/src/main/java/eu/eudat/managers/DataManagementPlanManager.java +++ b/dmp-backend/src/main/java/eu/eudat/managers/DataManagementPlanManager.java @@ -83,12 +83,25 @@ public class DataManagementPlanManager { user.setId(principal.getId()); createProjectIfItDoesntExist(newDmp, apiContext.getDatabaseRepository().getProjectDao(), user); newDmp.setCreator(user); - newDmp.setPrevious(oldDmp); + newDmp.setGroupId(oldDmp.getGroupId()); newDmp.setVersion(oldDmp.getVersion() + 1); newDmp.setId(null); newDmp = apiContext.getDatabaseRepository().getDmpDao().createOrUpdate(newDmp); copyDatasets(newDmp, apiContext.getDatabaseRepository().getDatasetDao()); + } + public static void clone(ApiContext apiContext, UUID uuid, DataManagementPlanNewVersionModel dataManagementPlan, Principal principal) throws Exception {DMP newDmp = dataManagementPlan.toDataModel(); + createOrganisationsIfTheyDontExist(newDmp, apiContext.getDatabaseRepository().getOrganisationDao()); + createResearchersIfTheyDontExist(newDmp, apiContext.getDatabaseRepository().getResearcherDao()); + UserInfo user = new UserInfo(); + user.setId(principal.getId()); + createProjectIfItDoesntExist(newDmp, apiContext.getDatabaseRepository().getProjectDao(), user); + newDmp.setCreator(user); + newDmp.setGroupId(UUID.randomUUID()); + newDmp.setVersion(0); + newDmp.setId(null); + newDmp = apiContext.getDatabaseRepository().getDmpDao().createOrUpdate(newDmp); + copyDatasets(newDmp, apiContext.getDatabaseRepository().getDatasetDao()); } public static void delete(ApiContext apiContext, UUID uuid) throws DMPWithDatasetsException { diff --git a/dmp-backend/src/main/java/eu/eudat/models/criteria/DataManagementPlanCriteria.java b/dmp-backend/src/main/java/eu/eudat/models/criteria/DataManagementPlanCriteria.java index 0d540ebc4..9510e7726 100644 --- a/dmp-backend/src/main/java/eu/eudat/models/criteria/DataManagementPlanCriteria.java +++ b/dmp-backend/src/main/java/eu/eudat/models/criteria/DataManagementPlanCriteria.java @@ -11,10 +11,30 @@ import java.util.List; import java.util.UUID; import java.util.stream.Collectors; -public class DataManagementPlanCriteria extends Criteria{ +public class DataManagementPlanCriteria extends Criteria { private Date periodStart; private Date periodEnd; + private boolean allVersions; + private List groupIds; + + public boolean getAllVersions() { + return allVersions; + } + + public void setAllVersions(boolean allVersions) { + this.allVersions = allVersions; + } + + public List getGroupIds() { + return groupIds; + } + + public void setGroupIds(List groupIds) { + this.groupIds = groupIds; + } + private List projects; + public Date getPeriodStart() { return periodStart; } @@ -39,9 +59,9 @@ public class DataManagementPlanCriteria extends Criteria{ this.projects = projects; } - public List getProjectEntities() { + public List getProjectEntities() { try { - return new DomainModelConverter().toDataModel(this.projects); + return new DomainModelConverter().toDataModel(this.projects); } catch (Exception e) { e.printStackTrace(); return new LinkedList<>(); diff --git a/dmp-backend/src/main/java/eu/eudat/models/dmp/DataManagementPlan.java b/dmp-backend/src/main/java/eu/eudat/models/dmp/DataManagementPlan.java index 8e4122622..9a0f729fb 100644 --- a/dmp-backend/src/main/java/eu/eudat/models/dmp/DataManagementPlan.java +++ b/dmp-backend/src/main/java/eu/eudat/models/dmp/DataManagementPlan.java @@ -18,7 +18,7 @@ import java.util.stream.Collectors; public class DataManagementPlan implements DataModel { private UUID id; private String label; - private DataManagementPlan previous; + private UUID groupId; private int version; private int status; private String description; @@ -46,12 +46,12 @@ public class DataManagementPlan implements DataModel { this.label = label; } - public DataManagementPlan getPrevious() { - return previous; + public UUID getGroupId() { + return groupId; } - public void setPrevious(DataManagementPlan previous) { - this.previous = previous; + public void setGroupId(UUID groupId) { + this.groupId = groupId; } public List getAssociatedUsers() { @@ -140,7 +140,7 @@ public class DataManagementPlan implements DataModel { this.organisations = new DomainModelConverter().fromDataModel(entity.getOrganisations().stream().collect(Collectors.toList()), Organisation.class); this.researchers = new DomainModelConverter().fromDataModel(entity.getResearchers().stream().collect(Collectors.toList()), Researcher.class); this.version = entity.getVersion(); - this.previous = this.previous == null ? null : new DomainModelConverter().fromDataModel(Arrays.asList(entity.getPrevious()), DataManagementPlan.class).get(0); + this.groupId = this.groupId == null ? null : this.groupId; this.label = entity.getLabel(); this.project = new Project(); this.project.fromDataModel(entity.getProject()); diff --git a/dmp-backend/src/main/java/eu/eudat/models/dmp/DataManagementPlanNewVersionModel.java b/dmp-backend/src/main/java/eu/eudat/models/dmp/DataManagementPlanNewVersionModel.java index d0cac9af3..aa4b8b9a3 100644 --- a/dmp-backend/src/main/java/eu/eudat/models/dmp/DataManagementPlanNewVersionModel.java +++ b/dmp-backend/src/main/java/eu/eudat/models/dmp/DataManagementPlanNewVersionModel.java @@ -19,7 +19,7 @@ import java.util.*; public class DataManagementPlanNewVersionModel implements DataModel { private UUID id; private String label; - private DataManagementPlan previous; + private UUID groupId; private int version; private int status; private String description; @@ -48,12 +48,12 @@ public class DataManagementPlanNewVersionModel implements DataModel { this.label = label; } - public DataManagementPlan getPrevious() { - return previous; + public UUID getGroupId() { + return groupId; } - public void setPrevious(DataManagementPlan previous) { - this.previous = previous; + public void setGroupId(UUID groupId) { + this.groupId = groupId; } public int getVersion() { @@ -156,13 +156,13 @@ public class DataManagementPlanNewVersionModel implements DataModel { entity.setUsers(new HashSet<>(new DomainModelConverter().toDataModel(this.associatedUsers))); entity.setDescription(this.description); entity.setStatus((short) this.status); - entity.setPrevious(this.previous == null ? null : new DomainModelConverter().toDataModel(Arrays.asList(this.previous)).get(0)); + entity.setGroupId(this.groupId == null ? UUID.randomUUID() : this.groupId); entity.setCreated(new Date()); entity.setLabel(this.label); entity.setModified(new Date()); List datasets = new LinkedList<>(); - if(this.datasets!=null){ - for (Dataset dataset :this.datasets){ + if (this.datasets != null) { + for (Dataset dataset : this.datasets) { eu.eudat.entities.Dataset entityDataset = new eu.eudat.entities.Dataset(); entityDataset.setId(dataset.getId()); datasets.add(entityDataset); diff --git a/dmp-backend/src/main/java/eu/eudat/models/listingmodels/DataManagementPlanListingModel.java b/dmp-backend/src/main/java/eu/eudat/models/listingmodels/DataManagementPlanListingModel.java index 8cbdd317f..091430f1e 100644 --- a/dmp-backend/src/main/java/eu/eudat/models/listingmodels/DataManagementPlanListingModel.java +++ b/dmp-backend/src/main/java/eu/eudat/models/listingmodels/DataManagementPlanListingModel.java @@ -10,6 +10,7 @@ import eu.eudat.utilities.helpers.LabelBuilder; import eu.eudat.utilities.helpers.LabelGenerator; import java.util.List; +import java.util.UUID; import java.util.stream.Collectors; @@ -21,6 +22,7 @@ public class DataManagementPlanListingModel implements DataModel { private String creationTime; private String organisations; private String version; + private UUID groupId; private Integer numOfDatasets; public String getId() { @@ -79,6 +81,14 @@ public class DataManagementPlanListingModel implements DataModel { this.version = version; } + public UUID getGroupId() { + return groupId; + } + + public void setGroupId(UUID groupId) { + this.groupId = groupId; + } + public Integer getNumOfDatasets() { return numOfDatasets; } @@ -96,6 +106,7 @@ public class DataManagementPlanListingModel implements DataModel { this.organisations =LabelBuilder.getLabel(new DomainModelConverter().fromDataModel(entity.getOrganisations().stream().collect(Collectors.toList()),Organisation.class)); this.creationTime = entity.getCreated().toString(); this.version = ""+entity.getVersion(); + this.groupId = entity.getGroupId(); this.numOfDatasets = entity.getDataset().size(); } diff --git a/dmp-backend/src/main/java/eu/eudat/queryable/QueryableList.java b/dmp-backend/src/main/java/eu/eudat/queryable/QueryableList.java index 6c4068e53..88ab9bdb4 100644 --- a/dmp-backend/src/main/java/eu/eudat/queryable/QueryableList.java +++ b/dmp-backend/src/main/java/eu/eudat/queryable/QueryableList.java @@ -2,9 +2,11 @@ package eu.eudat.queryable; import eu.eudat.entities.DataEntity; +import eu.eudat.queryable.predicates.NestedQuerySinglePredicate; import eu.eudat.queryable.predicates.OrderByPredicate; import eu.eudat.queryable.predicates.SelectPredicate; import eu.eudat.queryable.predicates.SinglePredicate; +import eu.eudat.queryable.types.SelectionField; import javax.persistence.criteria.Subquery; import java.util.List; @@ -42,8 +44,19 @@ public interface QueryableList> { Long count(); + QueryableList where(NestedQuerySinglePredicate predicate); + CompletableFuture countAsync(); - Subquery subQuery(SinglePredicate predicate,List fields); + Subquery subQuery(SinglePredicate predicate,List fields); + Subquery subQuery(NestedQuerySinglePredicate predicate, List fields); + + Subquery subQueryCount(NestedQuerySinglePredicate predicate, List fields); + + Subquery subQueryCount(SinglePredicate predicate, List fields); + + Subquery subQueryMax(SinglePredicate predicate, List fields,Class uClass); + + Subquery subQueryMax(NestedQuerySinglePredicate predicate, List fields,Class uClass); } diff --git a/dmp-backend/src/main/java/eu/eudat/queryable/hibernatequeryablelist/QueryableHibernateList.java b/dmp-backend/src/main/java/eu/eudat/queryable/hibernatequeryablelist/QueryableHibernateList.java index 2bd09ddd5..4ff77d48e 100644 --- a/dmp-backend/src/main/java/eu/eudat/queryable/hibernatequeryablelist/QueryableHibernateList.java +++ b/dmp-backend/src/main/java/eu/eudat/queryable/hibernatequeryablelist/QueryableHibernateList.java @@ -4,15 +4,19 @@ package eu.eudat.queryable.hibernatequeryablelist; import eu.eudat.entities.DataEntity; import eu.eudat.queryable.QueryableList; import eu.eudat.queryable.exceptions.NotSingleResultException; +import eu.eudat.queryable.predicates.NestedQuerySinglePredicate; import eu.eudat.queryable.predicates.OrderByPredicate; import eu.eudat.queryable.predicates.SelectPredicate; import eu.eudat.queryable.predicates.SinglePredicate; +import eu.eudat.queryable.types.SelectionField; import org.springframework.scheduling.annotation.Async; import org.springframework.transaction.annotation.Transactional; import javax.persistence.EntityManager; import javax.persistence.TypedQuery; import javax.persistence.criteria.*; +import java.lang.reflect.Array; +import java.util.Arrays; import java.util.LinkedList; import java.util.List; import java.util.Set; @@ -25,8 +29,11 @@ public class QueryableHibernateList> implements Queryabl private CriteriaQuery query; private Class tClass; private Root root; + private Root nestedQueryRoot; private Subquery subquery; - private List> predicates = new LinkedList<>(); + private List> singlePredicates = new LinkedList<>(); + private List> nestedPredicates = new LinkedList<>(); + private List> orderings = new LinkedList<>(); private List fields = new LinkedList<>(); private Integer length; @@ -79,7 +86,12 @@ public class QueryableHibernateList> implements Queryabl } public QueryableList where(SinglePredicate predicate) { - this.predicates.add(predicate); + this.singlePredicates.add(predicate); + return this; + } + + public QueryableList where(NestedQuerySinglePredicate predicate) { + this.nestedPredicates.add(predicate); return this; } @@ -107,7 +119,7 @@ public class QueryableHibernateList> implements Queryabl CriteriaQuery criteriaQuery = criteriaBuilder.createQuery(Long.class); Root root = criteriaQuery.from(tClass); criteriaQuery.select(criteriaBuilder.count(root)); - criteriaQuery.where(this.generateWherePredicates(this.predicates, root)); + criteriaQuery.where(this.generateWherePredicates(this.singlePredicates, root, this.nestedPredicates, this.nestedQueryRoot)); return this.manager.createQuery(criteriaQuery).getSingleResult(); } @@ -116,11 +128,19 @@ public class QueryableHibernateList> implements Queryabl CriteriaQuery criteriaQuery = criteriaBuilder.createQuery(Long.class); Root root = criteriaQuery.from(tClass); criteriaQuery.select(criteriaBuilder.count(root)); - criteriaQuery.where(this.generateWherePredicates(this.predicates, root)); + criteriaQuery.where(this.generateWherePredicates(this.singlePredicates, root, this.nestedPredicates, this.nestedQueryRoot)); return CompletableFuture.supplyAsync(() -> this.manager.createQuery(criteriaQuery).getSingleResult()); } - private Predicate[] generateWherePredicates(List> singlePredicates, Root root) { + + private Predicate[] generateWherePredicates(List> singlePredicates, Root root, List> nestedPredicates, Root nestedQueryRoot) { + List predicates = new LinkedList<>(); + predicates.addAll(Arrays.asList(this.generateSingleWherePredicates(singlePredicates, root))); + predicates.addAll(Arrays.asList(this.generateNestedWherePredicates(nestedPredicates, root, nestedQueryRoot))); + return predicates.toArray(new Predicate[predicates.size()]); + } + + private Predicate[] generateSingleWherePredicates(List> singlePredicates, Root root) { List predicates = new LinkedList<>(); for (SinglePredicate singlePredicate : singlePredicates) { predicates.add(singlePredicate.applyPredicate(this.manager.getCriteriaBuilder(), root)); @@ -128,6 +148,14 @@ public class QueryableHibernateList> implements Queryabl return predicates.toArray(new Predicate[predicates.size()]); } + private Predicate[] generateNestedWherePredicates(List> nestedPredicates, Root root, Root nestedQueryRoot) { + List predicates = new LinkedList<>(); + for (NestedQuerySinglePredicate singlePredicate : nestedPredicates) { + predicates.add(singlePredicate.applyPredicate(this.manager.getCriteriaBuilder(), root, nestedQueryRoot)); + } + return predicates.toArray(new Predicate[predicates.size()]); + } + private Order[] generateOrderPredicates(List> orderByPredicates, Root root) { List predicates = new LinkedList<>(); for (OrderByPredicate orderPredicate : orderByPredicates) { @@ -138,7 +166,7 @@ public class QueryableHibernateList> implements Queryabl public List toList() { - this.query.where(this.generateWherePredicates(this.predicates, this.root)); + this.query.where(this.generateWherePredicates(this.singlePredicates, this.root, this.nestedPredicates, this.nestedQueryRoot)); if (!this.orderings.isEmpty()) this.query.orderBy(this.generateOrderPredicates(this.orderings, this.root)); TypedQuery typedQuery = this.manager.createQuery(this.query); if (this.offset != null) typedQuery.setFirstResult(this.offset); @@ -151,7 +179,7 @@ public class QueryableHibernateList> implements Queryabl } public CompletableFuture> toListAsync() { - this.query.where(this.generateWherePredicates(this.predicates, this.root)); + this.query.where(this.generateWherePredicates(this.singlePredicates, this.root, this.nestedPredicates, this.nestedQueryRoot)); if (!this.orderings.isEmpty()) this.query.orderBy(this.generateOrderPredicates(this.orderings, this.root)); TypedQuery typedQuery = this.manager.createQuery(this.query); if (this.offset != null) typedQuery.setFirstResult(this.offset); @@ -165,7 +193,7 @@ public class QueryableHibernateList> implements Queryabl } public T getSingle() { - this.query.where(this.generateWherePredicates(this.predicates, this.root)); + this.query.where(this.generateWherePredicates(this.singlePredicates, this.root, this.nestedPredicates, this.nestedQueryRoot)); TypedQuery typedQuery = this.manager.createQuery(this.query); if (this.hint != null) typedQuery.setHint("javax.persistence.fetchgraph", this.manager.getEntityGraph(this.hint)); @@ -173,7 +201,7 @@ public class QueryableHibernateList> implements Queryabl } public CompletableFuture getSingleAsync() { - this.query.where(this.generateWherePredicates(this.predicates, this.root)); + this.query.where(this.generateWherePredicates(this.singlePredicates, this.root, this.nestedPredicates, this.nestedQueryRoot)); TypedQuery typedQuery = this.manager.createQuery(this.query); if (this.hint != null) typedQuery.setHint("javax.persistence.fetchgraph", this.manager.getEntityGraph(this.hint)); @@ -181,7 +209,7 @@ public class QueryableHibernateList> implements Queryabl } public T getSingleOrDefault() { - this.query.where(this.generateWherePredicates(this.predicates, this.root)); + this.query.where(this.generateWherePredicates(this.singlePredicates, this.root, this.nestedPredicates, this.nestedQueryRoot)); TypedQuery typedQuery = this.manager.createQuery(this.query); if (this.hint != null) @@ -193,7 +221,7 @@ public class QueryableHibernateList> implements Queryabl } public CompletableFuture getSingleOrDefaultAsync() { - this.query.where(this.generateWherePredicates(this.predicates, this.root)); + this.query.where(this.generateWherePredicates(this.singlePredicates, this.root, this.nestedPredicates, this.nestedQueryRoot)); TypedQuery typedQuery = this.manager.createQuery(this.query); if (this.hint != null) @@ -220,11 +248,56 @@ public class QueryableHibernateList> implements Queryabl } @Override - public Subquery subQuery(SinglePredicate predicate, List fields) { + public Subquery subQuery(SinglePredicate predicate, List fields) { Subquery subquery = this.manager.getCriteriaBuilder().createQuery().subquery(this.tClass); - Root root = subquery.from(this.tClass); - subquery.where(predicate.applyPredicate(this.manager.getCriteriaBuilder(), root)); - subquery.select(root.get(fields.get(0))); + this.nestedQueryRoot = subquery.from(this.tClass); + subquery.where(predicate.applyPredicate(this.manager.getCriteriaBuilder(), this.nestedQueryRoot)); + subquery.select(this.nestedQueryRoot.get(fields.get(0).getField())); + return subquery; + } + + @Override + public Subquery subQuery(NestedQuerySinglePredicate predicate, List fields) { + Subquery subquery = this.manager.getCriteriaBuilder().createQuery().subquery(this.tClass); + this.nestedQueryRoot = subquery.from(this.tClass); + subquery.where(predicate.applyPredicate(this.manager.getCriteriaBuilder(), this.root, this.nestedQueryRoot)); + subquery.select(this.nestedQueryRoot.get(fields.get(0).getField())); + return subquery; + } + + @Override + public Subquery subQueryCount(SinglePredicate predicate, List fields) { + Subquery subquery = this.manager.getCriteriaBuilder().createQuery().subquery(Long.class); + this.nestedQueryRoot = subquery.from(this.tClass); + subquery.where(predicate.applyPredicate(this.manager.getCriteriaBuilder(), this.nestedQueryRoot)); + subquery.select(this.manager.getCriteriaBuilder().count(this.nestedQueryRoot.get(fields.get(0).getField()))); + return subquery; + } + + @Override + public Subquery subQueryCount(NestedQuerySinglePredicate predicate, List fields) { + Subquery subquery = this.manager.getCriteriaBuilder().createQuery().subquery(Long.class); + this.nestedQueryRoot = subquery.from(this.tClass); + subquery.where(predicate.applyPredicate(this.manager.getCriteriaBuilder(), this.root, this.nestedQueryRoot)); + subquery.select(this.manager.getCriteriaBuilder().count(this.nestedQueryRoot.get(fields.get(0).getField()))); + return subquery; + } + + @Override + public Subquery subQueryMax(SinglePredicate predicate, List fields,Class uClass) { + Subquery subquery = this.manager.getCriteriaBuilder().createQuery().subquery(uClass); + this.nestedQueryRoot = subquery.from(this.tClass); + subquery.where(predicate.applyPredicate(this.manager.getCriteriaBuilder(), this.nestedQueryRoot)); + subquery.select(this.manager.getCriteriaBuilder().greatest(this.nestedQueryRoot.get(fields.get(0).getField()))); + return subquery; + } + + @Override + public Subquery subQueryMax(NestedQuerySinglePredicate predicate, List fields,Class uClass) { + Subquery subquery = this.manager.getCriteriaBuilder().createQuery().subquery(uClass); + this.nestedQueryRoot = subquery.from(this.tClass); + subquery.where(predicate.applyPredicate(this.manager.getCriteriaBuilder(), this.root, this.nestedQueryRoot)); + subquery.select(this.manager.getCriteriaBuilder().greatest(this.nestedQueryRoot.get(fields.get(0).getField()))); return subquery; } } diff --git a/dmp-backend/src/main/java/eu/eudat/queryable/predicates/NestedQuerySinglePredicate.java b/dmp-backend/src/main/java/eu/eudat/queryable/predicates/NestedQuerySinglePredicate.java new file mode 100644 index 000000000..b70f3127e --- /dev/null +++ b/dmp-backend/src/main/java/eu/eudat/queryable/predicates/NestedQuerySinglePredicate.java @@ -0,0 +1,13 @@ +package eu.eudat.queryable.predicates; + +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.Predicate; +import javax.persistence.criteria.Root; + +/** + * Created by ikalyvas on 2/7/2018. + */ +public interface NestedQuerySinglePredicate { + Predicate applyPredicate(CriteriaBuilder builder, Root root, Root nestedQueryRoot); + +} diff --git a/dmp-backend/src/main/java/eu/eudat/queryable/predicates/QueryablePredicate.java b/dmp-backend/src/main/java/eu/eudat/queryable/predicates/QueryablePredicate.java new file mode 100644 index 000000000..b4e6cb9a4 --- /dev/null +++ b/dmp-backend/src/main/java/eu/eudat/queryable/predicates/QueryablePredicate.java @@ -0,0 +1,7 @@ +package eu.eudat.queryable.predicates; + +/** + * Created by ikalyvas on 2/7/2018. + */ +public interface QueryablePredicate { +} diff --git a/dmp-backend/src/main/java/eu/eudat/queryable/predicates/SinglePredicate.java b/dmp-backend/src/main/java/eu/eudat/queryable/predicates/SinglePredicate.java index 8ba32671a..53f6f84fc 100644 --- a/dmp-backend/src/main/java/eu/eudat/queryable/predicates/SinglePredicate.java +++ b/dmp-backend/src/main/java/eu/eudat/queryable/predicates/SinglePredicate.java @@ -5,5 +5,5 @@ import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root; public interface SinglePredicate { - Predicate applyPredicate(CriteriaBuilder builder, Root root) ; + Predicate applyPredicate(CriteriaBuilder builder, Root root); } diff --git a/dmp-backend/src/main/java/eu/eudat/queryable/types/FieldSelectionType.java b/dmp-backend/src/main/java/eu/eudat/queryable/types/FieldSelectionType.java new file mode 100644 index 000000000..6fc544bfd --- /dev/null +++ b/dmp-backend/src/main/java/eu/eudat/queryable/types/FieldSelectionType.java @@ -0,0 +1,8 @@ +package eu.eudat.queryable.types; + +/** + * Created by ikalyvas on 2/7/2018. + */ +public enum FieldSelectionType { + FIELD, COUNT, MAX +} diff --git a/dmp-backend/src/main/java/eu/eudat/queryable/types/SelectionField.java b/dmp-backend/src/main/java/eu/eudat/queryable/types/SelectionField.java new file mode 100644 index 000000000..7cef18e0d --- /dev/null +++ b/dmp-backend/src/main/java/eu/eudat/queryable/types/SelectionField.java @@ -0,0 +1,34 @@ +package eu.eudat.queryable.types; + +/** + * Created by ikalyvas on 2/7/2018. + */ +public class SelectionField { + private FieldSelectionType type = FieldSelectionType.FIELD; + private String field; + + public SelectionField(String field) { + this.field = field; + } + + public SelectionField(FieldSelectionType type, String field) { + this.type = type; + this.field = field; + } + + public FieldSelectionType getType() { + return type; + } + + public void setType(FieldSelectionType type) { + this.type = type; + } + + public String getField() { + return field; + } + + public void setField(String field) { + this.field = field; + } +} diff --git a/dmp-frontend/src/app/dmps/dmps.routes.ts b/dmp-frontend/src/app/dmps/dmps.routes.ts index e2c68c0be..b3dace2a8 100644 --- a/dmp-frontend/src/app/dmps/dmps.routes.ts +++ b/dmp-frontend/src/app/dmps/dmps.routes.ts @@ -6,9 +6,11 @@ import { RouterModule, Routes } from '@angular/router'; const routes: Routes = [ { path: '', component: DataManagementPlanListingComponent }, + { path: 'viewversions/:groupId', component: DataManagementPlanListingComponent }, { path: 'edit/:id', component: DataManagementPlanEditorComponent }, { path: 'new', component: DataManagementPlanEditorComponent }, - { path: 'new_version/:id', component: DataManagementPlanWizardComponent, data: { clone: "clone" } }, + { path: 'new_version/:id', component: DataManagementPlanWizardComponent, data: { clone: false } }, + { path: 'clone/:id', component: DataManagementPlanWizardComponent, data: { clone: true } } ]; export const DataManagementPlanRoutes = RouterModule.forChild(routes); diff --git a/dmp-frontend/src/app/dmps/listing/dmp-listing.component.html b/dmp-frontend/src/app/dmps/listing/dmp-listing.component.html index a21575fe5..323dc0dac 100644 --- a/dmp-frontend/src/app/dmps/listing/dmp-listing.component.html +++ b/dmp-frontend/src/app/dmps/listing/dmp-listing.component.html @@ -30,7 +30,7 @@ {{'DMP-LISTING.COLUMNS.CREATION-TIME' | translate}} - {{row.creationTime | date:'shortDate'}} + {{row.creationTime | date:'shortDate'}} @@ -60,6 +60,8 @@ + +