1
2
3
4
5
6
7 package org.tailormap.api.controller;
8
9 import static org.springframework.http.HttpStatus.BAD_REQUEST;
10 import static org.springframework.http.HttpStatus.NOT_FOUND;
11 import static org.springframework.http.HttpStatus.NOT_MODIFIED;
12 import static org.tailormap.api.service.UploadsService.createUploadResponseEntity;
13
14 import jakarta.servlet.http.HttpServletRequest;
15 import java.util.UUID;
16 import org.springframework.http.CacheControl;
17 import org.springframework.http.ResponseEntity;
18 import org.springframework.web.bind.annotation.GetMapping;
19 import org.springframework.web.bind.annotation.PathVariable;
20 import org.springframework.web.bind.annotation.RestController;
21 import org.springframework.web.server.ResponseStatusException;
22 import org.tailormap.api.persistence.Upload;
23 import org.tailormap.api.persistence.UploadCategory;
24 import org.tailormap.api.repository.UploadRepository;
25 import org.tailormap.api.service.UploadsService;
26
27 @RestController
28 public class UploadsController {
29 private final UploadRepository uploadRepository;
30 private final UploadsService uploadsService;
31
32 public UploadsController(UploadRepository uploadRepository, UploadsService uploadsService) {
33 this.uploadRepository = uploadRepository;
34 this.uploadsService = uploadsService;
35 }
36
37 @GetMapping(
38 path = {
39
40
41 "/api/uploads/{category}/{id}",
42 "/api/uploads/{category}/{id}/{filename}"
43 })
44 public ResponseEntity<byte[]> getUpload(
45 HttpServletRequest request,
46 @PathVariable UploadCategory category,
47 @PathVariable(name = "id") UUID id,
48 @PathVariable(required = false) String filename) {
49
50 if (category.isRestricted()) {
51 throw new ResponseStatusException(
52 BAD_REQUEST, "Uploads for category " + category + " are not accessible via this endpoint");
53 }
54
55 long ifModifiedSince = request.getDateHeader("If-Modified-Since");
56
57 if (!uploadsService.checkIfModifiedSince(id, ifModifiedSince)) {
58 return ResponseEntity.status(NOT_MODIFIED).build();
59 }
60
61 Upload upload = uploadRepository
62 .findWithContentByIdAndCategory(id, category)
63 .orElseThrow(() -> new ResponseStatusException(NOT_FOUND));
64 return createUploadResponseEntity(upload);
65 }
66
67
68
69
70
71 @GetMapping("/api/uploads/{category}/latest")
72 public ResponseEntity<byte[]> getLatestUpload(@PathVariable UploadCategory category) {
73 if (category.isRestricted()) {
74 throw new ResponseStatusException(
75 BAD_REQUEST, "Uploads for category " + category + " are not accessible via this endpoint");
76 }
77 return uploadRepository
78 .findFirstWithContentByCategoryOrderByLastModifiedDesc(category)
79 .map(upload -> ResponseEntity.ok()
80 .header("Content-Type", upload.getMimeType())
81 .header(UploadsService.DESCRIPTION_HEADER_NAME, upload.getDescription())
82 .lastModified(upload.getLastModified().toInstant())
83 .contentLength(upload.getContentLength())
84 .cacheControl(CacheControl.noCache().cachePublic())
85 .body(upload.getContent()))
86 .orElseThrow(() -> new ResponseStatusException(NOT_FOUND));
87 }
88 }