package eu.eudat.logic.managers; import eu.eudat.configurations.dynamicproject.DynamicProjectConfiguration; import eu.eudat.configurations.dynamicproject.entities.Property; import eu.eudat.data.dao.criteria.DynamicFieldsCriteria; import eu.eudat.data.dao.criteria.OrganisationCriteria; import eu.eudat.data.dao.criteria.ProjectCriteria; import eu.eudat.data.dao.criteria.ResearcherCriteria; import eu.eudat.data.dao.entities.*; import eu.eudat.data.entities.*; import eu.eudat.data.query.items.item.dmp.DataManagementPlanCriteriaRequest; import eu.eudat.data.query.items.table.dmp.DataManagementPlanTableRequest; import eu.eudat.exceptions.datamanagementplan.DMPWithDatasetsException; import eu.eudat.exceptions.security.UnauthorisedException; import eu.eudat.logic.builders.entity.UserInfoBuilder; import eu.eudat.logic.services.ApiContext; import eu.eudat.models.HintedModelFactory; import eu.eudat.models.data.dmp.DataManagementPlan; import eu.eudat.models.data.dmp.DataManagementPlanNewVersionModel; import eu.eudat.models.data.dynamicfields.DynamicFieldWithValue; import eu.eudat.models.data.helpermodels.Tuple; import eu.eudat.models.data.helpers.common.DataTableData; import eu.eudat.models.data.listingmodels.DataManagementPlanListingModel; import eu.eudat.models.data.listingmodels.DatasetListingModel; import eu.eudat.models.data.security.Principal; import eu.eudat.queryable.QueryableList; import org.springframework.http.*; import org.springframework.scheduling.annotation.Async; import org.springframework.web.client.RestTemplate; import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.stream.Collectors; 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.getOperationsContext().getDatabaseRepository().getDmpDao().getWithCriteria(dataManagementPlanTableRequest.getCriteria()).withHint(HintedModelFactory.getHint(DataManagementPlanListingModel.class)); QueryableList authItems = apiContext.getOperationsContext().getDatabaseRepository().getDmpDao().getAuthenticated(items, userInfo); QueryableList pagedItems = PaginationManager.applyPaging(authItems, dataManagementPlanTableRequest); DataTableData dataTable = new DataTableData<>(); CompletableFuture itemsFuture = pagedItems.withHint(HintedModelFactory.getHint(DataManagementPlanListingModel.class)) .selectAsync(item -> { item.setDataset( item.getDataset().stream() .filter(dataset -> dataset.getDmp().getCreator().getId().equals(userInfo.getId()) || dataset.isPublic() || dataset.getDmp().getUsers().stream() .filter(x -> x.getId().equals(userInfo.getId())).collect(Collectors.toList()).size() > 0).collect(Collectors.toSet())); return new DataManagementPlanListingModel().fromDataModel(item); }) .whenComplete((resultList, throwable) -> dataTable.setData(resultList)); CompletableFuture countFuture = authItems.countAsync().whenComplete((count, throwable) -> { dataTable.setTotalCount(count); }); CompletableFuture.allOf(itemsFuture, countFuture).join(); return dataTable; } public eu.eudat.models.data.dmp.DataManagementPlan getSingle(DMPDao dmpsRepository, String id, Principal principal, DynamicProjectConfiguration dynamicProjectConfiguration) 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.data.dmp.DataManagementPlan datamanagementPlan = new eu.eudat.models.data.dmp.DataManagementPlan(); datamanagementPlan.fromDataModel(dataManagementPlanEntity); Map dmpProperties = dataManagementPlanEntity.getDmpProperties() != null ? new org.json.JSONObject(dataManagementPlanEntity.getDmpProperties()).toMap() : null; datamanagementPlan.setDynamicFields(dynamicProjectConfiguration.getFields().stream().map(item -> { DynamicFieldWithValue fieldWithValue = new DynamicFieldWithValue(); fieldWithValue.setId(item.getId()); fieldWithValue.setDependencies(item.getDependencies()); fieldWithValue.setName(item.getName()); fieldWithValue.setQueryProperty(item.getQueryProperty()); fieldWithValue.setRequired(item.getRequired()); return fieldWithValue; }).collect(Collectors.toList())); if (dmpProperties != null && datamanagementPlan.getDynamicFields() != null) datamanagementPlan.getDynamicFields().forEach(item -> { Map properties = (Map) dmpProperties.get(item.getId()); if (properties != null) item.setValue(new Tuple(properties.get("id"), properties.get("label"))); }); return datamanagementPlan; } public List getWithCriteria(DMPDao dmpsRepository, DataManagementPlanCriteriaRequest dataManagementPlanCriteria, Principal principal) throws IllegalAccessException, InstantiationException { UserInfo userInfo = new UserInfo(); userInfo.setId(principal.getId()); QueryableList items = dmpsRepository.getWithCriteria(dataManagementPlanCriteria.getCriteria()).withHint(HintedModelFactory.getHint(DataManagementPlan.class)); QueryableList authenticatedItems = dmpsRepository.getAuthenticated(items, userInfo); List datamanagementPlans = authenticatedItems.select(item -> new DataManagementPlan().fromDataModel(item)); return datamanagementPlans; } public List> getDynamicFields(String id, DynamicProjectConfiguration dynamicProjectConfiguration, DynamicFieldsCriteria criteria) throws IllegalAccessException, InstantiationException { List> result = new LinkedList<>(); RestTemplate restTemplate = new RestTemplate(); HttpHeaders headers = new HttpHeaders(); headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); headers.setContentType(MediaType.APPLICATION_JSON); HttpEntity entity = new HttpEntity<>("parameters", headers); Property property = dynamicProjectConfiguration.getConfiguration().getConfigurationProperties().stream() .filter(item -> item.getId().equals(id)).findFirst().orElse(null); StringBuilder stringBuilder = new StringBuilder(); if (criteria.getLike() != null) stringBuilder.append("?search=" + criteria.getLike()); if (property.getDependencies() != null && !property.getDependencies().isEmpty() && criteria.getDynamicFields() != null && !criteria.getDynamicFields().isEmpty()) { property.getDependencies().stream().forEach(item -> { DynamicFieldsCriteria.DynamicFieldDependencyCriteria dependencyCriteria = criteria.getDynamicFields().stream().filter(dfield -> dfield.getProperty().equals(item.getId())) .findFirst().orElse(null); if (dependencyCriteria != null) { if (criteria.getLike() != null || property.getDependencies().indexOf(item) > 0) stringBuilder.append("&"); stringBuilder.append(item.getQueryProperty() + "=" + dependencyCriteria.getValue()); } }); ResponseEntity response = restTemplate.exchange(property.getSourceUrl() + stringBuilder.toString(), HttpMethod.GET, entity, ArrayList.class); response.getBody().forEach(item -> { Tuple tuple = new Tuple<>(); tuple.setId((String) (((Map) item).get(property.getExternalFieldId()))); tuple.setLabel((String) (((Map) item).get(property.getExternalFieldLabel()))); result.add(tuple); }); } else { ResponseEntity response = restTemplate.exchange(property.getSourceUrl() + stringBuilder.toString(), HttpMethod.GET, entity, ArrayList.class); response.getBody().forEach(item -> { Tuple tuple = new Tuple<>(); tuple.setId((String) (((Map) item).get(property.getExternalFieldId()))); tuple.setLabel((String) (((Map) item).get(property.getExternalFieldLabel()))); result.add(tuple); }); } return result; } public static void createOrUpdate(ApiContext apiContext, DataManagementPlan dataManagementPlan, Principal principal) throws Exception { DMP newDmp = dataManagementPlan.toDataModel(); createOrganisationsIfTheyDontExist(newDmp, apiContext.getOperationsContext().getDatabaseRepository().getOrganisationDao()); createResearchersIfTheyDontExist(newDmp, apiContext.getOperationsContext().getDatabaseRepository().getResearcherDao()); UserInfo user = apiContext.getOperationsContext().getDatabaseRepository().getUserInfoDao().find(principal.getId()); createProjectIfItDoesntExist(newDmp, apiContext.getOperationsContext().getDatabaseRepository().getProjectDao(), user); newDmp.setCreator(user); newDmp = apiContext.getOperationsContext().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.getOperationsContext().getDatabaseRepository().getUserDmpDao().createOrUpdate(userDMP); } public static void newVersion(ApiContext apiContext, UUID uuid, DataManagementPlanNewVersionModel dataManagementPlan, Principal principal) throws Exception { DMP oldDmp = apiContext.getOperationsContext().getDatabaseRepository().getDmpDao().find(uuid); DMP newDmp = dataManagementPlan.toDataModel(); createOrganisationsIfTheyDontExist(newDmp, apiContext.getOperationsContext().getDatabaseRepository().getOrganisationDao()); createResearchersIfTheyDontExist(newDmp, apiContext.getOperationsContext().getDatabaseRepository().getResearcherDao()); UserInfo user = apiContext.getOperationsContext().getBuilderFactory().getBuilder(UserInfoBuilder.class).id(principal.getId()).build(); createProjectIfItDoesntExist(newDmp, apiContext.getOperationsContext().getDatabaseRepository().getProjectDao(), user); newDmp.setCreator(user); newDmp.setGroupId(oldDmp.getGroupId()); newDmp.setVersion(oldDmp.getVersion() + 1); newDmp.setId(null); newDmp = apiContext.getOperationsContext().getDatabaseRepository().getDmpDao().createOrUpdate(newDmp); copyDatasets(newDmp, apiContext.getOperationsContext().getDatabaseRepository().getDatasetDao()); } public static void clone(ApiContext apiContext, UUID uuid, DataManagementPlanNewVersionModel dataManagementPlan, Principal principal) throws Exception { DMP newDmp = dataManagementPlan.toDataModel(); createOrganisationsIfTheyDontExist(newDmp, apiContext.getOperationsContext().getDatabaseRepository().getOrganisationDao()); createResearchersIfTheyDontExist(newDmp, apiContext.getOperationsContext().getDatabaseRepository().getResearcherDao()); UserInfo user = apiContext.getOperationsContext().getBuilderFactory().getBuilder(UserInfoBuilder.class).id(principal.getId()).build(); createProjectIfItDoesntExist(newDmp, apiContext.getOperationsContext().getDatabaseRepository().getProjectDao(), user); newDmp.setCreator(user); newDmp.setGroupId(UUID.randomUUID()); newDmp.setVersion(0); newDmp.setId(null); newDmp = apiContext.getOperationsContext().getDatabaseRepository().getDmpDao().createOrUpdate(newDmp); copyDatasets(newDmp, apiContext.getOperationsContext().getDatabaseRepository().getDatasetDao()); } public static void delete(ApiContext apiContext, UUID uuid) throws DMPWithDatasetsException { DMP oldDmp = apiContext.getOperationsContext().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.getOperationsContext().getDatabaseRepository().getDmpDao().createOrUpdate(oldDmp); } private static void createResearchersIfTheyDontExist(DMP newDmp, ResearcherDao researcherRepository) { 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 researcher = researcherRepository.createOrUpdate(researcher); } } } private static void createOrganisationsIfTheyDontExist(DMP newDmp, OrganisationDao organisationRepository) { if (newDmp.getOrganisations() != null && !newDmp.getOrganisations().isEmpty()) { for (eu.eudat.data.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.data.entities.Project projectEntity = projectDao.getWithCriteria(criteria).getSingleOrDefault(); if (projectEntity != null) project.setId(projectEntity.getId()); else { project.setType(Project.ProjectType.EXTERNAL.getValue()); projectDao.createOrUpdate(project); } } } 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.getDatasetDataRepositories() != null) { newDataset.setDatasetDataRepositories(newDataset.getDatasetDataRepositories().stream().map(item -> { DataRepository dataRepository = new DataRepository(); dataRepository.setId(item.getId()); DatasetDataRepository datasetDataRepository = new DatasetDataRepository(); datasetDataRepository.setDataRepository(dataRepository); datasetDataRepository.setDataset(newDataset); return datasetDataRepository; }).collect(Collectors.toSet())); } if (newDataset.getDatasetExternalDatasets() != null) { newDataset.setDatasetExternalDatasets(newDataset.getDatasetExternalDatasets().stream().map(item -> { ExternalDataset externalDataset = new ExternalDataset(); externalDataset.setId(item.getId()); DatasetExternalDataset datasetExternalDataset = new DatasetExternalDataset(); datasetExternalDataset.setExternalDataset(externalDataset); datasetExternalDataset.setDataset(newDataset); return datasetExternalDataset; }).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()); DatasetService datasetService = new DatasetService(); datasetService.setService(service); datasetService.setDataset(newDataset); return datasetService; }).collect(Collectors.toSet())); } newDataset.setCreated(new Date()); return newDataset; }).thenApplyAsync(item -> { futures.add(datasetDao.createOrUpdateAsync(item)); return futures; }).join(); } } }