package it.inaf.ia2.transfer.controller; import it.inaf.ia2.transfer.persistence.FileDAO; import it.inaf.ia2.transfer.persistence.ListOfFilesDAO; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; import java.util.List; import java.util.Optional; import javax.servlet.http.HttpServletRequest; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import static org.springframework.http.HttpStatus.NOT_FOUND; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; @RestController public class PutFileController { @Value("${path_prefix}") private String pathPrefix; @Autowired private FileDAO fileDAO; @Autowired private ListOfFilesDAO listOfFilesDAO; @Autowired private HttpServletRequest request; @PutMapping("/**") public ResponseEntity putFile(@RequestParam("file") MultipartFile file) throws IOException { String path = request.getServletPath(); Optional optFileInfo = fileDAO.getFileInfo(path); if (optFileInfo.isPresent()) { try (InputStream in = file.getInputStream()) { storeFile(optFileInfo.get(), in); } return ResponseEntity.ok().build(); } else { return new ResponseEntity<>("File " + path + " not found", NOT_FOUND); } } private void storeFile(FileInfo fileInfo, InputStream is) throws IOException { if (fileInfo.getAcceptViews() != null && fileInfo.getAcceptViews().contains("urn:list-of-files")) { storeListOfFiles(fileInfo, is); } else { storeGenericFile(fileInfo, is); } } private void storeListOfFiles(FileInfo fileInfo, InputStream is) throws IOException { List filePaths = parseListOfFiles(is); listOfFilesDAO.createList(fileInfo.getVirtualPath(), filePaths); } private List parseListOfFiles(InputStream is) throws IOException { List filePaths = new ArrayList<>(); try (BufferedReader br = new BufferedReader(new InputStreamReader(is))) { String line; while ((line = br.readLine()) != null && !line.isBlank()) { filePaths.add(line.trim()); } } return filePaths; } private void storeGenericFile(FileInfo fileInfo, InputStream is) throws IOException { Path path = Path.of(pathPrefix, fileInfo.getOsRelPath()); File file = path.toFile(); /** * This block must be synchronized, to avoid concurrency issues when * multiple files are uploaded to a new folder in parallel. */ synchronized (this) { if (!file.getParentFile().exists()) { if (!file.getParentFile().mkdirs()) { throw new IllegalStateException("Unable to create parent folder: " + file.getParentFile().getAbsolutePath()); } } } Files.copy(is, file.toPath()); } }