2022-03-16 11:14:08 +01:00
package eu.eudat.controllers ;
2022-04-18 17:26:20 +02:00
import com.fasterxml.jackson.core.JsonProcessingException ;
2022-03-16 11:14:08 +01:00
import com.fasterxml.jackson.databind.JsonNode ;
import com.fasterxml.jackson.databind.ObjectMapper ;
import eu.eudat.data.entities.FileUpload ;
import eu.eudat.exceptions.security.UnauthorisedException ;
import eu.eudat.logic.managers.DatasetProfileManager ;
import eu.eudat.logic.security.claims.ClaimedAuthorities ;
import eu.eudat.logic.services.ApiContext ;
import eu.eudat.logic.services.operations.DatabaseRepository ;
import eu.eudat.logic.utilities.documents.helpers.FileEnvelope ;
import eu.eudat.logic.utilities.json.JsonSearcher ;
import eu.eudat.models.HintedModelFactory ;
2022-04-18 17:26:20 +02:00
import eu.eudat.models.data.components.commons.datafield.UploadData ;
2022-03-16 11:14:08 +01:00
import eu.eudat.models.data.datasetwizard.DatasetWizardModel ;
import eu.eudat.models.data.helpers.responses.ResponseItem ;
import eu.eudat.models.data.security.Principal ;
import eu.eudat.types.ApiMessageCode ;
import eu.eudat.types.Authorities ;
import org.apache.poi.util.IOUtils ;
2022-04-18 17:26:20 +02:00
import org.slf4j.Logger ;
import org.slf4j.LoggerFactory ;
2022-03-16 11:14:08 +01:00
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.transaction.Transactional ;
import java.io.* ;
import java.nio.file.Files ;
2022-04-18 17:26:20 +02:00
import java.util.HashSet ;
import java.util.NoSuchElementException ;
import java.util.Set ;
import java.util.UUID ;
2022-03-16 11:14:08 +01:00
import java.util.stream.Collectors ;
@RestController
@RequestMapping ( value = { " /api/file/ " } )
public class FileController {
2022-04-18 17:26:20 +02:00
private static final Logger logger = LoggerFactory . getLogger ( FileController . class ) ;
2022-03-16 11:14:08 +01:00
private DatasetProfileManager datasetProfileManager ;
private final Environment environment ;
private DatabaseRepository databaseRepository ;
2022-04-18 17:26:20 +02:00
private final ObjectMapper objectMapper ;
2022-03-16 11:14:08 +01:00
@Autowired
public FileController ( DatasetProfileManager datasetProfileManager , Environment environment , ApiContext apiContext ) {
this . datasetProfileManager = datasetProfileManager ;
this . environment = environment ;
this . databaseRepository = apiContext . getOperationsContext ( ) . getDatabaseRepository ( ) ;
2022-04-18 17:26:20 +02:00
this . objectMapper = apiContext . getUtilitiesService ( ) . getGenericObjectMapper ( ) ;
2022-03-16 11:14:08 +01:00
}
@RequestMapping ( method = RequestMethod . POST , value = { " /upload " } )
public ResponseEntity < ResponseItem < String > > upload (
@RequestParam ( " file " ) MultipartFile file , @RequestParam ( " datasetProfileId " ) String datasetProfileId , @RequestParam ( " fieldId " ) String fieldId ,
@ClaimedAuthorities ( claims = { Authorities . ADMIN , Authorities . MANAGER , Authorities . USER } ) Principal principal )
throws IllegalAccessException , IOException {
String uuid = UUID . randomUUID ( ) . toString ( ) ;
eu . eudat . models . data . admin . composite . DatasetProfile datasetprofile = this . datasetProfileManager . getDatasetProfile ( datasetProfileId ) ;
2022-04-18 17:26:20 +02:00
String json = objectMapper . writeValueAsString ( datasetprofile . getSections ( ) ) ;
JsonNode propertiesJson = objectMapper . readTree ( json ) ;
2022-03-16 11:14:08 +01:00
Set < JsonNode > fieldNodes = new HashSet < > ( ) ;
fieldNodes . addAll ( JsonSearcher . findNodes ( propertiesJson , " id " , fieldId , false ) ) ;
// AtomicReference<String> exceptionMessage = null;
2022-04-18 17:26:20 +02:00
Boolean acceptedFile = false ;
for ( JsonNode node : fieldNodes ) {
2022-03-16 11:14:08 +01:00
JsonNode data = node . get ( " data " ) ;
2022-04-18 17:26:20 +02:00
try {
UploadData uploadData = objectMapper . treeToValue ( data , UploadData . class ) ;
if ( uploadData ! = null ) {
if ( uploadData . getMaxFileSizeInMB ( ) ! = null ) {
if ( file . getSize ( ) < = ( uploadData . getMaxFileSizeInMB ( ) * Math . pow ( 1024 , 2 ) ) ) {
acceptedFile = true ;
}
2022-03-16 11:14:08 +01:00
}
2022-04-18 17:26:20 +02:00
if ( acceptedFile & & uploadData . getTypes ( ) ! = null & & ! uploadData . getTypes ( ) . isEmpty ( ) ) {
acceptedFile = false ;
for ( UploadData . Option option : uploadData . getTypes ( ) ) {
if ( option . getValue ( ) ! = null ) {
if ( file . getContentType ( ) . equals ( option . getValue ( ) ) ) {
acceptedFile = true ;
}
2022-03-16 11:14:08 +01:00
}
}
2022-04-18 17:26:20 +02:00
}
2022-03-16 11:14:08 +01:00
}
2022-04-18 17:26:20 +02:00
} catch ( JsonProcessingException e ) {
logger . error ( e . getLocalizedMessage ( ) , e ) ;
}
}
2022-03-16 11:14:08 +01:00
// if(!acceptedFile.get()) {
// exceptionMessage.set("The file type is not accepted.");
// }
2022-04-18 17:26:20 +02:00
if ( ! acceptedFile ) {
2022-03-16 11:14:08 +01:00
return ResponseEntity . status ( HttpStatus . BAD_REQUEST ) . body ( new ResponseItem < String > ( ) . status ( ApiMessageCode . ERROR_MESSAGE ) . message ( " The uploaded file is too large or has an unaccepted type " ) ) ;
}
File convFile = new File ( this . environment . getProperty ( " temp.temp " ) + uuid ) ;
FileOutputStream fos = new FileOutputStream ( convFile ) ;
fos . write ( file . getBytes ( ) ) ;
fos . close ( ) ;
return ResponseEntity . status ( HttpStatus . OK ) . body ( new ResponseItem < String > ( ) . payload ( uuid )
. status ( ApiMessageCode . SUCCESS_MESSAGE ) . message ( " " ) ) ;
}
@RequestMapping ( method = RequestMethod . POST , value = { " /delete-temp " } )
public ResponseEntity < ResponseItem < String > > upload ( @RequestBody String filename ) throws IllegalAccessException , IOException {
File convFile = new File ( this . environment . getProperty ( " temp.temp " ) + filename ) ;
// Boolean deleted = convFile.delete();
Boolean deleted = Files . deleteIfExists ( convFile . toPath ( ) ) ;
return ResponseEntity . status ( HttpStatus . OK ) . body ( new ResponseItem < String > ( ) . payload ( deleted . toString ( ) )
. status ( ApiMessageCode . SUCCESS_MESSAGE ) . message ( " " ) ) ;
}
@Transactional
@RequestMapping ( method = RequestMethod . GET , value = { " {id} " } , produces = " application/json " )
public @ResponseBody
ResponseEntity download ( @PathVariable String id
, @ClaimedAuthorities ( claims = { Authorities . ADMIN , Authorities . MANAGER , Authorities . USER , Authorities . ANONYMOUS } ) Principal principal
) throws IOException {
FileUpload fileUpload = databaseRepository . getFileUploadDao ( ) . find ( UUID . fromString ( id ) ) ;
if ( fileUpload = = null ) {
throw new NoSuchElementException ( " File with id " + id + " not found " ) ;
}
if ( fileUpload . getEntityType ( ) . name ( ) . equals ( FileUpload . EntityType . DATASET . name ( ) ) ) {
eu . eudat . data . entities . Dataset datasetEntity = databaseRepository . getDatasetDao ( ) . find ( fileUpload . getEntityId ( ) , HintedModelFactory . getHint ( DatasetWizardModel . class ) ) ;
if ( datasetEntity = = null ) {
throw new NoSuchElementException ( " No dataset with id " + fileUpload . getEntityId ( ) + " found. This dataset was related to the file with id " + id ) ;
}
if ( ! datasetEntity . getDmp ( ) . isPublic ( ) & & datasetEntity . getDmp ( ) . getUsers ( )
. stream ( ) . filter ( userInfo - > userInfo . getUser ( ) . getId ( ) = = principal . getId ( ) )
. collect ( Collectors . toList ( ) ) . size ( ) = = 0 )
throw new UnauthorisedException ( ) ;
}
FileEnvelope fileEnvelope = new FileEnvelope ( ) ;
fileEnvelope . setFilename ( fileUpload . getName ( ) ) ;
File exportFile = new File ( this . environment . getProperty ( " file.storage " ) + id ) ;
fileEnvelope . setFile ( exportFile ) ;
InputStream resource = new FileInputStream ( fileEnvelope . getFile ( ) ) ;
HttpHeaders responseHeaders = new HttpHeaders ( ) ;
responseHeaders . setContentLength ( fileEnvelope . getFile ( ) . length ( ) ) ;
responseHeaders . setContentType ( MediaType . APPLICATION_OCTET_STREAM ) ;
String fileName = fileEnvelope . getFilename ( ) . replace ( " " , " _ " ) . replace ( " , " , " _ " ) ;
responseHeaders . set ( " Content-Disposition " , " attachment;filename= " + fileName ) ;
responseHeaders . set ( " Access-Control-Expose-Headers " , " Content-Disposition " ) ;
responseHeaders . set ( " Cache-Control " , " no-store " ) ;
responseHeaders . get ( " Access-Control-Expose-Headers " ) . add ( " Content-Type " ) ;
byte [ ] content = IOUtils . toByteArray ( resource ) ;
resource . close ( ) ;
return new ResponseEntity < > ( content ,
responseHeaders ,
HttpStatus . OK ) ;
}
}