package eu.eudat.logic.managers; import eu.eudat.data.dao.criteria.DataRepositoryCriteria; import eu.eudat.data.dao.criteria.ExternalDatasetCriteria; import eu.eudat.data.dao.criteria.RegistryCriteria; import eu.eudat.data.dao.criteria.ServiceCriteria; import eu.eudat.data.dao.entities.*; import eu.eudat.data.entities.*; import eu.eudat.data.query.items.table.dataset.DatasetTableRequest; import eu.eudat.elastic.criteria.DatasetCriteria; import eu.eudat.elastic.repository.DatasetRepository; import eu.eudat.logic.builders.entity.UserInfoBuilder; import eu.eudat.logic.services.ApiContext; import eu.eudat.logic.services.forms.VisibilityRuleService; import eu.eudat.logic.utilities.documents.helpers.FileEnvelope; import eu.eudat.logic.utilities.documents.word.WordBuilder; import eu.eudat.logic.utilities.documents.xml.ExportXmlBuilder; import eu.eudat.models.HintedModelFactory; import eu.eudat.models.data.datasetwizard.DatasetWizardModel; import eu.eudat.models.data.helpers.common.DataTableData; import eu.eudat.models.data.listingmodels.DatasetListingModel; import eu.eudat.models.data.security.Principal; import eu.eudat.models.data.user.composite.PagedDatasetProfile; import eu.eudat.queryable.QueryableList; import org.apache.commons.io.IOUtils; import org.json.JSONObject; import org.springframework.core.env.Environment; import org.springframework.core.io.FileSystemResource; import org.springframework.http.*; import org.springframework.http.converter.ByteArrayHttpMessageConverter; import org.springframework.util.LinkedMultiValueMap; import org.springframework.web.client.RestTemplate; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.stream.Collectors; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; public class DatasetManager { public DataTableData getPaged(ApiContext apiContext, DatasetTableRequest datasetTableRequest, Principal principal) throws Exception { DatasetCriteria datasetCriteria = new DatasetCriteria(); datasetCriteria.setTags(datasetTableRequest.getCriteria().getTags()); List datasets = apiContext.getOperationsContext().getDatasetRepository().exists() ? apiContext.getOperationsContext().getDatasetRepository().query(datasetCriteria) : new LinkedList<>(); UserInfo userInfo = apiContext.getOperationsContext().getBuilderFactory().getBuilder(UserInfoBuilder.class).id(principal.getId()).build(); QueryableList items = apiContext.getOperationsContext().getDatabaseRepository().getDatasetDao().getWithCriteria(datasetTableRequest.getCriteria()).withHint(HintedModelFactory.getHint(DatasetListingModel.class)); if (datasetTableRequest.getCriteria().getTags() != null && !datasetTableRequest.getCriteria().getTags().isEmpty()) { if (!datasets.isEmpty()) items.where((builder, root) -> root.get("id").in(datasets.stream().map(x -> UUID.fromString(x.getId())).collect(Collectors.toList()))); else items.where((builder, root) -> root.get("id").in(new UUID[]{UUID.randomUUID()})); } QueryableList authItems = apiContext.getOperationsContext().getDatabaseRepository().getDatasetDao().getAuthenticated(items, userInfo); QueryableList pagedItems = PaginationManager.applyPaging(authItems, datasetTableRequest); DataTableData dataTable = new DataTableData(); CompletableFuture> itemsFuture = pagedItems. selectAsync(item -> new DatasetListingModel().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 DatasetWizardModel getSingle(DatasetDao datatasetRepository, DatasetRepository elasticDatasetRepository, String id) throws InstantiationException, IllegalAccessException, IOException { DatasetWizardModel dataset = new DatasetWizardModel(); eu.eudat.data.entities.Dataset datasetEntity = datatasetRepository.find(UUID.fromString(id), HintedModelFactory.getHint(DatasetWizardModel.class)); eu.eudat.elastic.entities.Dataset datasetElastic = elasticDatasetRepository.exists() ? elasticDatasetRepository.findDocument(id) : new eu.eudat.elastic.entities.Dataset(); dataset.setDatasetProfileDefinition(getPagedProfile(dataset, datasetEntity)); dataset.fromDataModel(datasetEntity); dataset.setTags(datasetElastic.getTags()); return dataset; } private PagedDatasetProfile getPagedProfile(DatasetWizardModel dataset, eu.eudat.data.entities.Dataset datasetEntity) { eu.eudat.models.data.user.composite.DatasetProfile datasetprofile = UserManager.generateDatasetProfileModel(datasetEntity.getProfile()); datasetprofile.setStatus(dataset.getStatus()); if (datasetEntity.getProperties() != null) { JSONObject jobject = new JSONObject(datasetEntity.getProperties()); Map properties = jobject.toMap(); datasetprofile.fromJsonObject(properties); } PagedDatasetProfile pagedDatasetProfile = new PagedDatasetProfile(); pagedDatasetProfile.buildPagedDatasetProfile(datasetprofile); return pagedDatasetProfile; } public File getWordDocument(DatasetDao datatasetRepository, String id, VisibilityRuleService visibilityRuleService) throws InstantiationException, IllegalAccessException, IOException { WordBuilder wordBuilder = new WordBuilder(); DatasetWizardModel dataset = new DatasetWizardModel(); eu.eudat.data.entities.Dataset datasetEntity = datatasetRepository.find(UUID.fromString(id), HintedModelFactory.getHint(DatasetWizardModel.class)); Map properties = new HashMap<>(); if (datasetEntity.getProperties() != null) { JSONObject jobject = new JSONObject(datasetEntity.getProperties()); properties = jobject.toMap(); } PagedDatasetProfile pagedDatasetProfile = getPagedProfile(dataset, datasetEntity); visibilityRuleService.setProperties(properties); visibilityRuleService.buildVisibilityContext(pagedDatasetProfile.getRules()); File file = wordBuilder.build(pagedDatasetProfile, datasetEntity.getLabel(), visibilityRuleService); return file; } public FileEnvelope getXmlDocument(DatasetDao datatasetRepository, String id, VisibilityRuleService visibilityRuleService) throws InstantiationException, IllegalAccessException, IOException { ExportXmlBuilder xmlBuilder = new ExportXmlBuilder(); DatasetWizardModel dataset = new DatasetWizardModel(); eu.eudat.data.entities.Dataset datasetEntity = datatasetRepository.find(UUID.fromString(id), HintedModelFactory.getHint(DatasetWizardModel.class)); Map properties = new HashMap<>(); if (datasetEntity.getProperties() != null) { JSONObject jobject = new JSONObject(datasetEntity.getProperties()); properties = jobject.toMap(); } PagedDatasetProfile pagedDatasetProfile = getPagedProfile(dataset, datasetEntity); visibilityRuleService.setProperties(properties); visibilityRuleService.buildVisibilityContext(pagedDatasetProfile.getRules()); File file = xmlBuilder.build(pagedDatasetProfile, visibilityRuleService); FileEnvelope fileEnvelope = new FileEnvelope(); fileEnvelope.setFile(file); fileEnvelope.setFilename(datasetEntity.getLabel()); return fileEnvelope; } public File convertToPDF(File file, Environment environment, String label) throws IOException, InterruptedException { LinkedMultiValueMap map = new LinkedMultiValueMap<>(); map.add("file", new FileSystemResource(file)); HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.MULTIPART_FORM_DATA); HttpEntity> requestEntity = new HttpEntity>( map, headers); Map queueResult = new RestTemplate().postForObject( environment.getProperty("pdf.converter.url") + "api/v1/", requestEntity, Map.class); Map mediaResult = new RestTemplate().getForObject(environment.getProperty("pdf.converter.url") + "/api/v1/" + queueResult.get("id"), Map.class); System.out.println("Status: " + mediaResult.get("status")); while (!mediaResult.get("status").equals("finished")) { Thread.sleep(500); mediaResult = new RestTemplate().getForObject(environment.getProperty("pdf.converter.url") + "api/v1/" + queueResult.get("id"), Map.class); System.out.println("Polling"); } RestTemplate restTemplate = new RestTemplate(); restTemplate.getMessageConverters().add(new ByteArrayHttpMessageConverter()); HttpHeaders headers2 = new HttpHeaders(); headers.setAccept(Arrays.asList(MediaType.APPLICATION_OCTET_STREAM)); HttpEntity entity = new HttpEntity(headers2); ResponseEntity response = restTemplate.exchange(environment.getProperty("pdf.converter.url") + mediaResult.get("result_url"), HttpMethod.GET, entity, byte[].class, "1"); UUID uuid = UUID.randomUUID(); File zip = new File(uuid + ".zip"); if (response.getStatusCode().equals(HttpStatus.OK)) { FileOutputStream output = new FileOutputStream(zip); IOUtils.write(response.getBody(), output); } return extractFromZip(zip, label + ".pdf"); } private File extractFromZip(File file, String filename) throws IOException { byte[] buffer = new byte[1024]; File newFile = new File(filename); ZipInputStream zis = new ZipInputStream(new FileInputStream(file)); ZipEntry zipEntry = zis.getNextEntry(); while (zipEntry != null) { String zippedFileName = zipEntry.getName(); if (zippedFileName.equals("pdf")) { FileOutputStream fos = new FileOutputStream(newFile); int len; while ((len = zis.read(buffer)) > 0) { fos.write(buffer, 0, len); } fos.close(); zipEntry = zis.getNextEntry(); } } zis.closeEntry(); zis.close(); return newFile; } public static eu.eudat.data.entities.Dataset createOrUpdate(ApiContext apiContext, DatasetWizardModel datasetWizardModel, Principal principal) throws Exception { eu.eudat.data.entities.Dataset dataset = datasetWizardModel.toDataModel(); propertiesModelToString(datasetWizardModel, dataset); UserInfo userInfo = apiContext.getOperationsContext().getBuilderFactory().getBuilder(UserInfoBuilder.class).id(principal.getId()).build(); dataset.setCreator(userInfo); updateTags(apiContext.getOperationsContext().getDatasetRepository(), datasetWizardModel); createRegistriesIfTheyDontExist(apiContext.getOperationsContext().getDatabaseRepository().getRegistryDao(), dataset); createDataRepositoriesIfTheyDontExist(apiContext.getOperationsContext().getDatabaseRepository().getDataRepositoryDao(), dataset); createServicesIfTheyDontExist(apiContext.getOperationsContext().getDatabaseRepository().getDatasetServiceDao(), apiContext.getOperationsContext().getDatabaseRepository().getServiceDao(), dataset); createExternalDatasetsIfTheyDontExist(apiContext.getOperationsContext().getDatabaseRepository().getDatasetExternalDatasetDao(), apiContext.getOperationsContext().getDatabaseRepository().getExternalDatasetDao(), dataset); return apiContext.getOperationsContext().getDatabaseRepository().getDatasetDao().createOrUpdate(dataset); } private static void propertiesModelToString(DatasetWizardModel datasetWizardModel, eu.eudat.data.entities.Dataset dataset) { Map values = new HashMap(); PagedDatasetProfile properties = datasetWizardModel.getDatasetProfileDefinition(); properties.toMap(values); JSONObject jobject = new JSONObject(values); dataset.setProperties(jobject.toString()); } private static void updateTags(DatasetRepository datasetRepository, DatasetWizardModel datasetWizardModel) throws IOException { if (datasetWizardModel.getTags() != null && !datasetWizardModel.getTags().isEmpty()) { eu.eudat.elastic.entities.Dataset dataset = new eu.eudat.elastic.entities.Dataset(); dataset.setId(datasetWizardModel.getId().toString()); dataset.setTags(datasetWizardModel.getTags()); datasetRepository.createOrUpdate(dataset); } } private static void createRegistriesIfTheyDontExist(RegistryDao registryDao, eu.eudat.data.entities.Dataset dataset) { if (dataset.getRegistries() != null && !dataset.getRegistries().isEmpty()) { for (eu.eudat.data.entities.Registry registry : dataset.getRegistries()) { RegistryCriteria criteria = new RegistryCriteria(); criteria.setLike(registry.getReference()); List entries = registryDao.getWithCriteria(criteria).toList(); if (entries != null && !entries.isEmpty()) registry.setId(entries.get(0).getId()); else registry = registryDao.createOrUpdate(registry); } } } private static void createDataRepositoriesIfTheyDontExist(DataRepositoryDao dataRepositoryDao, eu.eudat.data.entities.Dataset dataset) { Set datasetDataRepositories = dataset.getDatasetDataRepositories(); dataset.setDatasetDataRepositories(new HashSet<>()); if (datasetDataRepositories != null && !datasetDataRepositories.isEmpty()) { for (eu.eudat.data.entities.DatasetDataRepository datasetDataRepository : datasetDataRepositories) { DataRepositoryCriteria criteria = new DataRepositoryCriteria(); criteria.setLike(datasetDataRepository.getDataRepository().getReference()); List entries = dataRepositoryDao.getWithCriteria(criteria).toList(); if (entries != null && !entries.isEmpty()) { datasetDataRepository.getDataRepository().setId(entries.get(0).getId()); datasetDataRepository.setDataset(dataset); dataset.getDatasetDataRepositories().add(datasetDataRepository); } else { DataRepository dataRepository = dataRepositoryDao.createOrUpdate(datasetDataRepository.getDataRepository()); datasetDataRepository.setDataRepository(dataRepository); dataset.getDatasetDataRepositories().add(datasetDataRepository); } } } } private static void createServicesIfTheyDontExist(DatasetServiceDao datasetServiceDao, ServiceDao serviceDao, eu.eudat.data.entities.Dataset dataset) { Set services = dataset.getServices(); dataset.setServices(new HashSet<>()); if (services != null && !services.isEmpty()) { for (eu.eudat.data.entities.DatasetService datasetService : services) { ServiceCriteria criteria = new ServiceCriteria(); criteria.setLike(datasetService.getService().getLabel()); List entries = serviceDao.getWithCriteria(criteria).toList(); if (entries != null && !entries.isEmpty()) { datasetService.getService().setId(entries.get(0).getId()); datasetService.setDataset(dataset); dataset.getServices().add(datasetService); } else { Service service = serviceDao.createOrUpdate(datasetService.getService()); datasetService.setService(service); dataset.getServices().add(datasetService); } } } } private static void createExternalDatasetsIfTheyDontExist(DatasetExternalDatasetDao datasetExternalDatasetDao, ExternalDatasetDao externalDatasetDao, eu.eudat.data.entities.Dataset dataset) { Set externalDatasets = dataset.getDatasetExternalDatasets(); dataset.setDatasetExternalDatasets(new HashSet<>()); if (externalDatasets != null && !externalDatasets.isEmpty()) { for (eu.eudat.data.entities.DatasetExternalDataset datasetExternalDataset : externalDatasets) { ExternalDatasetCriteria criteria = new ExternalDatasetCriteria(); criteria.setLike(datasetExternalDataset.getExternalDataset().getLabel()); List entries = externalDatasetDao.getWithCriteria(criteria).toList(); if (entries != null && !entries.isEmpty()) { datasetExternalDataset.getExternalDataset().setId(entries.get(0).getId()); datasetExternalDataset.setDataset(dataset); dataset.getDatasetExternalDatasets().add(datasetExternalDataset); } else { ExternalDataset externalDataset = externalDatasetDao.createOrUpdate(datasetExternalDataset.getExternalDataset()); datasetExternalDataset.setExternalDataset(externalDataset); dataset.getDatasetExternalDatasets().add(datasetExternalDataset); } } } } public static void makePublic(DatasetDao datasetDao, UUID id) throws Exception { eu.eudat.data.entities.Dataset dataset = datasetDao.find(id); if (dataset.getStatus() != eu.eudat.data.entities.Dataset.Status.FINALISED.getValue()) throw new Exception("You cannot make public a Dataset That Has not Been Finalised"); dataset.setPublic(true); datasetDao.createOrUpdate(dataset); } }