/** * Copyright (C) 2011 JTalks.org Team * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ package org.jtalks.jcommune.web.controller; import org.jtalks.jcommune.model.entity.Post; import org.jtalks.jcommune.model.entity.PostComment; import org.jtalks.jcommune.service.PostCommentService; import org.jtalks.jcommune.plugin.api.exceptions.NotFoundException; import org.jtalks.jcommune.service.PostService; import org.jtalks.jcommune.web.dto.CodeReviewCommentDto; import org.jtalks.jcommune.web.dto.CodeReviewDto; import org.jtalks.jcommune.plugin.api.web.dto.json.FailJsonResponse; import org.jtalks.jcommune.plugin.api.web.dto.json.FailValidationJsonResponse; import org.jtalks.jcommune.plugin.api.web.dto.json.JsonResponse; import org.jtalks.jcommune.plugin.api.web.dto.json.JsonResponseReason; import org.jtalks.jcommune.plugin.api.web.dto.json.JsonResponseStatus; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.propertyeditors.StringTrimmerEditor; import org.springframework.security.access.AccessDeniedException; import org.springframework.stereotype.Controller; import org.springframework.validation.BindingResult; import org.springframework.web.bind.WebDataBinder; import org.springframework.web.bind.annotation.*; import javax.validation.Valid; /** * Serves code review comment management web requests * * @author Vyachesla Mishcheryakov * @see org.jtalks.jcommune.model.entity.Topic */ @Controller public class CodeReviewCommentController { public static final String POST_ID = "postId"; public static final String COMMENT_ID = "commentId"; private PostCommentService postCommentService; private PostService postService; /** * @param postCommentService to operate with {@link org.jtalks.jcommune.model.entity.PostComment} entities * @param postService to operate with {@link org.jtalks.jcommune.model.entity.Post} entities */ @Autowired public CodeReviewCommentController(PostCommentService postCommentService, PostService postService) { this.postCommentService = postCommentService; this.postService = postService; } /** * This method turns the trim binder on. Trim binder * removes leading and trailing spaces from the submitted fields. * So, it ensures, that all validations will be applied to * trimmed field values only. * * @param binder Binder object to be injected */ @InitBinder public void initBinder(WebDataBinder binder) { binder.registerCustomEditor(String.class, new StringTrimmerEditor(true)); } /** * Returns code review by its ID as JSON data * * @param postId ID of post * @return JSON response object containing string status and review DTO as * result field * @throws NotFoundException if code review was not found */ @RequestMapping(value = "/reviews/{postId}/json", method = RequestMethod.GET) @ResponseBody public JsonResponse getCodeReview(@PathVariable("postId") Long postId) throws NotFoundException { Post post = postService.get(postId); return new JsonResponse(JsonResponseStatus.SUCCESS, new CodeReviewDto(post)); } /** * Adds CR comment to review * @param commentDto incoming DTO object from client * @param bindingResult object contains validation information * @param postId ID of post where add comment to * @return response with status 'success' and comment DTO object if comment * was added or 'fail' with no objects if there were some errors * @throws NotFoundException when no review with <code>reviewId</code>was found */ @RequestMapping(value="/reviewcomments/new", method = RequestMethod.POST) @ResponseBody public JsonResponse addComment( @Valid @ModelAttribute CodeReviewCommentDto commentDto, BindingResult bindingResult, @RequestParam("postId") Long postId) throws NotFoundException { if (bindingResult.hasErrors()) { return new FailValidationJsonResponse(bindingResult.getAllErrors()); } PostComment addedComment = postService.addComment(postId, commentDto.getCommentAttributes(), commentDto.getBody()); CodeReviewCommentDto addedCommentDto = new CodeReviewCommentDto(addedComment); return new JsonResponse(JsonResponseStatus.SUCCESS, addedCommentDto); } /** * Deletes CR comment from review * * @param commentId comment ID * @param postId ID of post where delete comment to * @return response with status 'success' if comment * was deleted or 'fail' with no objects if there were some errors * @throws NotFoundException when no review with <code>reviewId</code> * or comment with <code>commentId</code> was found */ @RequestMapping(value = "/reviewcomments/delete", method = RequestMethod.GET) @ResponseBody public JsonResponse deleteComment( @RequestParam(COMMENT_ID) Long commentId, @RequestParam(POST_ID) Long postId) throws NotFoundException { postService.deleteComment(postService.get(postId), postCommentService.get(commentId)); return new JsonResponse(JsonResponseStatus.SUCCESS); } /** * Save CR comment * @param commentDto incoming DTO object from client * @param bindingResult object contains validation information * @return response with status 'success' and comment DTO object if comment * was added or 'fail' with no objects if there were some errors * @throws NotFoundException when no CR comment with <code>commentDto.id</code> * was found */ @RequestMapping(value="/reviewcomments/edit", method = RequestMethod.POST) @ResponseBody public JsonResponse editComment( @Valid @ModelAttribute CodeReviewCommentDto commentDto, BindingResult bindingResult, @RequestParam("branchId") long branchId) throws NotFoundException { if (bindingResult.hasErrors()) { return new FailValidationJsonResponse(bindingResult.getAllErrors()); } PostComment editedComment = postCommentService.updateComment( commentDto.getId(), commentDto.getBody(), branchId); CodeReviewCommentDto editedCommentDto = new CodeReviewCommentDto(editedComment); return new JsonResponse(JsonResponseStatus.SUCCESS, editedCommentDto); } /** * Returns fail response when security exception is through * @return fail response with status 'Fail' and reason 'security' */ @ExceptionHandler(AccessDeniedException.class) @ResponseBody public FailJsonResponse securityError() { return new FailJsonResponse(JsonResponseReason.SECURITY); } /** * Returns fail response when entity with given ID was not found * @return fail response with status 'Fail' and reason 'entity-not-found' */ @ExceptionHandler(NotFoundException.class) @ResponseBody public FailJsonResponse entityNotFoundError() { return new FailJsonResponse(JsonResponseReason.ENTITY_NOT_FOUND); } }