package eu.eudat.managers; import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.stream.Collectors; import eu.eudat.builders.entity.UserInfoBuilder; import eu.eudat.dao.entities.*; import eu.eudat.entities.*; import eu.eudat.exceptions.datamanagementplan.DMPWithDatasetsException; import eu.eudat.exceptions.security.UnauthorisedException; import eu.eudat.models.HintedModelFactory; import eu.eudat.models.criteria.OrganisationCriteria; import eu.eudat.models.criteria.ProjectCriteria; import eu.eudat.models.criteria.ResearcherCriteria; import eu.eudat.models.dmp.DataManagementPlan; import eu.eudat.models.dmp.DataManagementPlanCriteriaRequest; import eu.eudat.models.dmp.DataManagementPlanNewVersionModel; import eu.eudat.models.dmp.DataManagementPlanTableRequest; import eu.eudat.models.helpers.common.DataTableData; import eu.eudat.models.listingmodels.DataManagementPlanListingModel; import eu.eudat.models.listingmodels.DatasetListingModel; import eu.eudat.models.security.Principal; import eu.eudat.queryable.QueryableList; import eu.eudat.services.ApiContext; import org.springframework.scheduling.annotation.Async; public class DataManagementPlanManager { public DataTableData getPaged(ApiContext apiContext, DataManagementPlanTableRequest dataManagementPlanTableRequest, Principal principal) throws Exception { UserInfo userInfo = new UserInfo(); userInfo.setId(principal.getId()); QueryableList items = apiContext.getDatabaseRepository().getDmpDao().getWithCriteria(dataManagementPlanTableRequest.getCriteria()); QueryableList authItems = apiContext.getDatabaseRepository().getDmpDao().getAuthenticated(items, userInfo); QueryableList pagedItems = PaginationManager.applyPaging(authItems, dataManagementPlanTableRequest); DataTableData dataTable = new DataTableData(); CompletableFuture itemsFuture = pagedItems.withHint(HintedModelFactory.getHint(DataManagementPlanListingModel.class)).toListAsync().whenComplete((resultList, throwable) -> { List datamanagementPlans = resultList.stream().map(item -> new DataManagementPlanListingModel().fromDataModel(item)).collect(Collectors.toList()); dataTable.setData(datamanagementPlans); }); CompletableFuture countFuture = items.countAsync().whenComplete((count, throwable) -> { dataTable.setTotalCount(count); }); CompletableFuture.allOf(itemsFuture, countFuture).join(); return dataTable; } public eu.eudat.models.dmp.DataManagementPlan getSingle(DMPDao dmpsRepository, String id, Principal principal) throws InstantiationException, IllegalAccessException { DMP dataManagementPlanEntity = dmpsRepository.find(UUID.fromString(id)); if (dataManagementPlanEntity.getCreator().getId() != principal.getId() && dataManagementPlanEntity.getUsers().stream().filter(userInfo -> userInfo.getId() == principal.getId()).collect(Collectors.toList()).size() == 0) throw new UnauthorisedException(); eu.eudat.models.dmp.DataManagementPlan datamanagementPlan = new eu.eudat.models.dmp.DataManagementPlan(); datamanagementPlan.fromDataModel(dataManagementPlanEntity); return datamanagementPlan; } public List getWithCriteria(DMPDao dmpsRepository, DataManagementPlanCriteriaRequest dataManagementPlanCriteria) throws IllegalAccessException, InstantiationException { QueryableList items = dmpsRepository.getWithCriteria(dataManagementPlanCriteria.getCriteria()); List datamanagementPlans = items.toList().stream().map(item -> new DataManagementPlan().fromDataModel(item)).collect(Collectors.toList()); return datamanagementPlans; } public static void createOrUpdate(ApiContext apiContext, DataManagementPlan dataManagementPlan, Principal principal) throws Exception { DMP newDmp = dataManagementPlan.toDataModel(); createOrganisationsIfTheyDontExist(newDmp, apiContext.getDatabaseRepository().getOrganisationDao()); createResearchersIfTheyDontExist(newDmp, apiContext.getDatabaseRepository().getResearcherDao()); UserInfo user = apiContext.getDatabaseRepository().getUserInfoDao().find(principal.getId()); createProjectIfItDoesntExist(newDmp, apiContext.getDatabaseRepository().getProjectDao(), user); newDmp.setCreator(user); newDmp = apiContext.getDatabaseRepository().getDmpDao().createOrUpdate(newDmp); if (dataManagementPlan.getAssociatedUsers().stream().filter(item -> item.getId() == principal.getId()).collect(Collectors.toList()).size() == 0) assignUser(newDmp, user, apiContext); } public static void assignUser(DMP dmp, UserInfo userInfo, ApiContext apiContext) { UserDMP userDMP = new UserDMP(); userDMP.setDmp(dmp); userDMP.setUser(userInfo); userDMP.setRole(UserDMP.UserDMPRoles.OWNER.getValue()); apiContext.getDatabaseRepository().getUserDmpDao().createOrUpdate(userDMP); } public static void newVersion(ApiContext apiContext, UUID uuid, DataManagementPlanNewVersionModel dataManagementPlan, Principal principal) throws Exception { DMP oldDmp = apiContext.getDatabaseRepository().getDmpDao().find(uuid); DMP newDmp = dataManagementPlan.toDataModel(); createOrganisationsIfTheyDontExist(newDmp, apiContext.getDatabaseRepository().getOrganisationDao()); createResearchersIfTheyDontExist(newDmp, apiContext.getDatabaseRepository().getResearcherDao()); UserInfo user = apiContext.getBuilderFactory().getBuilder(UserInfoBuilder.class).id(principal.getId()).build(); createProjectIfItDoesntExist(newDmp, apiContext.getDatabaseRepository().getProjectDao(), user); newDmp.setCreator(user); 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 = apiContext.getBuilderFactory().getBuilder(UserInfoBuilder.class).id(principal.getId()).build(); 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 { DMP oldDmp = apiContext.getDatabaseRepository().getDmpDao().find(uuid); if (oldDmp.getDataset().size() > 0) throw new DMPWithDatasetsException("You cannot Remove Datamanagement Plan with Datasets"); oldDmp.setStatus(DMP.DMPStatus.DELETED.getValue()); apiContext.getDatabaseRepository().getDmpDao().createOrUpdate(oldDmp); } private static void createResearchersIfTheyDontExist(DMP newDmp, ResearcherDao researcherRepository) { if (newDmp.getResearchers() != null && !newDmp.getResearchers().isEmpty()) { for (eu.eudat.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 researcher = researcherRepository.createOrUpdate(researcher); } } } private static void createOrganisationsIfTheyDontExist(DMP newDmp, OrganisationDao organisationRepository) { if (newDmp.getOrganisations() != null && !newDmp.getOrganisations().isEmpty()) { for (eu.eudat.entities.Organisation organisation : newDmp.getOrganisations()) { OrganisationCriteria criteria = new OrganisationCriteria(); criteria.setLike(organisation.getReference()); List entries = organisationRepository.getWithCriteria(criteria).toList(); if (entries != null && !entries.isEmpty()) organisation.setId(entries.get(0).getId()); else organisation = organisationRepository.createOrUpdate(organisation); } } } private static void createProjectIfItDoesntExist(DMP newDmp, ProjectDao projectDao, UserInfo userInfo) { if (newDmp.getProject() != null) { Project project = newDmp.getProject(); ProjectCriteria criteria = new ProjectCriteria(); criteria.setReference(project.getReference()); eu.eudat.entities.Project projectEntity = projectDao.getWithCriteria(criteria).getSingleOrDefault(); if (projectEntity != null) project.setId(projectEntity.getId()); else { project.setCreationUser(userInfo); projectDao.createOrUpdate(project); } } } @Async private static void copyDatasets(DMP newDmp, DatasetDao datasetDao) { List> futures = new LinkedList<>(); for (Dataset dataset : newDmp.getDataset()) { datasetDao.asQueryable().withHint(HintedModelFactory.getHint(DatasetListingModel.class)).where((builder, root) -> builder.equal(root.get("id"), dataset.getId())).getSingleAsync() .thenApplyAsync(entityDataset -> { Dataset newDataset = new Dataset(); newDataset.update(entityDataset); newDataset.setDmp(newDmp); newDataset.setStatus(Dataset.Status.SAVED.getValue()); if (newDataset.getDataRepositories() != null) { newDataset.setDataRepositories(newDataset.getDataRepositories().stream().map(item -> { DataRepository dataRepository = new DataRepository(); dataRepository.setId(item.getId()); return dataRepository; }).collect(Collectors.toSet())); } if (newDataset.getExternalDatasets() != null) { newDataset.setExternalDatasets(newDataset.getExternalDatasets().stream().map(item -> { ExternalDataset externalDataset = new ExternalDataset(); externalDataset.setId(item.getId()); return externalDataset; }).collect(Collectors.toSet())); } if (newDataset.getRegistries() != null) { newDataset.setRegistries(newDataset.getRegistries().stream().map(item -> { Registry registry = new Registry(); registry.setId(item.getId()); return registry; }).collect(Collectors.toSet())); } if (newDataset.getServices() != null) { newDataset.setServices(newDataset.getServices().stream().map(item -> { Service service = new Service(); service.setId(item.getId()); return service; }).collect(Collectors.toSet())); } newDataset.setCreated(new Date()); return newDataset; }).thenApplyAsync(item -> { futures.add(datasetDao.createOrUpdateAsync(item)); return futures; }).join(); } } }