From a5c0add82b6f27b848018d2c063b91f99233d4d3 Mon Sep 17 00:00:00 2001 From: Jesse Brault Date: Fri, 26 Jul 2024 10:12:14 -0500 Subject: [PATCH] ImageController updateInfo and deleteImage methods and related. A bunch of TODO tests. --- .../api/image/ImageControllerTests.java | 77 ++++++++++++++- .../api/image/S3ImageServiceTests.java | 67 ++++++++----- .../mealsmadeeasy/api/DevConfiguration.java | 7 +- .../api/image/ImageController.java | 84 +++++++++++++--- .../mealsmadeeasy/api/image/ImageService.java | 16 +--- .../api/image/S3ImageService.java | 96 ++++++++----------- .../api/image/body/ImageUpdateInfoBody.java | 64 +++++++++++++ .../api/image/spec/ImageCreateInfoSpec.java | 48 ++++++++++ .../api/image/spec/ImageUpdateInfoSpec.java | 30 ++++++ 9 files changed, 378 insertions(+), 111 deletions(-) create mode 100644 src/main/java/app/mealsmadeeasy/api/image/body/ImageUpdateInfoBody.java create mode 100644 src/main/java/app/mealsmadeeasy/api/image/spec/ImageCreateInfoSpec.java create mode 100644 src/main/java/app/mealsmadeeasy/api/image/spec/ImageUpdateInfoSpec.java diff --git a/src/integrationTest/java/app/mealsmadeeasy/api/image/ImageControllerTests.java b/src/integrationTest/java/app/mealsmadeeasy/api/image/ImageControllerTests.java index 9bb8dba..ebea18a 100644 --- a/src/integrationTest/java/app/mealsmadeeasy/api/image/ImageControllerTests.java +++ b/src/integrationTest/java/app/mealsmadeeasy/api/image/ImageControllerTests.java @@ -2,6 +2,8 @@ package app.mealsmadeeasy.api.image; import app.mealsmadeeasy.api.auth.AuthService; import app.mealsmadeeasy.api.auth.LoginException; +import app.mealsmadeeasy.api.image.spec.ImageCreateInfoSpec; +import app.mealsmadeeasy.api.image.spec.ImageUpdateInfoSpec; import app.mealsmadeeasy.api.user.User; import app.mealsmadeeasy.api.user.UserCreateException; import app.mealsmadeeasy.api.user.UserService; @@ -21,8 +23,10 @@ import org.testcontainers.utility.DockerImageName; import java.io.IOException; import java.io.InputStream; +import java.util.Set; import static org.hamcrest.CoreMatchers.nullValue; +import static org.junit.jupiter.api.Assertions.fail; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.multipart; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; @@ -76,7 +80,8 @@ public class ImageControllerTests { owner, USER_FILENAME, hal9000, - 27881L + 27881L, + new ImageCreateInfoSpec() ); } } @@ -89,12 +94,24 @@ public class ImageControllerTests { } } + private Image makePublic(Image image, User modifier) { + final ImageUpdateInfoSpec spec = new ImageUpdateInfoSpec(); + spec.setPublic(true); + return this.imageService.update(image, modifier, spec); + } + + private Image addViewer(Image image, User modifier, User viewerToAdd) { + final ImageUpdateInfoSpec spec = new ImageUpdateInfoSpec(); + spec.setViewersToAdd(Set.of(viewerToAdd)); + return this.imageService.update(image, modifier, spec); + } + @Test @DirtiesContext public void getImageNoPrincipal() throws Exception { final User owner = this.createTestUser("imageOwner"); final Image image = this.createHal9000(owner); - this.imageService.setPublic(image, owner, true); + this.makePublic(image, owner); try (final InputStream hal9000 = getHal9000()) { final byte[] halBytes = hal9000.readAllBytes(); this.mockMvc.perform(get("/images/imageOwner/HAL9000.svg")) @@ -130,7 +147,7 @@ public class ImageControllerTests { final User owner = this.createTestUser("imageOwner"); final User viewer = this.createTestUser("viewer"); final Image image = this.createHal9000(owner); - this.imageService.addViewer(image, owner, viewer); + this.addViewer(image, owner, viewer); final String accessToken = this.getAccessToken(viewer.getUsername()); this.doGetImageTestWithViewer(accessToken); } @@ -170,4 +187,58 @@ public class ImageControllerTests { } } + @Test + @DirtiesContext + public void updateAlt() throws Exception { + fail("TODO"); + } + + @Test + @DirtiesContext + public void updateCaption() throws Exception { + fail("TODO"); + } + + @Test + @DirtiesContext + public void updateIsPublic() throws Exception { + fail("TODO"); + } + + @Test + @DirtiesContext + public void addViewers() throws Exception { + fail("TODO"); + } + + @Test + @DirtiesContext + public void removeViewers() throws Exception { + fail("TODO"); + } + + @Test + @DirtiesContext + public void clearAllViewers() throws Exception { + fail("TODO"); + } + + @Test + @DirtiesContext + public void updateInfoWithViewerFails() throws Exception { + fail("TODO"); + } + + @Test + @DirtiesContext + public void deleteImageWithOwner() throws Exception { + fail("TODO"); + } + + @Test + @DirtiesContext + public void deleteImageWithViewer() throws Exception { + fail("TODO"); + } + } diff --git a/src/integrationTest/java/app/mealsmadeeasy/api/image/S3ImageServiceTests.java b/src/integrationTest/java/app/mealsmadeeasy/api/image/S3ImageServiceTests.java index 453fd19..c848488 100644 --- a/src/integrationTest/java/app/mealsmadeeasy/api/image/S3ImageServiceTests.java +++ b/src/integrationTest/java/app/mealsmadeeasy/api/image/S3ImageServiceTests.java @@ -1,5 +1,7 @@ package app.mealsmadeeasy.api.image; +import app.mealsmadeeasy.api.image.spec.ImageCreateInfoSpec; +import app.mealsmadeeasy.api.image.spec.ImageUpdateInfoSpec; import app.mealsmadeeasy.api.user.User; import app.mealsmadeeasy.api.user.UserCreateException; import app.mealsmadeeasy.api.user.UserService; @@ -17,6 +19,7 @@ import org.testcontainers.utility.DockerImageName; import java.io.IOException; import java.io.InputStream; import java.util.List; +import java.util.Set; import static app.mealsmadeeasy.api.image.ContainsImagesMatcher.containsImages; import static app.mealsmadeeasy.api.user.IsUserMatcher.isUser; @@ -25,6 +28,7 @@ import static org.hamcrest.CoreMatchers.nullValue; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.notNullValue; +import static org.junit.jupiter.api.Assertions.fail; @Testcontainers @SpringBootTest @@ -68,11 +72,18 @@ public class S3ImageServiceTests { owner, USER_FILENAME, hal9000, - 27881L + 27881L, + new ImageCreateInfoSpec() ); } } + private Image makePublic(Image image, User modifier) { + final ImageUpdateInfoSpec spec = new ImageUpdateInfoSpec(); + spec.setPublic(true); + return this.imageService.update(image, modifier, spec); + } + @Test public void smokeScreen() {} @@ -109,7 +120,7 @@ public class S3ImageServiceTests { public void loadPublicImage() throws ImageException, IOException { final User owner = this.createTestUser("imageOwner"); Image image = this.createHal9000(owner); - image = this.imageService.setPublic(image, owner, true); + image = this.makePublic(image, owner); try (final InputStream stored = this.imageService.getImageContent(image, null)) { final byte[] storedBytes = stored.readAllBytes(); @@ -123,7 +134,9 @@ public class S3ImageServiceTests { final User owner = this.createTestUser("imageOwner"); final User viewer = this.createTestUser("imageViewer"); Image image = this.createHal9000(owner); - image = this.imageService.addViewer(image, owner, viewer); + final ImageUpdateInfoSpec spec = new ImageUpdateInfoSpec(); + spec.setViewersToAdd(Set.of(viewer)); + image = this.imageService.update(image, owner, spec); try (final InputStream stored = this.imageService.getImageContent(image, viewer)) { final byte[] storedBytes = stored.readAllBytes(); @@ -151,40 +164,44 @@ public class S3ImageServiceTests { @Test @DirtiesContext - public void updateOwner() throws ImageException, IOException { - final User oldOwner = this.createTestUser("oldImageOwner"); - final User newOwner = this.createTestUser("newImageOwner"); - Image image = this.createHal9000(oldOwner); - assertThat(image.getOwner(), isUser(oldOwner)); - image = this.imageService.updateOwner(image, oldOwner, newOwner); - assertThat(image.getOwner(), isUser(newOwner)); + public void updateAlt() throws Exception { + fail("TODO"); } @Test @DirtiesContext - public void setAlt() throws ImageException, IOException { - final User owner = this.createTestUser("imageOwner"); - Image image = this.createHal9000(owner); - image = this.imageService.setAlt(image, owner, "Example alt."); - assertThat(image.getAlt(), is("Example alt.")); + public void updateCaption() throws Exception { + fail("TODO"); } @Test @DirtiesContext - public void setCaption() throws ImageException, IOException { - final User owner = this.createTestUser("imageOwner"); - Image image = this.createHal9000(owner); - image = this.imageService.setCaption(image, owner, "Example caption."); - assertThat(image.getCaption(), is("Example caption.")); + public void updateIsPublic() throws Exception { + fail("TODO"); } @Test @DirtiesContext - public void setPublicToTrue() throws ImageException, IOException { - final User owner = this.createTestUser("imageOwner"); - Image image = this.createHal9000(owner); - image = this.imageService.setPublic(image, owner, true); - assertThat(image.isPublic(), is(true)); + public void addViewers() throws Exception { + fail("TODO"); + } + + @Test + @DirtiesContext + public void removeViewers() throws Exception { + fail("TODO"); + } + + @Test + @DirtiesContext + public void clearAllViewers() throws Exception { + fail("TODO"); + } + + @Test + @DirtiesContext + public void deleteImage() throws Exception { + fail("TODO"); } } diff --git a/src/main/java/app/mealsmadeeasy/api/DevConfiguration.java b/src/main/java/app/mealsmadeeasy/api/DevConfiguration.java index a4d5058..d3e5328 100644 --- a/src/main/java/app/mealsmadeeasy/api/DevConfiguration.java +++ b/src/main/java/app/mealsmadeeasy/api/DevConfiguration.java @@ -3,6 +3,7 @@ package app.mealsmadeeasy.api; import app.mealsmadeeasy.api.image.Image; import app.mealsmadeeasy.api.image.ImageException; import app.mealsmadeeasy.api.image.ImageService; +import app.mealsmadeeasy.api.image.spec.ImageCreateInfoSpec; import app.mealsmadeeasy.api.recipe.Recipe; import app.mealsmadeeasy.api.recipe.RecipeService; import app.mealsmadeeasy.api.user.User; @@ -47,13 +48,15 @@ public class DevConfiguration { logger.info("Created {}", recipe); try (final InputStream inputStream = DevConfiguration.class.getResourceAsStream("HAL9000.svg")) { + final ImageCreateInfoSpec spec = new ImageCreateInfoSpec(); + spec.setPublic(true); final Image image = this.imageService.create( testUser, "HAL9000.svg", inputStream, - 27881L + 27881L, + spec ); - this.imageService.setPublic(image, testUser, true); logger.info("Created {}", image); } catch (IOException | ImageException e) { logger.error("Failed to load and/or create HAL9000.svg", e); diff --git a/src/main/java/app/mealsmadeeasy/api/image/ImageController.java b/src/main/java/app/mealsmadeeasy/api/image/ImageController.java index a352651..bd92577 100644 --- a/src/main/java/app/mealsmadeeasy/api/image/ImageController.java +++ b/src/main/java/app/mealsmadeeasy/api/image/ImageController.java @@ -1,5 +1,8 @@ package app.mealsmadeeasy.api.image; +import app.mealsmadeeasy.api.image.body.ImageUpdateInfoBody; +import app.mealsmadeeasy.api.image.spec.ImageCreateInfoSpec; +import app.mealsmadeeasy.api.image.spec.ImageUpdateInfoSpec; import app.mealsmadeeasy.api.image.view.ImageView; import app.mealsmadeeasy.api.user.User; import app.mealsmadeeasy.api.user.UserService; @@ -14,6 +17,8 @@ import org.springframework.web.multipart.MultipartFile; import java.io.IOException; import java.io.InputStream; +import java.util.Set; +import java.util.stream.Collectors; @RestController @RequestMapping("/images") @@ -22,6 +27,7 @@ public class ImageController { private static ImageView getView(Image image, User owner) { final ImageView imageView = new ImageView(); imageView.setCreated(image.getCreated()); + imageView.setModified(image.getModified()); imageView.setFilename(image.getUserFilename()); imageView.setMimeType(image.getMimeType()); imageView.setAlt(image.getAlt()); @@ -44,6 +50,29 @@ public class ImageController { this.userService = userService; } + private ImageUpdateInfoSpec getImageUpdateSpec(ImageUpdateInfoBody body) { + final ImageUpdateInfoSpec spec = new ImageUpdateInfoSpec(); + spec.setAlt(body.getAlt()); + spec.setCaption(body.getCaption()); + spec.setPublic(body.getPublic()); + if (body.getViewersToAdd() != null) { + spec.setViewersToAdd( + body.getViewersToAdd().stream() + .map(this.userService::getUser) + .collect(Collectors.toSet()) + ); + } + if (body.getViewersToRemove() != null) { + spec.setViewersToRemove( + body.getViewersToRemove().stream() + .map(this.userService::getUser) + .collect(Collectors.toSet()) + ); + } + spec.setClearAllViewers(body.getClearAllViewers()); + return spec; + } + @GetMapping("/{username}/{filename}") public ResponseEntity getImage( @AuthenticationPrincipal User principal, @@ -65,29 +94,58 @@ public class ImageController { @RequestParam(required = false) String alt, @RequestParam(required = false) String caption, @RequestParam(required = false) Boolean isPublic, + @RequestParam(required = false) Set viewers, @AuthenticationPrincipal User principal ) throws IOException, ImageException { if (principal == null) { throw new AccessDeniedException("Must be logged in."); } - - Image saved = this.imageService.create( + final ImageCreateInfoSpec createSpec = new ImageCreateInfoSpec(); + createSpec.setAlt(alt); + createSpec.setCaption(caption); + createSpec.setPublic(isPublic); + if (viewers != null) { + createSpec.setViewersToAdd(viewers.stream().map(this.userService::getUser).collect(Collectors.toSet())); + } + final Image saved = this.imageService.create( principal, filename, image.getInputStream(), - image.getSize() + image.getSize(), + createSpec ); - if (alt != null) { - saved = this.imageService.setAlt(saved, principal, alt); - } - if (caption != null) { - saved = this.imageService.setCaption(saved, principal, caption); - } - if (isPublic != null) { - saved = this.imageService.setPublic(saved, principal, isPublic); - } - return ResponseEntity.status(201).body(getView(saved, principal)); } + @PostMapping("/{username}/{filename}") + public ResponseEntity updateInfo( + @AuthenticationPrincipal User principal, + @PathVariable String username, + @PathVariable String filename, + @RequestBody ImageUpdateInfoBody body + ) throws ImageException { + if (principal == null) { + throw new AccessDeniedException("Must be logged in."); + } + final User owner = this.userService.getUser(username); + final Image image = this.imageService.getByOwnerAndFilename(owner, filename, principal); + final Image updated = this.imageService.update(image, principal, this.getImageUpdateSpec(body)); + return ResponseEntity.ok(getView(updated, owner)); + } + + @DeleteMapping("/{username}/{filename}") + public ResponseEntity deleteImage( + @AuthenticationPrincipal User principal, + @PathVariable String username, + @PathVariable String filename + ) throws ImageException, IOException { + if (principal == null) { + throw new AccessDeniedException("Must be logged in."); + } + final User owner = this.userService.getUser(username); + final Image image = this.imageService.getByOwnerAndFilename(owner, filename, principal); + this.imageService.deleteImage(image, principal); + return ResponseEntity.noContent().build(); + } + } diff --git a/src/main/java/app/mealsmadeeasy/api/image/ImageService.java b/src/main/java/app/mealsmadeeasy/api/image/ImageService.java index c154abe..52aa7a9 100644 --- a/src/main/java/app/mealsmadeeasy/api/image/ImageService.java +++ b/src/main/java/app/mealsmadeeasy/api/image/ImageService.java @@ -1,5 +1,7 @@ package app.mealsmadeeasy.api.image; +import app.mealsmadeeasy.api.image.spec.ImageCreateInfoSpec; +import app.mealsmadeeasy.api.image.spec.ImageUpdateInfoSpec; import app.mealsmadeeasy.api.user.User; import org.jetbrains.annotations.Nullable; @@ -9,23 +11,15 @@ import java.util.List; public interface ImageService { - Image create(User owner, String userFilename, InputStream inputStream, long objectSize) + Image create(User owner, String userFilename, InputStream inputStream, long objectSize, ImageCreateInfoSpec infoSpec) throws IOException, ImageException; Image getByOwnerAndFilename(User owner, String filename, User viewer) throws ImageException; InputStream getImageContent(Image image, @Nullable User viewer) throws IOException; List getImagesOwnedBy(User user); - Image updateOwner(Image image, User oldOwner, User newOwner); + Image update(Image image, User modifier, ImageUpdateInfoSpec spec); - Image setAlt(Image image, User owner, String alt); - Image setCaption(Image image, User owner, String caption); - Image setPublic(Image image, User owner, boolean isPublic); - - Image addViewer(Image image, User owner, User viewer); - Image removeViewer(Image image, User owner, User viewer); - Image clearViewers(Image image, User owner); - - void deleteImage(Image image, User owner) throws IOException; + void deleteImage(Image image, User modifier) throws IOException; } diff --git a/src/main/java/app/mealsmadeeasy/api/image/S3ImageService.java b/src/main/java/app/mealsmadeeasy/api/image/S3ImageService.java index 432091a..b236b2e 100644 --- a/src/main/java/app/mealsmadeeasy/api/image/S3ImageService.java +++ b/src/main/java/app/mealsmadeeasy/api/image/S3ImageService.java @@ -1,5 +1,7 @@ package app.mealsmadeeasy.api.image; +import app.mealsmadeeasy.api.image.spec.ImageCreateInfoSpec; +import app.mealsmadeeasy.api.image.spec.ImageUpdateInfoSpec; import app.mealsmadeeasy.api.s3.S3Manager; import app.mealsmadeeasy.api.user.User; import app.mealsmadeeasy.api.user.UserEntity; @@ -17,6 +19,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; @Service +/* TODO: update modified LocalDateTime when updating */ public class S3ImageService implements ImageService { private static final Pattern extensionPattern = Pattern.compile(".+\\.(.+)$"); @@ -62,9 +65,29 @@ public class S3ImageService implements ImageService { }; } + private void transferFromSpec(S3ImageEntity entity, ImageCreateInfoSpec spec) { + if (spec.getAlt() != null) { + entity.setAlt(spec.getAlt()); + } + if (spec.getCaption() != null) { + entity.setCaption(spec.getCaption()); + } + if (spec.getPublic() != null) { + entity.setPublic(spec.getPublic()); + } + for (final User viewerToAdd : spec.getViewersToAdd()) { + entity.getViewers().add((UserEntity) viewerToAdd); + } + } + @Override - public Image create(User owner, String userFilename, InputStream inputStream, long objectSize) - throws IOException, ImageException { + public Image create( + User owner, + String userFilename, + InputStream inputStream, + long objectSize, + ImageCreateInfoSpec createSpec + ) throws IOException, ImageException { final String mimeType = this.getMimeType(userFilename); final String uuid = UUID.randomUUID().toString(); final String extension = this.getExtension(mimeType); @@ -78,6 +101,7 @@ public class S3ImageService implements ImageService { draft.setUserFilename(userFilename); draft.setMimeType(mimeType); draft.setObjectName(objectName); + this.transferFromSpec(draft, createSpec); return this.imageRepository.save(draft); } @@ -103,64 +127,22 @@ public class S3ImageService implements ImageService { } @Override - @PreAuthorize("@imageSecurity.isOwner(#image, #oldOwner)") - public Image updateOwner(Image image, User oldOwner, User newOwner) { - final S3ImageEntity imageEntity = (S3ImageEntity) image; - imageEntity.setOwner((UserEntity) newOwner); - return this.imageRepository.save(imageEntity); + @PreAuthorize("@imageSecurity.isOwner(#image, #modifier)") + public Image update(final Image image, User modifier, ImageUpdateInfoSpec updateSpec) { + S3ImageEntity entity = (S3ImageEntity) image; + this.transferFromSpec(entity, updateSpec); + for (final User toRemove : updateSpec.getViewersToRemove()) { + entity.getViewers().remove((UserEntity) toRemove); + } + if (updateSpec.getClearAllViewers() != null) { + entity.getViewers().clear(); + } + return this.imageRepository.save(entity); } @Override - @PreAuthorize("@imageSecurity.isOwner(#image, #owner)") - public Image setAlt(Image image, User owner, String alt) { - final S3ImageEntity imageEntity = (S3ImageEntity) image; - imageEntity.setAlt(alt); - return this.imageRepository.save(imageEntity); - } - - @Override - @PreAuthorize("@imageSecurity.isOwner(#image, #owner)") - public Image setCaption(Image image, User owner, String caption) { - final S3ImageEntity imageEntity = (S3ImageEntity) image; - imageEntity.setCaption(caption); - return this.imageRepository.save(imageEntity); - } - - @Override - @PreAuthorize("@imageSecurity.isOwner(#image, #owner)") - public Image setPublic(Image image, User owner, boolean isPublic) { - final S3ImageEntity imageEntity = (S3ImageEntity) image; - imageEntity.setPublic(isPublic); - return this.imageRepository.save(imageEntity); - } - - @Override - @PreAuthorize("@imageSecurity.isOwner(#image, #owner)") - public Image addViewer(Image image, User owner, User viewer) { - final S3ImageEntity withViewers = this.imageRepository.getByIdWithViewers(image.getId()); - withViewers.getViewers().add((UserEntity) viewer); - return this.imageRepository.save(withViewers); - } - - @Override - @PreAuthorize("@imageSecurity.isOwner(#image, #owner)") - public Image removeViewer(Image image, User owner, User viewer) { - final S3ImageEntity withViewers = this.imageRepository.getByIdWithViewers(image.getId()); - withViewers.getViewers().remove((UserEntity) viewer); - return this.imageRepository.save(withViewers); - } - - @Override - @PreAuthorize("@imageSecurity.isOwner(#image, #owner)") - public Image clearViewers(Image image, User owner) { - final S3ImageEntity withViewers = this.imageRepository.getByIdWithViewers(image.getId()); - withViewers.getViewers().clear(); - return this.imageRepository.save(withViewers); - } - - @Override - @PreAuthorize("@imageSecurity.isOwner(#image, #owner)") - public void deleteImage(Image image, User owner) throws IOException { + @PreAuthorize("@imageSecurity.isOwner(#image, #modifier)") + public void deleteImage(Image image, User modifier) throws IOException { final S3ImageEntity imageEntity = (S3ImageEntity) image; this.imageRepository.delete(imageEntity); this.s3Manager.delete("images", imageEntity.getObjectName()); diff --git a/src/main/java/app/mealsmadeeasy/api/image/body/ImageUpdateInfoBody.java b/src/main/java/app/mealsmadeeasy/api/image/body/ImageUpdateInfoBody.java new file mode 100644 index 0000000..1eea9e4 --- /dev/null +++ b/src/main/java/app/mealsmadeeasy/api/image/body/ImageUpdateInfoBody.java @@ -0,0 +1,64 @@ +package app.mealsmadeeasy.api.image.body; + +import org.jetbrains.annotations.Nullable; + +import java.util.Set; + +public class ImageUpdateInfoBody { + + private @Nullable String alt; + private @Nullable String caption; + private @Nullable Boolean isPublic; + private @Nullable Set viewersToAdd; + private @Nullable Set viewersToRemove; + private @Nullable Boolean clearAllViewers; + + public @Nullable String getAlt() { + return this.alt; + } + + public void setAlt(@Nullable String alt) { + this.alt = alt; + } + + public @Nullable String getCaption() { + return this.caption; + } + + public void setCaption(@Nullable String caption) { + this.caption = caption; + } + + public @Nullable Boolean getPublic() { + return this.isPublic; + } + + public void setPublic(@Nullable Boolean aPublic) { + isPublic = aPublic; + } + + public @Nullable Set getViewersToAdd() { + return this.viewersToAdd; + } + + public void setViewersToAdd(@Nullable Set viewersToAdd) { + this.viewersToAdd = viewersToAdd; + } + + public @Nullable Set getViewersToRemove() { + return this.viewersToRemove; + } + + public void setViewersToRemove(@Nullable Set viewersToRemove) { + this.viewersToRemove = viewersToRemove; + } + + public @Nullable Boolean getClearAllViewers() { + return this.clearAllViewers; + } + + public void setClearAllViewers(@Nullable Boolean clearAllViewers) { + this.clearAllViewers = clearAllViewers; + } + +} diff --git a/src/main/java/app/mealsmadeeasy/api/image/spec/ImageCreateInfoSpec.java b/src/main/java/app/mealsmadeeasy/api/image/spec/ImageCreateInfoSpec.java new file mode 100644 index 0000000..69c363c --- /dev/null +++ b/src/main/java/app/mealsmadeeasy/api/image/spec/ImageCreateInfoSpec.java @@ -0,0 +1,48 @@ +package app.mealsmadeeasy.api.image.spec; + +import app.mealsmadeeasy.api.user.User; +import org.jetbrains.annotations.Nullable; + +import java.util.HashSet; +import java.util.Set; + +public class ImageCreateInfoSpec { + + private @Nullable String alt; + private @Nullable String caption; + private @Nullable Boolean isPublic; + private Set viewersToAdd = new HashSet<>(); + + public @Nullable String getAlt() { + return this.alt; + } + + public void setAlt(@Nullable String alt) { + this.alt = alt; + } + + public @Nullable String getCaption() { + return this.caption; + } + + public void setCaption(@Nullable String caption) { + this.caption = caption; + } + + public @Nullable Boolean getPublic() { + return this.isPublic; + } + + public void setPublic(@Nullable Boolean aPublic) { + isPublic = aPublic; + } + + public Set getViewersToAdd() { + return this.viewersToAdd; + } + + public void setViewersToAdd(Set viewersToAdd) { + this.viewersToAdd = viewersToAdd; + } + +} diff --git a/src/main/java/app/mealsmadeeasy/api/image/spec/ImageUpdateInfoSpec.java b/src/main/java/app/mealsmadeeasy/api/image/spec/ImageUpdateInfoSpec.java new file mode 100644 index 0000000..ea0465c --- /dev/null +++ b/src/main/java/app/mealsmadeeasy/api/image/spec/ImageUpdateInfoSpec.java @@ -0,0 +1,30 @@ +package app.mealsmadeeasy.api.image.spec; + +import app.mealsmadeeasy.api.user.User; +import org.jetbrains.annotations.Nullable; + +import java.util.HashSet; +import java.util.Set; + +public class ImageUpdateInfoSpec extends ImageCreateInfoSpec { + + private Set viewersToRemove = new HashSet<>(); + private @Nullable Boolean clearAllViewers; + + public Set getViewersToRemove() { + return this.viewersToRemove; + } + + public void setViewersToRemove(Set viewersToRemove) { + this.viewersToRemove = viewersToRemove; + } + + public @Nullable Boolean getClearAllViewers() { + return this.clearAllViewers; + } + + public void setClearAllViewers(@Nullable Boolean clearAllViewers) { + this.clearAllViewers = clearAllViewers; + } + +}