From 26110beac2255ac216158c43bd47ea0d46c96e23 Mon Sep 17 00:00:00 2001 From: FyloZ Date: Wed, 19 Feb 2020 06:46:31 -0500 Subject: [PATCH] Continue transition vers exceptions + DTO --- .gitignore | 2 +- .../core/io/file/FileHandler.java | 1 + .../core/io/file/ImageHandler.java | 1 + .../io/response/ModelResponseBuilder.java | 19 ++- .../core/io/response/ResponseDataType.java | 3 + .../core/model/dto/RecipeEditorFormDto.java | 14 ++ .../core/services/files/FilesService.java | 13 +- .../core/services/files/ImagesService.java | 33 +++++ .../core/services/model/CompanyService.java | 5 - .../core/services/model/MixService.java | 30 +++-- .../core/services/model/RecipeService.java | 20 +++ .../core/services/model/StepService.java | 29 ++++- .../creators/MixCreatorController.java | 2 +- .../editors/MixEditorController.java | 121 ++++++------------ .../editors/RecipeEditorController.java | 98 ++++---------- .../files/ImageFilesController.java | 26 ++-- src/main/resources/templates/mix/editor.html | 2 +- 17 files changed, 220 insertions(+), 199 deletions(-) create mode 100644 src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/dto/RecipeEditorFormDto.java create mode 100644 src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/files/ImagesService.java diff --git a/.gitignore b/.gitignore index eeec143..c314b99 100644 --- a/.gitignore +++ b/.gitignore @@ -28,5 +28,5 @@ HELP.md ### VS Code ### .vscode/ -/logs/ +*.log /workdir/ diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/io/file/FileHandler.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/io/file/FileHandler.java index 9ebb7c3..3dd158a 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/io/file/FileHandler.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/io/file/FileHandler.java @@ -9,6 +9,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +@Deprecated(since = "1.3.0") public class FileHandler { protected String name; diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/io/file/ImageHandler.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/io/file/ImageHandler.java index 067185f..6186745 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/io/file/ImageHandler.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/io/file/ImageHandler.java @@ -7,6 +7,7 @@ import dev.fyloz.trial.colorrecipesexplorer.core.services.model.RecipeService; import java.util.List; import java.util.stream.Collectors; +@Deprecated(since = "1.3.0") public class ImageHandler extends FileHandler { public static final String IMAGES_LOCATION = ColorRecipesExplorerApplication.UPLOAD_LOCATION + "/images"; diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/io/response/ModelResponseBuilder.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/io/response/ModelResponseBuilder.java index 1d676b1..12ab1bc 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/io/response/ModelResponseBuilder.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/io/response/ModelResponseBuilder.java @@ -5,6 +5,7 @@ import org.springframework.web.servlet.ModelAndView; public class ModelResponseBuilder extends ResponseBuilder { private static final String PATH_PARAMETER_PATTERN = "(\\{\\w+\\})"; + private static final String REDIRECT_PATH_PREFIX = "redirect:/"; private ModelAndView model; @@ -26,13 +27,17 @@ public class ModelResponseBuilder extends ResponseBuilder step; + +} diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/files/FilesService.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/files/FilesService.java index a1a9f82..b22f630 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/files/FilesService.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/files/FilesService.java @@ -47,13 +47,24 @@ public class FilesService { * * @param input L'InputStream * @return Le InputStream transformé en String - * @throws IOException Si la transformation vers un String échoue + * @throws IOException La transformation vers un String a échoué */ public String readInputStreamAsString(InputStream input) throws IOException { byte[] data = FileCopyUtils.copyToByteArray(input); return new String(data, StandardCharsets.UTF_8); } + /** + * Récupère le contenu d'un fichier dans un tableau de Byte. + * + * @param path Le chemin vers le fichier + * @return Le contenu du fichier dans un tableau de Byte + * @throws IOException La lecture du fichier a échoué + */ + public byte[] readFileAsBytes(String path) throws IOException { + return Files.readAllBytes(Paths.get(path)); + } + /** * Écrit un fichier Multipart sur le disque. * diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/files/ImagesService.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/files/ImagesService.java new file mode 100644 index 0000000..d2db0d7 --- /dev/null +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/files/ImagesService.java @@ -0,0 +1,33 @@ +package dev.fyloz.trial.colorrecipesexplorer.core.services.files; + +import dev.fyloz.trial.colorrecipesexplorer.ColorRecipesExplorerApplication; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.io.IOException; + +@Service +public class ImagesService { + + private static final String IMAGES_DIRECTORY = "images"; + + private FilesService filesService; + + @Autowired + public ImagesService(FilesService filesService) { + this.filesService = filesService; + } + + public byte[] readImage(String name) { + try { + return filesService.readFileAsBytes(getPath(name)); + } catch (IOException ex) { + throw new RuntimeException("Erreur lors de la lecture d'une image: " + ex.getMessage()); + } + } + + private String getPath(String name) { + return String.format("%s/%s/%s", ColorRecipesExplorerApplication.UPLOAD_LOCATION, IMAGES_DIRECTORY, name); + } + +} diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/CompanyService.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/CompanyService.java index fe8ed13..ec3536b 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/CompanyService.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/CompanyService.java @@ -26,11 +26,6 @@ public class CompanyService extends GenericService { super.delete(entity); } - @Override - public boolean isValidForCreation(Company entity) { - return super.isValidForCreation(entity) && !existsByName(entity.getName()); - } - /** * Vérifie si une bannière correspondant à un nom existe. * diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/MixService.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/MixService.java index ce872e5..1b136e7 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/MixService.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/MixService.java @@ -42,19 +42,17 @@ public class MixService extends GenericService { * @return Les produits disponibles pour ce mélange */ public Collection getAvailableMaterialsForMixId(Long recipeId, Long mixId) { - Recipe recipe = recipeService.getById(recipeId); - return existsById(mixId) ? getAvailableMaterialsForMix(recipe, getById(mixId)) : getAvailableMaterialsForNewMix(recipe); + return existsById(mixId) ? getAvailableMaterialsForMix(getById(mixId)) : getAvailableMaterialsForNewMix(recipeService.getById(recipeId)); } /** * Récupère les produits disponibles pour un mélange existant. * - * @param recipe La recette dans laquelle se trouve le mélange - * @param mix Le mélange + * @param mix Le mélange * @return Les produits disponibles pour ce mélange */ - public Collection getAvailableMaterialsForMix(Recipe recipe, Mix mix) { - return getAvailableMaterialsForNewMix(recipe) + public Collection getAvailableMaterialsForMix(Mix mix) { + return getAvailableMaterialsForNewMix(mix.getRecipe()) .stream() .filter(m -> !m.equals(mix.getMixType().getMaterial())) .collect(Collectors.toList()); @@ -153,12 +151,22 @@ public class MixService extends GenericService { } } - public boolean deleteMix(Mix mix) { - if (mixQuantityService.deleteAll(mix.getMixQuantities())) { - return super.delete(mix); - } + @Deprecated(since = "1.3.0", forRemoval = true) + public void deleteMix(Mix mix) { + mixQuantityService.deleteAll(mix.getMixQuantities()); + delete(mix); + } - return false; + @Override + public void delete(Mix mix) { + mixQuantityService.deleteAll(mix.getMixQuantities()); +/ + super.delete(mix); + } + + @Override + public void deleteById(Long id) { + delete(getById(id)); } /** diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/RecipeService.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/RecipeService.java index 4dac948..8918d71 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/RecipeService.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/RecipeService.java @@ -3,6 +3,7 @@ package dev.fyloz.trial.colorrecipesexplorer.core.services.model; import dev.fyloz.trial.colorrecipesexplorer.core.io.file.FileHandler; import dev.fyloz.trial.colorrecipesexplorer.core.io.file.ImageHandler; import dev.fyloz.trial.colorrecipesexplorer.core.model.*; +import dev.fyloz.trial.colorrecipesexplorer.core.model.dto.RecipeEditorFormDto; import dev.fyloz.trial.colorrecipesexplorer.core.model.dto.RecipeExplorerFormDto; import dev.fyloz.trial.colorrecipesexplorer.core.services.GenericService; import dev.fyloz.trial.colorrecipesexplorer.dao.RecipeDao; @@ -61,6 +62,7 @@ public class RecipeService extends GenericService { return mappedByCompany(getAll()); } + @Deprecated(since = "1.3.0", forRemoval = true) public Recipe updateRecipe(Recipe newRecipe, Recipe storedRecipe, MultiValueMap form) { storedRecipe.setName(newRecipe.getName()); storedRecipe.setCompany(newRecipe.getCompany()); @@ -73,6 +75,20 @@ public class RecipeService extends GenericService { return convertAndCreateSteps(storedRecipe, form); } + /** + * Met à jour une recette ainsi que ses étapes. + * + * @param recipeDto Les informations de la recette à mettre à jour + * @return La recette mise à jour + */ + @Transactional + public Recipe updateRecipeAndSteps(RecipeEditorFormDto recipeDto) { + Recipe recipe = recipeDto.getRecipe(); + + stepService.createAllForRecipe(recipe, recipeDto.getStep()); + return update(recipeDto.getRecipe()); + } + /** * Met à jour les informations d'une recette trouvées dans l'explorateur de recette. * @@ -230,4 +246,8 @@ public class RecipeService extends GenericService { return true; } + + public String getImageFileName(Recipe recipe) { + return String.format("%s_%s", recipe.getId(), recipe.getName()); + } } diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/StepService.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/StepService.java index 8063109..c1b917e 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/StepService.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/StepService.java @@ -1,16 +1,43 @@ package dev.fyloz.trial.colorrecipesexplorer.core.services.model; +import dev.fyloz.trial.colorrecipesexplorer.core.model.Recipe; import dev.fyloz.trial.colorrecipesexplorer.core.model.RecipeStep; import dev.fyloz.trial.colorrecipesexplorer.core.services.GenericService; import dev.fyloz.trial.colorrecipesexplorer.dao.StepDao; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.validation.constraints.NotNull; +import java.util.List; @Service public class StepService extends GenericService { @Autowired public StepService(StepDao stepDao) { - super(stepDao); + super(stepDao, RecipeStep.class); } + + /** + * Crée une étape pour une recette. + * + * @param recipe La recette + * @param message Le message de l'étape à créer + */ + public void createForRecipe(Recipe recipe, String message) { + save(new RecipeStep(recipe, message)); + } + + /** + * Crée toutes les étapes pour une recette. + * + * @param recipe La recette + * @param messages Tous les messages des étapes à créer + */ + @Transactional + public void createAllForRecipe(Recipe recipe, List messages) { + messages.forEach(m -> createForRecipe(recipe, m)); + } + } diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/creators/MixCreatorController.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/creators/MixCreatorController.java index e3ad702..7188f3c 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/creators/MixCreatorController.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/creators/MixCreatorController.java @@ -47,7 +47,7 @@ public class MixCreatorController { modelResponseBuilder .addResponseData(ResponseDataType.RECIPE, recipe) .addResponseData(ResponseDataType.MATERIAL_TYPES, materialTypeService.getAll()) - .addAttribute("materialsJson", materialService.asJson(mixService.getAvailableMaterialsForNewMix(recipe))); + .addResponseData(ResponseDataType.MATERIALS_JSON, materialService.asJson(mixService.getAvailableMaterialsForNewMix(recipe))); if (materialService.getAll().isEmpty()) modelResponseBuilder.addResponseData(ResponseDataType.BLOCK_BUTTON, true); diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/editors/MixEditorController.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/editors/MixEditorController.java index 13ceb47..ec40b91 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/editors/MixEditorController.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/editors/MixEditorController.java @@ -1,12 +1,14 @@ package dev.fyloz.trial.colorrecipesexplorer.web.controller.editors; +import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.EntityNotFoundException; import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ModelResponseBuilder; import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ResponseCode; import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ResponseDataType; import dev.fyloz.trial.colorrecipesexplorer.core.model.Mix; import dev.fyloz.trial.colorrecipesexplorer.core.model.dto.MixCreationFormDto; -import dev.fyloz.trial.colorrecipesexplorer.core.services.model.*; -import dev.fyloz.trial.colorrecipesexplorer.core.utils.ControllerUtils; +import dev.fyloz.trial.colorrecipesexplorer.core.services.model.MaterialService; +import dev.fyloz.trial.colorrecipesexplorer.core.services.model.MaterialTypeService; +import dev.fyloz.trial.colorrecipesexplorer.core.services.model.MixService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.stereotype.Controller; @@ -14,9 +16,7 @@ import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.ModelAndView; import javax.validation.Valid; -import java.util.Optional; -import static dev.fyloz.trial.colorrecipesexplorer.web.StringBank.*; import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.*; @Controller @@ -24,89 +24,46 @@ public class MixEditorController { private MixService mixService; private MaterialService materialService; - private RecipeService recipeService; - private MixTypeService mixTypeService; private MaterialTypeService materialTypeService; @Autowired - public MixEditorController(MixService mixService, MaterialService materialService, RecipeService recipeService, MixTypeService mixTypeService, MaterialTypeService materialTypeService) { + public MixEditorController(MixService mixService, MaterialService materialService, MaterialTypeService materialTypeService) { this.mixService = mixService; this.materialService = materialService; - this.recipeService = recipeService; - this.mixTypeService = mixTypeService; this.materialTypeService = materialTypeService; } - /** - * Affiche la page d'édition d'un mélange. - * Cette méthode requiert l'identifiant du mélange à modifier dans l'URL. - * - * @param model Le Model injecté par Thymeleaf - * @param id L'identifiant du mélange à modifier - * @return La page à afficher. - */ @GetMapping(EDITOR_MIX_SPECIFIC) public ModelAndView getPage(ModelAndView model, @PathVariable Long id) { - ModelResponseBuilder modelResponseBuilder = new ModelResponseBuilder(model) - .withView(EDITOR_MIX_SPECIFIC.replaceAll("/\\{id}", "")); + ModelResponseBuilder modelResponseBuilder = new ModelResponseBuilder(model).withView(EDITOR_MIX); + + try { + Mix mix = mixService.getById(id); - Optional optionalMix = mixService.getById(id); - if (optionalMix.isEmpty()) { return modelResponseBuilder - .withView(ControllerUtils.redirect(EDITOR_RECIPE)) + .addResponseData(ResponseDataType.MIX, mix) + .addResponseData(ResponseDataType.MATERIAL_TYPES, materialTypeService.getAll()) + .addResponseData(ResponseDataType.MIX_JSON, mixService.asJson(mix)) + .addResponseData(ResponseDataType.MATERIALS_JSON, materialService.asJson(mixService.getAvailableMaterialsForMix(mix))) + .build(); + + } catch (EntityNotFoundException ex) { + return modelResponseBuilder + .withRedirect(EDITOR_RECIPE) .build(); } - - Mix mix = optionalMix.get(); - - return modelResponseBuilder - .addResponseData(ResponseDataType.MIX, mix) - .addResponseData(ResponseDataType.RECIPE, mix.getRecipe()) - .addAttribute(MATERIAL_TYPE, mix.getMixType().getMaterial().getMaterialType()) - .addAttribute(MATERIAL_TYPES, materialTypeService.getAll()) - .addAttribute("mixJson", materialService.asJson(mix)) - .addAttribute("materialsJson", mixService.asJson(mixService.getAvailableMaterialsForMix(mix.getRecipe(), mix))) - .build(); } - /** - * Permet à l'utilisateur de modifier un mélange. - *

- * La mise à jour échouera si: - * - L'utilisateur n'est pas autorisé à exécuter cette action - * - Le mélange n'existe pas - * - Un des produits n'existe pas - * - Une erreur est survenue lors de la mise à jour dans la base de données - *

- * Modèle de la page: - * - error: Contient le message d'erreur, s'il y a lieu - *

- * REQUIERT UNE AUTORISATION - * - * @param form Le formulaire du mélange entré par l'utilisateur - * @return La page à afficher. - */ @PostMapping(value = EDITOR_MIX, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE) - public ModelAndView saveMix(@ModelAttribute @Valid MixCreationFormDto formDto, @RequestParam("mixId") Long id) { - ModelResponseBuilder modelResponseBuilder = new ModelResponseBuilder(); + public ModelAndView updateMix(@ModelAttribute @Valid MixCreationFormDto formDto, @RequestParam("mixId") Long id) { + ModelResponseBuilder modelResponseBuilder = new ModelResponseBuilder().withRedirect(EDITOR_RECIPE_SPECIFIC, formDto.getRecipe().getId()); - Optional optionalMix = mixService.getById(id); - if (optionalMix.isEmpty()) { - modelResponseBuilder.addResponseCode(ResponseCode.MIX_NOT_FOUND, id); + try { + Mix mix = mixService.getById(id); - return getPage(modelResponseBuilder.build(), id); - } - - Mix mix = optionalMix.get(); - modelResponseBuilder.withRedirect(EDITOR_RECIPE_SPECIFIC, mix.getRecipe().getId()); - - ModelResponseBuilder editResult = mixService.edit(mix, formDto); - if (editResult != null) { - return getPage( - modelResponseBuilder - .addResponseCode(ResponseCode.ERROR_SAVING) - .build(), - id); + mixService.edit(mix, formDto); + } catch (EntityNotFoundException ex) { + return getPage(modelResponseBuilder.addResponseCode(ResponseCode.MIX_NOT_FOUND, id).build(), id); } return modelResponseBuilder.build(); @@ -114,25 +71,19 @@ public class MixEditorController { @GetMapping(REMOVER_MIX_SPECIFIC) public ModelAndView deleteMix(@PathVariable Long id) { - ModelResponseBuilder modelResponseBuilder = new ModelResponseBuilder(""); + ModelResponseBuilder modelResponseBuilder = new ModelResponseBuilder(); - Optional optionalMix = mixService.getById(id); - if (optionalMix.isEmpty()) { - return getPage(modelResponseBuilder - .addResponseCode(ResponseCode.MIX_NOT_FOUND, id) - .build(), - id); + try { + Mix mix = mixService.getById(id); + mixService.delete(mix); + + return modelResponseBuilder + .withRedirect(EDITOR_RECIPE_SPECIFIC, mix.getRecipe().getId()) + .build(); + } catch (EntityNotFoundException ex) { + modelResponseBuilder.addResponseCode(ResponseCode.MIX_NOT_FOUND, id); } - Mix mix = optionalMix.get(); - modelResponseBuilder.withView(ControllerUtils.redirect(EDITOR_RECIPE_SPECIFIC.replace("{recipeID}", String.valueOf(mix.getRecipe().getId())))); - - if (!mixService.deleteMix(mix)) { - modelResponseBuilder.addResponseCode(ResponseCode.ERROR_SAVING); - - return getPage(modelResponseBuilder.build(), id); - } - - return modelResponseBuilder.build(); + return getPage(modelResponseBuilder.build(), id); } } diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/editors/RecipeEditorController.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/editors/RecipeEditorController.java index e9998ad..1575a87 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/editors/RecipeEditorController.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/editors/RecipeEditorController.java @@ -1,25 +1,22 @@ package dev.fyloz.trial.colorrecipesexplorer.web.controller.editors; +import dev.fyloz.trial.colorrecipesexplorer.core.exception.model.EntityNotFoundException; import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ModelResponseBuilder; import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ResponseCode; import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ResponseDataType; import dev.fyloz.trial.colorrecipesexplorer.core.model.Recipe; +import dev.fyloz.trial.colorrecipesexplorer.core.model.dto.RecipeEditorFormDto; import dev.fyloz.trial.colorrecipesexplorer.core.services.model.CompanyService; import dev.fyloz.trial.colorrecipesexplorer.core.services.model.RecipeService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.stereotype.Controller; import org.springframework.transaction.annotation.Transactional; -import org.springframework.util.MultiValueMap; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.servlet.ModelAndView; -import java.util.ArrayList; -import java.util.Optional; - import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.*; @Controller @@ -34,17 +31,8 @@ public class RecipeEditorController { this.companyService = companyService; } - /** - * Affiche la page listant toutes les recettes. - *

- * Modèle de la page: - * - recipes: Contient un Map de toutes les recettes triées par compagnie - * - * @param model Le Model injecté par Thymeleaf - * @return La page à afficher. - */ @GetMapping(EDITOR_RECIPE) - public ModelAndView listRecipes(ModelAndView model) { + public ModelAndView getPage(ModelAndView model) { return new ModelResponseBuilder(model) .withView(EDITOR_RECIPE) .addResponseData(ResponseDataType.RECIPE_MAP, recipeService.getRecipesByCompany()) @@ -52,74 +40,38 @@ public class RecipeEditorController { } @GetMapping(EDITOR_RECIPE_SPECIFIC) - public ModelAndView showEditPage(ModelAndView model, @PathVariable Long id, Recipe recipe) { - ModelResponseBuilder modelResponseBuilder = new ModelResponseBuilder(model) - .withView(EDITOR_RECIPE_EDITOR); + public ModelAndView getEditPage(ModelAndView model, @PathVariable Long id, Recipe recipe) { + ModelResponseBuilder modelResponseBuilder = new ModelResponseBuilder(model).withView(EDITOR_RECIPE_EDITOR); - if (recipe.getName() == null || recipe.getCompany() == null) { - Optional optionalRecipe = recipeService.getById(id); + try { + if (recipe == null) recipe = recipeService.getById(id); - if (optionalRecipe.isEmpty()) { - return listRecipes( - modelResponseBuilder - .addResponseCode(ResponseCode.RECIPE_NOT_FOUND, id) - .build() - ); - } - - recipe = optionalRecipe.get(); + modelResponseBuilder + .addResponseData(ResponseDataType.RECIPE, recipe) + .addResponseData(ResponseDataType.COMPANIES, companyService.getAll()) + .addResponseData(ResponseDataType.MIXES, recipeService.getSortedMixes(recipe)) + .addResponseData(ResponseDataType.IMAGES, recipeService.getImageFiles(recipe)) + .addResponseData(ResponseDataType.RECIPE_JSON, recipeService.asJson(recipe)); + } catch (EntityNotFoundException ex) { + return getPage(modelResponseBuilder.addResponseCode(ResponseCode.RECIPE_NOT_FOUND, id).build()); } - return modelResponseBuilder - .addResponseData(ResponseDataType.RECIPE, recipe) - .addResponseData(ResponseDataType.COMPANIES, companyService.getAll()) - .addResponseData(ResponseDataType.MIXES, recipeService.getSortedMixes(recipe)) - .addResponseData(ResponseDataType.IMAGES, recipeService.getImageFiles(recipe)) - .addAttribute("recipeJSON", recipeService.asJson(recipe)) - .build(); + return modelResponseBuilder.build(); } - /** - * Permet à l'utilisateur de modifier une recette. - *

- * La mise à jour échouera si: - * - L'utilisateur n'est pas autorisé à exécuter cette action - * - La recette n'existe pas - * - Une erreur est survenue lors de la mise à jour dans la base de données - *

- * Modèle de la page: - * - error: Contient le message d'erreur, s'il y a lieu - * - recipeCode: Contient la couleur d'une recette - *

- * REQUIERT UNE AUTORISATION - * - * @param recipe La recette à modifier - * @param form Le formulaire entré par l'utilisateur - * @return La page à afficher. - */ @PostMapping(value = EDITOR_RECIPE, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE) @Transactional - public ModelAndView saveRecipe(Recipe recipe, @RequestBody MultiValueMap form) { - ModelResponseBuilder modelResponseBuilder = new ModelResponseBuilder(""); - Long recipeId = recipe.getId(); + public ModelAndView updateRecipe(RecipeEditorFormDto recipeDto) { + ModelResponseBuilder modelResponseBuilder = new ModelResponseBuilder(); - Optional optionalStoredRecipe = recipeService.getById(recipeId); - if (optionalStoredRecipe.isEmpty()) { - return listRecipes( - modelResponseBuilder - .addResponseCode(ResponseCode.RECIPE_NOT_FOUND, recipeId) - .build()); + try { + recipeService.updateRecipeAndSteps(recipeDto); + + modelResponseBuilder.addResponseCode(ResponseCode.SUCCESS_SAVING_RECIPE, recipeDto.getRecipe().getName()); + } catch (EntityNotFoundException ex) { + modelResponseBuilder.addResponseCode(ResponseCode.RECIPE_NOT_FOUND, recipeDto.getRecipe().getId()).build(); } - Optional optionalRecipe = recipeService.updateRecipe(recipe, optionalStoredRecipe.get(), form); - if (optionalRecipe.isPresent()) { - modelResponseBuilder.addResponseCode(ResponseCode.SUCCESS_SAVING_RECIPE, optionalRecipe.get().getName()); - return listRecipes(modelResponseBuilder.build()); - } - - return listRecipes( - modelResponseBuilder - .addResponseCode(ResponseCode.ERROR_SAVING) - .build()); + return getPage(modelResponseBuilder.build()); } } diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/files/ImageFilesController.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/files/ImageFilesController.java index 97d3aaa..eb2b376 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/files/ImageFilesController.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/files/ImageFilesController.java @@ -7,6 +7,7 @@ import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ModelResponseBuilde import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ResponseCode; import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ResponseDataType; import dev.fyloz.trial.colorrecipesexplorer.core.model.Recipe; +import dev.fyloz.trial.colorrecipesexplorer.core.services.files.ImagesService; import dev.fyloz.trial.colorrecipesexplorer.core.services.model.RecipeService; import dev.fyloz.trial.colorrecipesexplorer.core.utils.ControllerUtils; import org.springframework.beans.factory.annotation.Autowired; @@ -31,28 +32,19 @@ import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.*; public class ImageFilesController { private RecipeService recipeService; + private ImagesService imagesService; @Autowired - public ImageFilesController(RecipeService recipeService) { + public ImageFilesController(RecipeService recipeService, ImagesService imagesService) { this.recipeService = recipeService; + this.imagesService = imagesService; } - /** - * Récupère l'image voulue sous forme JPEG. - * - * @param image Le nom de l'image - * @return L'image en JPEG. - */ @GetMapping(IMAGES_FILES) public ResponseEntity getImage(@PathVariable String image) { - ImageHandler imageHandler = new ImageHandler(image, recipeService); - - byte[] content = imageHandler.readFile(); - if (content == null) return ResponseEntity.notFound().build(); - HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.IMAGE_JPEG); - return new ResponseEntity<>(content, headers, HttpStatus.OK); + return new ResponseEntity<>(imagesService.readImage(image), headers, HttpStatus.OK); } /** @@ -62,8 +54,8 @@ public class ImageFilesController { * Modèle de la page: * - id: Contient l'identifiant de la recette * - * @param model Le Model injecté par Thymeleaf - * @param id L'identifiant de la recette + * @param model Le Model injecté par Thymeleaf + * @param id L'identifiant de la recette * @return La page à afficher. */ @GetMapping(ADD_IMAGE_SPECIFIC) @@ -90,8 +82,8 @@ public class ImageFilesController { *

* REQUIERT UNE AUTORISATION * - * @param id L'identifiant de la recette - * @param image L'image uploadée + * @param id L'identifiant de la recette + * @param image L'image uploadée * @return La page à afficher. */ @PostMapping(ADD_IMAGE) diff --git a/src/main/resources/templates/mix/editor.html b/src/main/resources/templates/mix/editor.html index 64d0460..e75f998 100644 --- a/src/main/resources/templates/mix/editor.html +++ b/src/main/resources/templates/mix/editor.html @@ -5,7 +5,7 @@ - +