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.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.utilities.documents.helpers.FileEnvelope; 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.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import javax.persistence.NoResultException; 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; @Autowired public Datasets(ApiContext apiContext, Environment environment, DatasetManager datasetManager, ConfigLoader configLoader, UserManager userManager) { super(apiContext); this.environment = environment; this.datasetManager = datasetManager; this.configLoader = configLoader; this.userManager = userManager; } /* * 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())); // } } @javax.transaction.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 { if (contentType.equals("application/xml")) { VisibilityRuleService visibilityRuleService = this.getApiContext().getUtilitiesService().getVisibilityRuleService(); return this.datasetManager.getDocument(id, visibilityRuleService, contentType, principal); } else if (contentType.equals("application/msword")) { FileEnvelope file = datasetManager.getWordDocumentFile(this.configLoader, id, this.getApiContext().getUtilitiesService().getVisibilityRuleService(), principal); InputStream resource = new FileInputStream(file.getFile()); HttpHeaders responseHeaders = new HttpHeaders(); responseHeaders.setContentLength(file.getFile().length()); responseHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM); responseHeaders.set("Content-Disposition", "attachment;filename=" + file.getFilename()); 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(), 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, this.getApiContext().getUtilitiesService().getVisibilityRuleService(), principal); String fileName = file.getFilename(); if (fileName.endsWith(".docx")){ fileName = fileName.substring(0, fileName.length() - 5); } File pdffile = datasetManager.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 * */ @javax.transaction.Transactional @RequestMapping(method = RequestMethod.POST, consumes = "application/json", produces = "application/json") public @ResponseBody ResponseEntity> createOrUpdate(@RequestBody DatasetWizardModel profile, Principal principal) throws Exception { Dataset dataset = this.datasetManager.createOrUpdate(profile, principal); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE).message("Created").payload(dataset.getId())); } @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))); } @javax.transaction.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); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE).message("Deleted")); } @javax.transaction.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())); } } /* * 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 * */ @javax.transaction.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)); } @javax.transaction.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)); } }