package eu.eudat.controllers; import eu.eudat.data.entities.Dataset; import eu.eudat.data.query.items.item.dataset.DatasetWizardAutocompleteRequest; import eu.eudat.data.query.items.item.datasetprofile.DatasetProfileWizardAutocompleteRequest; import eu.eudat.data.query.items.table.dataset.DatasetPublicTableRequest; import eu.eudat.data.query.items.table.dataset.DatasetTableRequest; import eu.eudat.data.query.items.table.datasetprofile.DatasetProfileTableRequestItem; import eu.eudat.exceptions.datasetwizard.DatasetWizardCannotUnlockException; import eu.eudat.exceptions.security.UnauthorisedException; import eu.eudat.logic.managers.DatasetManager; import eu.eudat.logic.managers.DatasetWizardManager; import eu.eudat.logic.managers.FileManager; import eu.eudat.logic.managers.UserManager; import eu.eudat.logic.proxy.config.configloaders.ConfigLoader; import eu.eudat.logic.security.claims.ClaimedAuthorities; import eu.eudat.logic.services.ApiContext; import eu.eudat.logic.services.forms.VisibilityRuleService; import eu.eudat.logic.services.forms.VisibilityRuleServiceImpl; import eu.eudat.logic.utilities.documents.helpers.FileEnvelope; import eu.eudat.logic.utilities.documents.pdf.PDFUtils; import eu.eudat.models.data.dataset.DatasetOverviewModel; import eu.eudat.models.data.datasetprofile.DatasetProfileListingModel; import eu.eudat.models.data.datasetwizard.DataManagentPlanListingModel; import eu.eudat.models.data.datasetwizard.DatasetWizardModel; import eu.eudat.models.data.dmp.AssociatedProfile; import eu.eudat.models.data.helpers.common.DataTableData; import eu.eudat.models.data.helpers.responses.ResponseItem; import eu.eudat.models.data.listingmodels.DataManagementPlanOverviewModel; 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.types.ApiMessageCode; import eu.eudat.types.Authorities; import org.apache.poi.util.IOUtils; 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.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import javax.persistence.NoResultException; import javax.transaction.Transactional; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.nio.file.Files; import java.util.List; import java.util.Locale; import java.util.UUID; import static eu.eudat.types.Authorities.ANONYMOUS; @RestController @CrossOrigin @RequestMapping(value = {"/api/datasets/"}) public class Datasets extends BaseController { private static final Logger logger = LoggerFactory.getLogger(Datasets.class); private Environment environment; private DatasetManager datasetManager; private ConfigLoader configLoader; private UserManager userManager; private FileManager fileManager; @Autowired public Datasets(ApiContext apiContext, Environment environment, DatasetManager datasetManager, ConfigLoader configLoader, UserManager userManager, FileManager fileManager) { super(apiContext); this.environment = environment; this.datasetManager = datasetManager; this.configLoader = configLoader; this.userManager = userManager; this.fileManager = fileManager; } /* * Data Retrieval * */ @RequestMapping(method = RequestMethod.POST, value = {"paged"}, consumes = "application/json", produces = "application/json") public @ResponseBody ResponseEntity>> getPaged(@RequestBody DatasetTableRequest datasetTableRequest, @ClaimedAuthorities(claims = {Authorities.ADMIN, Authorities.MANAGER, Authorities.USER, Authorities.ANONYMOUS}) Principal principal) throws Exception { DataTableData dataTable = this.datasetManager.getPaged(datasetTableRequest, principal); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem>().status(ApiMessageCode.NO_MESSAGE).payload(dataTable)); } @RequestMapping(method = RequestMethod.POST, value = {"/public/paged"}, consumes = "application/json", produces = "application/json") public @ResponseBody ResponseEntity>> getPublicPaged(@RequestBody DatasetPublicTableRequest datasetTableRequest, @ClaimedAuthorities(claims = {Authorities.ADMIN, Authorities.MANAGER, Authorities.USER, Authorities.ANONYMOUS}) Principal principal) throws Exception { DataTableData dataTable = this.datasetManager.getPaged(datasetTableRequest, principal); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem>().status(ApiMessageCode.NO_MESSAGE).payload(dataTable)); } @RequestMapping(method = RequestMethod.GET, value = {"/overview/{id}"}) public @ResponseBody ResponseEntity getOverviewSingle(@PathVariable String id,@ClaimedAuthorities(claims = {Authorities.ADMIN, Authorities.MANAGER, Authorities.USER, Authorities.ANONYMOUS}) Principal principal) { try { DatasetOverviewModel dataset = this.datasetManager.getOverviewSingle(id, principal, false); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.NO_MESSAGE).payload(dataset)); } catch (Exception e) { if (e instanceof UnauthorisedException) { return ResponseEntity.status(HttpStatus.FORBIDDEN).body(new ResponseItem().status(ApiMessageCode.ERROR_MESSAGE)); } else { return ResponseEntity.status(HttpStatus.NOT_FOUND).body(new ResponseItem().status(ApiMessageCode.ERROR_MESSAGE)); } } } @RequestMapping(method = RequestMethod.GET, value = {"/publicOverview/{id}"}) public @ResponseBody ResponseEntity getOverviewSinglePublic(@PathVariable String id, @ClaimedAuthorities(claims = {Authorities.ADMIN, Authorities.MANAGER, Authorities.USER, Authorities.ANONYMOUS}) Principal principal) throws Exception { // try { DatasetOverviewModel dataset = this.datasetManager.getOverviewSingle(id, principal, true); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.NO_MESSAGE).payload(dataset)); // } catch (Exception ex) { // return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem().status(ApiMessageCode.NO_MESSAGE).message(ex.getMessage())); // } } @Transactional @RequestMapping(method = RequestMethod.GET, value = {"{id}"}, produces = "application/json") public @ResponseBody ResponseEntity getSingle(@PathVariable String id, @RequestHeader("Content-Type") String contentType, @ClaimedAuthorities(claims = {Authorities.ADMIN, Authorities.MANAGER, Authorities.USER, Authorities.ANONYMOUS}) Principal principal) throws IllegalAccessException, IOException, InstantiationException { try { VisibilityRuleService visibilityRuleService = new VisibilityRuleServiceImpl(); if (contentType.equals("application/xml")) { return this.datasetManager.getDocument(id, visibilityRuleService, contentType, principal); } else if (contentType.equals("application/msword")) { FileEnvelope file = datasetManager.getWordDocumentFile(this.configLoader, id, visibilityRuleService, principal); InputStream resource = new FileInputStream(file.getFile()); HttpHeaders responseHeaders = new HttpHeaders(); responseHeaders.setContentLength(file.getFile().length()); responseHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM); String fileName = file.getFilename().replace(" ", "_").replace(",", "_"); responseHeaders.set("Content-Disposition", "attachment;filename=" + fileName); responseHeaders.set("Access-Control-Expose-Headers", "Content-Disposition"); responseHeaders.get("Access-Control-Expose-Headers").add("Content-Type"); byte[] content = IOUtils.toByteArray(resource); resource.close(); Files.deleteIfExists(file.getFile().toPath()); return new ResponseEntity<>(content, responseHeaders, HttpStatus.OK); } else { DatasetWizardModel dataset = this.datasetManager.getSingle(id, principal); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.NO_MESSAGE).payload(dataset)); } } catch (Exception e) { logger.error(e.getMessage(), e); if (e instanceof UnauthorisedException) { return ResponseEntity.status(HttpStatus.FORBIDDEN).body(new ResponseItem().status(ApiMessageCode.ERROR_MESSAGE)); } else if (e instanceof NoResultException) { return ResponseEntity.status(HttpStatus.NOT_FOUND).body(new ResponseItem().status(ApiMessageCode.ERROR_MESSAGE)); } else { return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(new ResponseItem().status(ApiMessageCode.ERROR_MESSAGE)); } } } @RequestMapping(method = RequestMethod.POST, value = {"/datasetProfilesUsedByDatasets/paged"}, produces = "application/json") public @ResponseBody ResponseEntity>> getUsingDatasetProfilesPaged(@RequestBody DatasetProfileTableRequestItem datasetProfileTableRequestItem, Principal principal) { DataTableData datasetProfileTableData = this.datasetManager.getDatasetProfilesUsedByDatasets(datasetProfileTableRequestItem, principal); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem>().status(ApiMessageCode.NO_MESSAGE).payload(datasetProfileTableData)); } @RequestMapping(method = RequestMethod.POST, value = {"/userDmps"}, produces = "application/json") public @ResponseBody ResponseEntity>> getUserDmps(@RequestBody DatasetWizardAutocompleteRequest datasetWizardAutocompleteRequest, Principal principal) throws IllegalAccessException, InstantiationException { List dataManagementPlans = DatasetWizardManager.getUserDmps(this.getApiContext().getOperationsContext().getDatabaseRepository().getDmpDao(), datasetWizardAutocompleteRequest, principal); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem>().status(ApiMessageCode.NO_MESSAGE).payload(dataManagementPlans)); } @RequestMapping(method = RequestMethod.POST, value = {"/getAvailableProfiles"}, produces = "application/json") public @ResponseBody ResponseEntity>> getAvailableProfiles(@RequestBody DatasetProfileWizardAutocompleteRequest datasetProfileWizardAutocompleteRequest, @ClaimedAuthorities(claims = {ANONYMOUS}) Principal principal) throws IllegalAccessException, InstantiationException { List dataManagementPlans = DatasetWizardManager.getAvailableProfiles(this.getApiContext().getOperationsContext().getDatabaseRepository().getDmpDao(), this.getApiContext().getOperationsContext().getDatabaseRepository().getDatasetProfileDao(), datasetProfileWizardAutocompleteRequest); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem>().status(ApiMessageCode.NO_MESSAGE).payload(dataManagementPlans)); } @RequestMapping(method = RequestMethod.GET, value = {"/public/{id}"}, produces = "application/json") public @ResponseBody ResponseEntity getSinglePublic(@PathVariable String id) throws Exception { try { DatasetWizardModel dataset = this.datasetManager.getSinglePublic(id); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.NO_MESSAGE).payload(dataset)); } catch (Exception ex) { return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem().status(ApiMessageCode.NO_MESSAGE).message(ex.getMessage())); } } @RequestMapping(method = RequestMethod.GET, value = {"/get/{id}"}, produces = "application/json") public ResponseEntity> getSingle(@PathVariable String id) { eu.eudat.data.entities.DatasetProfile profile = this.getApiContext().getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(UUID.fromString(id)); eu.eudat.models.data.user.composite.DatasetProfile datasetprofile = userManager.generateDatasetProfileModel(profile); PagedDatasetProfile pagedDatasetProfile = new PagedDatasetProfile(); pagedDatasetProfile.buildPagedDatasetProfile(datasetprofile); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.NO_MESSAGE).payload(pagedDatasetProfile)); } @RequestMapping(method = RequestMethod.GET, value = {"profile/{id}"}, produces = "application/json") public @ResponseBody ResponseEntity getSingleProfileUpdate(@PathVariable String id, @ClaimedAuthorities(claims = {ANONYMOUS}) Principal principal) throws IllegalAccessException, IOException, InstantiationException { DatasetWizardModel dataset = this.datasetManager.datasetUpdateProfile(id); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.NO_MESSAGE).payload(dataset)); } /* * Data Export * */ @RequestMapping(method = RequestMethod.GET, value = {"/getPDF/{id}"}) public @ResponseBody ResponseEntity getPDFDocument(@PathVariable String id, @ClaimedAuthorities(claims = {Authorities.ADMIN, Authorities.MANAGER, Authorities.USER, Authorities.ANONYMOUS}) Principal principal) throws IllegalAccessException, IOException, InstantiationException, InterruptedException { FileEnvelope file = datasetManager.getWordDocumentFile(this.configLoader, id, new VisibilityRuleServiceImpl(), principal); String fileName = file.getFilename().replace(" ", "_").replace(",", "_"); if (fileName.endsWith(".docx")){ fileName = fileName.substring(0, fileName.length() - 5); } File pdffile = PDFUtils.convertToPDF(file, environment); InputStream resource = new FileInputStream(pdffile); HttpHeaders responseHeaders = new HttpHeaders(); responseHeaders.setContentLength(pdffile.length()); responseHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM); responseHeaders.set("Content-Disposition", "attachment;filename=" + fileName + ".pdf"); responseHeaders.set("Access-Control-Expose-Headers", "Content-Disposition"); responseHeaders.get("Access-Control-Expose-Headers").add("Content-Type"); byte[] content = IOUtils.toByteArray(resource); resource.close(); Files.deleteIfExists(file.getFile().toPath()); Files.deleteIfExists(pdffile.toPath()); return new ResponseEntity<>(content, responseHeaders, HttpStatus.OK); } /* * Data Management * */ @Transactional @RequestMapping(method = RequestMethod.POST, consumes = "application/json", produces = "application/json") public @ResponseBody ResponseEntity> createOrUpdate(@RequestBody DatasetWizardModel profile, Principal principal) throws Exception { DatasetWizardModel dataset = new DatasetWizardModel().fromDataModel(this.datasetManager.createOrUpdate(profile, principal)); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE).message("Created").payload(dataset)); } @Transactional @RequestMapping(method = RequestMethod.GET, value = {"/makepublic/{id}"}, produces = "application/json") public @ResponseBody ResponseEntity> makePublic(@PathVariable UUID id, Principal principal, Locale locale) throws Exception { this.datasetManager.makePublic(this.getApiContext().getOperationsContext().getDatabaseRepository().getDatasetDao(), id); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE).message(this.getApiContext().getHelpersService().getMessageSource().getMessage("dataset.public", new Object[]{}, locale))); } @Transactional @RequestMapping(method = RequestMethod.DELETE, value = {"/delete/{id}"}, produces = "application/json") public @ResponseBody ResponseEntity> delete(@PathVariable(value = "id") UUID id, Principal principal) throws Exception { new DatasetWizardManager().delete(this.getApiContext(), id); this.fileManager.markAllFilesOfEntityIdAsDeleted(id); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE).message("Deleted")); } @Transactional @RequestMapping(method = RequestMethod.GET, value = {"/{id}/unlock"}, produces = "application/json") public @ResponseBody ResponseEntity> unlock(@PathVariable(value = "id") UUID id, Principal principal) throws Exception { try { new DatasetWizardManager().unlock(this.getApiContext(), id); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE).message("Unlocked")); } catch (DatasetWizardCannotUnlockException datasetWizardCannotUnlockException) { return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem().status(ApiMessageCode.ERROR_MESSAGE).message(datasetWizardCannotUnlockException.getMessage())); } } @RequestMapping(method = RequestMethod.GET, value = {"/{id}/validate"}, produces = "application/json") public @ResponseBody ResponseEntity> validate(@PathVariable(value = "id") UUID id, Principal principal) throws Exception { Dataset dataset = datasetManager.getEntitySingle(id); String failedField = datasetManager.checkDatasetValidation(dataset); if (failedField == null) { return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE).message("Valid")); } else { return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem().status(ApiMessageCode.ERROR_MESSAGE).message("Field value of " + failedField + " must be filled.")); } } /* * Data Import * */ @RequestMapping(method = RequestMethod.POST, value = {"/upload"}) public ResponseEntity datasetXmlImport(@RequestParam("file") MultipartFile file, @RequestParam("dmpId") String dmpId, @RequestParam("datasetProfileId") String datasetProfileId, Principal principal) { try { Dataset dataset = this.datasetManager.createDatasetFromXml(file, dmpId, datasetProfileId, principal); if (dataset != null){ return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE)); } else { return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem().status(ApiMessageCode.NO_MESSAGE).message("Import was unsuccessful.")); } } catch (Exception e) { logger.error(e.getMessage(), e); return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem().status(ApiMessageCode.NO_MESSAGE).message("Import was unsuccessful.")); } } /* * Data Index * */ @Transactional @RequestMapping(method = RequestMethod.POST, value = {"/index"}) public @ResponseBody ResponseEntity> generateIndex(Principal principal) throws Exception { this.datasetManager.generateIndex(principal); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE).message("Generated").payload(null)); } @Transactional @RequestMapping(method = RequestMethod.DELETE, value = {"/index"}) public @ResponseBody ResponseEntity> clearIndex(Principal principal) throws Exception { this.datasetManager.clearIndex(principal); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE).message("Cleared").payload(null)); } }