109 lines
4.4 KiB
Java
109 lines
4.4 KiB
Java
package app.mealsmadeeasy.api.recipe.comment;
|
|
|
|
import app.mealsmadeeasy.api.markdown.MarkdownService;
|
|
import app.mealsmadeeasy.api.recipe.Recipe;
|
|
import app.mealsmadeeasy.api.recipe.RecipeRepository;
|
|
import app.mealsmadeeasy.api.user.User;
|
|
import app.mealsmadeeasy.api.util.NoSuchEntityWithIdException;
|
|
import app.mealsmadeeasy.api.util.NoSuchEntityWithUsernameAndSlugException;
|
|
import org.springframework.data.domain.Pageable;
|
|
import org.springframework.data.domain.Slice;
|
|
import org.springframework.security.access.prepost.PostAuthorize;
|
|
import org.springframework.security.access.prepost.PreAuthorize;
|
|
import org.springframework.stereotype.Service;
|
|
|
|
import java.time.OffsetDateTime;
|
|
|
|
import static java.util.Objects.requireNonNull;
|
|
|
|
@Service
|
|
public class RecipeCommentServiceImpl implements RecipeCommentService {
|
|
|
|
private final RecipeCommentRepository recipeCommentRepository;
|
|
private final RecipeRepository recipeRepository;
|
|
private final MarkdownService markdownService;
|
|
|
|
public RecipeCommentServiceImpl(
|
|
RecipeCommentRepository recipeCommentRepository,
|
|
RecipeRepository recipeRepository,
|
|
MarkdownService markdownService
|
|
) {
|
|
this.recipeCommentRepository = recipeCommentRepository;
|
|
this.recipeRepository = recipeRepository;
|
|
this.markdownService = markdownService;
|
|
}
|
|
|
|
@Override
|
|
@PreAuthorize("@recipeSecurity.isViewableBy(#recipeUsername, #recipeSlug, #commenter)")
|
|
public RecipeComment create(
|
|
String recipeUsername,
|
|
String recipeSlug,
|
|
User commenter,
|
|
RecipeCommentCreateBody body
|
|
) {
|
|
requireNonNull(commenter);
|
|
final RecipeComment draft = new RecipeComment();
|
|
draft.setCreated(OffsetDateTime.now());
|
|
draft.setRawText(body.getText());
|
|
draft.setCachedRenderedText(this.markdownService.renderAndCleanMarkdown(body.getText()));
|
|
draft.setOwner(commenter);
|
|
final Recipe recipe = this.recipeRepository.findByOwnerUsernameAndSlug(recipeUsername, recipeSlug)
|
|
.orElseThrow(
|
|
() -> new NoSuchEntityWithUsernameAndSlugException(Recipe.class, recipeUsername, recipeSlug)
|
|
);
|
|
draft.setRecipe(recipe);
|
|
return this.recipeCommentRepository.save(draft);
|
|
}
|
|
|
|
@PostAuthorize("@recipeSecurity.isViewableBy(returnObject.recipe, #viewer)")
|
|
private RecipeComment loadCommentEntity(Integer commentId, User viewer) {
|
|
return this.recipeCommentRepository.findById(commentId).orElseThrow(
|
|
() -> new NoSuchEntityWithIdException(RecipeComment.class, commentId)
|
|
);
|
|
}
|
|
|
|
@Override
|
|
public RecipeComment get(Integer commentId, User viewer) {
|
|
return this.loadCommentEntity(commentId, viewer);
|
|
}
|
|
|
|
@Override
|
|
@PreAuthorize("@recipeSecurity.isViewableBy(#recipeUsername, #recipeSlug, #viewer)")
|
|
public Slice<RecipeCommentView> getComments(
|
|
String recipeUsername,
|
|
String recipeSlug,
|
|
Pageable pageable,
|
|
User viewer
|
|
) {
|
|
final Recipe recipe = this.recipeRepository.findByOwnerUsernameAndSlug(recipeUsername, recipeSlug).orElseThrow(
|
|
() -> new NoSuchEntityWithUsernameAndSlugException(Recipe.class, recipeUsername, recipeSlug)
|
|
);
|
|
final Slice<RecipeComment> commentEntities = this.recipeCommentRepository.findAllByRecipe(recipe, pageable);
|
|
return commentEntities.map(commentEntity -> RecipeCommentView.from(
|
|
commentEntity,
|
|
false
|
|
));
|
|
}
|
|
|
|
@Override
|
|
public RecipeComment update(Integer commentId, User viewer, RecipeCommentUpdateSpec spec) {
|
|
final RecipeComment entity = this.loadCommentEntity(commentId, viewer);
|
|
entity.setRawText(spec.getRawText());
|
|
return this.recipeCommentRepository.save(entity);
|
|
}
|
|
|
|
@PostAuthorize("@recipeSecurity.isOwner(returnObject.recipe, #modifier)")
|
|
private RecipeComment loadForDelete(Integer commentId, User modifier) {
|
|
return this.recipeCommentRepository.findById(commentId).orElseThrow(() ->
|
|
new NoSuchEntityWithIdException(RecipeComment.class, commentId)
|
|
);
|
|
}
|
|
|
|
@Override
|
|
public void delete(Integer commentId, User modifier) {
|
|
final RecipeComment entityToDelete = this.loadForDelete(commentId, modifier);
|
|
this.recipeCommentRepository.delete(entityToDelete);
|
|
}
|
|
|
|
}
|