package eu.eudat.logic.managers; import com.jayway.jsonpath.DocumentContext; import com.jayway.jsonpath.JsonPath; import eu.eudat.data.dao.criteria.DataManagementPlanCriteria; import eu.eudat.data.dao.criteria.RequestItem; import eu.eudat.data.dao.entities.DatasetDao; import eu.eudat.data.dao.entities.DatasetProfileDao; import eu.eudat.data.entities.DMPProfile; import eu.eudat.data.entities.DescriptionTemplate; import eu.eudat.data.query.items.dmpblueprint.DataManagementPlanBlueprintTableRequest; import eu.eudat.data.query.items.item.dmpprofile.DataManagementPlanProfileCriteriaRequest; import eu.eudat.data.query.items.table.dmpprofile.DataManagementPlanProfileTableRequest; import eu.eudat.exceptions.datasetprofile.DatasetProfileWithDatasetsExeption; import eu.eudat.exceptions.dmpblueprint.DmpBlueprintUsedException; import eu.eudat.logic.services.operations.DatabaseRepository; import eu.eudat.logic.utilities.builders.XmlBuilder; import eu.eudat.logic.utilities.documents.helpers.FileEnvelope; import eu.eudat.logic.utilities.documents.xml.dmpXml.ExportXmlBuilderDmpBlueprint; import eu.eudat.logic.utilities.documents.xml.dmpXml.ImportXmlBuilderDmpBlueprint; import eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.*; import eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.types.FieldCategory; import eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.types.SystemFieldType; import eu.eudat.models.data.helpermodels.Tuple; import eu.eudat.models.data.helpers.common.AutoCompleteLookupItem; import eu.eudat.models.data.helpers.common.DataTableData; import eu.eudat.models.data.listingmodels.DataManagementPlanBlueprintListingModel; import eu.eudat.models.data.listingmodels.DataManagementPlanProfileListingModel; import eu.eudat.models.data.security.Principal; import eu.eudat.queryable.QueryableList; import eu.eudat.logic.services.ApiContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.env.Environment; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Component; import javax.activation.MimetypesFileTypeMap; import javax.xml.xpath.*; import java.io.*; import java.nio.file.Files; import java.util.*; import java.util.concurrent.CompletableFuture; import org.springframework.http.*; import org.springframework.web.client.RestTemplate; import org.springframework.web.multipart.MultipartFile; import org.w3c.dom.Document; import org.w3c.dom.Element; /** * Created by ikalyvas on 3/21/2018. */ @Component public class DataManagementProfileManager { private static final Logger logger = LoggerFactory.getLogger(DataManagementProfileManager.class); private ApiContext apiContext; private DatabaseRepository databaseRepository; private Environment environment; @Autowired public DataManagementProfileManager(ApiContext apiContext, Environment environment) { this.apiContext = apiContext; this.databaseRepository = apiContext.getOperationsContext().getDatabaseRepository(); this.environment = environment; } public DataTableData getPaged(DataManagementPlanProfileTableRequest dataManagementPlanProfileTableRequest, Principal principal) throws Exception { QueryableList items = apiContext.getOperationsContext().getDatabaseRepository().getDmpProfileDao().getWithCriteria(dataManagementPlanProfileTableRequest.getCriteria()); QueryableList pagedItems = PaginationManager.applyPaging(items, dataManagementPlanProfileTableRequest); DataTableData dataTable = new DataTableData(); CompletableFuture itemsFuture = pagedItems .selectAsync(item -> new DataManagementPlanProfileListingModel().fromDataModel(item)).whenComplete((resultList, throwable) -> { dataTable.setData(resultList); }); CompletableFuture countFuture = items.countAsync().whenComplete((count, throwable) -> { dataTable.setTotalCount(count); }); CompletableFuture.allOf(itemsFuture, countFuture).join(); return dataTable; } public DataTableData getPagedBlueprint(DataManagementPlanBlueprintTableRequest dataManagementPlanBlueprintTableRequest, Principal principal) throws Exception { QueryableList items = apiContext.getOperationsContext().getDatabaseRepository().getDmpProfileDao().getWithCriteriaBlueprint(dataManagementPlanBlueprintTableRequest.getCriteria()); QueryableList pagedItems = PaginationManager.applyPaging(items, dataManagementPlanBlueprintTableRequest); DataTableData dataTable = new DataTableData<>(); CompletableFuture itemsFuture = pagedItems .selectAsync(item -> new DataManagementPlanBlueprintListingModel().fromDataModel(item)).whenComplete((resultList, throwable) -> dataTable.setData(resultList)); CompletableFuture countFuture = items.countAsync().whenComplete((count, throwable) -> dataTable.setTotalCount(count)); CompletableFuture.allOf(itemsFuture, countFuture).join(); return dataTable; } public DataManagementPlanProfileListingModel getSingle(String id, Principal principal) throws InstantiationException, IllegalAccessException { DMPProfile dmpProfile = databaseRepository.getDmpProfileDao().find(UUID.fromString(id)); DataManagementPlanProfileListingModel dataManagementPlanProfileListingModel = new DataManagementPlanProfileListingModel(); dataManagementPlanProfileListingModel.fromDataModel(dmpProfile); return dataManagementPlanProfileListingModel; } public DataManagementPlanBlueprintListingModel getSingleBlueprint(String id, Principal principal) { DMPProfile dmpProfile = databaseRepository.getDmpProfileDao().find(UUID.fromString(id)); DataManagementPlanBlueprintListingModel dataManagementPlanBlueprintListingModel = new DataManagementPlanBlueprintListingModel(); dataManagementPlanBlueprintListingModel.fromDataModel(dmpProfile); return dataManagementPlanBlueprintListingModel; } public boolean fieldInBlueprint(String id, SystemFieldType type, Principal principal) { DMPProfile dmpProfile = databaseRepository.getDmpProfileDao().find(UUID.fromString(id)); return this.fieldInBlueprint(dmpProfile, type, principal); } public boolean fieldInBlueprint(DMPProfile dmpProfile, SystemFieldType type, Principal principal) { DataManagementPlanBlueprintListingModel dmpBlueprint = new DataManagementPlanBlueprintListingModel(); dmpBlueprint.fromDataModel(dmpProfile); for(Section section: dmpBlueprint.getDefinition().getSections()){ for(FieldModel field: section.getFields()){ if(field.getCategory().equals(FieldCategory.SYSTEM)){ SystemField systemField = field.toSystemField(); if(systemField.getType().equals(type)){ return true; } } } } return false; } public List sectionIndexesForDescriptionTemplate(DMPProfile dmpProfile, UUID descriptionTemplateId) { DataManagementPlanBlueprintListingModel dmpBlueprint = new DataManagementPlanBlueprintListingModel(); dmpBlueprint.fromDataModel(dmpProfile); List sectionIndexes = new ArrayList<>(); for(int i = 0; i < dmpBlueprint.getDefinition().getSections().size(); i++) { Section section = dmpBlueprint.getDefinition().getSections().get(i); if(section.getHasTemplates() && section.getDescriptionTemplates().stream().anyMatch(x -> x.getDescriptionTemplateId().equals(descriptionTemplateId))) sectionIndexes.add(i); } return sectionIndexes; } public List getWithCriteria(DataManagementPlanProfileCriteriaRequest dataManagementPlanProfileCriteriaRequest) throws IllegalAccessException, InstantiationException { QueryableList items = databaseRepository.getDmpProfileDao().getWithCriteria(dataManagementPlanProfileCriteriaRequest.getCriteria()); List datamanagementPlans = items.select(item -> new DataManagementPlanProfileListingModel().fromDataModel(item)); return datamanagementPlans; } public void createOrUpdate(DataManagementPlanProfileListingModel dataManagementPlanProfileListingModel, Principal principal) throws Exception { DMPProfile dmpProfile = dataManagementPlanProfileListingModel.toDataModel(); apiContext.getOperationsContext().getDatabaseRepository().getDmpProfileDao().createOrUpdate(dmpProfile); } public void createOrUpdateBlueprint(DataManagementPlanBlueprintListingModel dataManagementPlanBlueprintListingModel, Principal principal) throws Exception { DMPProfile dmpProfile = dataManagementPlanBlueprintListingModel.toDataModel(); apiContext.getOperationsContext().getDatabaseRepository().getDmpProfileDao().createOrUpdate(dmpProfile); } public void inactivate(String id) { DMPProfile dmpProfile = databaseRepository.getDmpProfileDao().find(UUID.fromString(id)); DataManagementPlanCriteria dataManagementPlanCriteria = new DataManagementPlanCriteria(); dataManagementPlanCriteria.setProfile(dmpProfile); if (dmpProfile.getStatus() == DMPProfile.Status.SAVED.getValue() || databaseRepository.getDmpDao().getWithCriteria(dataManagementPlanCriteria).count() == 0) { dmpProfile.setStatus(DMPProfile.Status.DELETED.getValue()); databaseRepository.getDmpProfileDao().createOrUpdate(dmpProfile); } else { throw new DmpBlueprintUsedException("This blueprint can not deleted, because DMPs are associated with it"); } } public ResponseEntity getDocument(DataManagementPlanBlueprintListingModel dmpProfile) throws IOException { FileEnvelope envelope = getXmlDocument(dmpProfile); InputStream resource = new FileInputStream(envelope.getFile()); logger.info("Mime Type of " + envelope.getFilename() + " is " + new MimetypesFileTypeMap().getContentType(envelope.getFile())); HttpHeaders responseHeaders = new HttpHeaders(); responseHeaders.setContentLength(envelope.getFile().length()); responseHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM); String fileName = envelope.getFilename().replace(" ", "_").replace(",", "_"); responseHeaders.set("Content-Disposition", "attachment;filename=" + fileName + ".xml"); responseHeaders.set("Access-Control-Expose-Headers", "Content-Disposition"); responseHeaders.get("Access-Control-Expose-Headers").add("Content-Type"); byte[] content = org.apache.poi.util.IOUtils.toByteArray(resource); resource.close(); Files.deleteIfExists(envelope.getFile().toPath()); return new ResponseEntity<>(content, responseHeaders, HttpStatus.OK); } public FileEnvelope getXmlDocument(DataManagementPlanBlueprintListingModel dmpProfile) throws IOException { ExportXmlBuilderDmpBlueprint xmlBuilder = new ExportXmlBuilderDmpBlueprint(); File file = xmlBuilder.build(dmpProfile, environment); FileEnvelope fileEnvelope = new FileEnvelope(); fileEnvelope.setFile(file); fileEnvelope.setFilename(dmpProfile.getLabel()); return fileEnvelope; } public eu.eudat.logic.utilities.documents.xml.dmpXml.dmpBlueprintModel.DmpBlueprint createDmpProfileFromXml(MultipartFile multiPartFile) { ImportXmlBuilderDmpBlueprint xmlBuilder = new ImportXmlBuilderDmpBlueprint(); try { return xmlBuilder.build(convert(multiPartFile)); } catch (IOException e) { logger.error(e.getMessage(), e); } return null; } private File convert(MultipartFile file) throws IOException { File convFile = new File(this.environment.getProperty("temp.temp") + file.getOriginalFilename()); convFile.createNewFile(); FileOutputStream fos = new FileOutputStream(convFile); fos.write(file.getBytes()); fos.close(); return convFile; } public List> getExternalAutocomplete(RequestItem lookupItem) throws XPathExpressionException { DMPProfile dmpProfile = this.apiContext.getOperationsContext().getDatabaseRepository().getDmpProfileDao().find(UUID.fromString(lookupItem.getCriteria().getProfileID())); Field field = this.queryForField(dmpProfile.getDefinition(), lookupItem.getCriteria().getFieldID()); DmpProfileExternalAutoComplete data = field.getExternalAutocomplete(); return this.externalAutocompleteRequest(data, lookupItem.getCriteria().getLike()); } private Field queryForField(String xml, String fieldId) throws XPathExpressionException { Field field = new Field(); Document document = XmlBuilder.fromXml(xml); XPathFactory xpathFactory = XPathFactory.newInstance(); XPath xpath = xpathFactory.newXPath(); XPathExpression expr = xpath.compile("//field[@id='" + fieldId + "']"); Element name = (Element) expr.evaluate(document, XPathConstants.NODE); field.fromXml(name); return field; } private List> externalAutocompleteRequest(DmpProfileExternalAutoComplete data, String like) { return externalAutocompleteRequest(data.getUrl(), data.getOptionsRoot(), data.getLabel(), data.getValue(), like); } public static List> externalAutocompleteRequest(String url, String optionsRoot, String label, String value, String like) { List> result = new LinkedList<>(); RestTemplate restTemplate = new RestTemplate(); HttpHeaders headers = new HttpHeaders(); headers.setAccept(Collections.singletonList(MediaType.valueOf("application/vnd.api+json; charset=utf-8"))); headers.setContentType(MediaType.APPLICATION_JSON); HttpEntity entity = new HttpEntity<>("parameters", headers); ResponseEntity response = restTemplate.exchange(url + "?search=" + like, HttpMethod.GET, entity, Object.class); DocumentContext jsonContext = JsonPath.parse(response.getBody()); List> jsonItems = jsonContext.read(optionsRoot + "['" + label + "','" + value + "']"); jsonItems.forEach(item -> result.add(new Tuple<>(item.get(value), item.get(label)))); return result; } }