/** * {@inheritDoc} */ @Override public <T extends SubscriptionAwareEntity> String getUnsubscribeLinkForSubscribersOf(Class<T> clazz) { return getTopic().getUnsubscribeLinkForSubscribersOf(clazz); }
/** * {@inheritDoc} */ @Override public Set<JCUser> getSubscribers() { return getTopic().getSubscribers(); }
/** * Returns the post breadcrumbs. * * @param post {@link org.jtalks.jcommune.model.entity.Post} the breadcrumbed post. * @return the breadcrumb list for the current <code>Post</code> location. */ public List<Breadcrumb> getForumBreadcrumb(Post post) { List<Breadcrumb> breadcrumbList = getForumBreadcrumb(post.getTopic()); breadcrumbList.add(preparePostBreadcrumb(post)); return breadcrumbList; }
/** * Edit post page filled with data from post with given id * * @param postId post id * @return redirect to post form page * @throws NotFoundException when topic or post not found */ @RequestMapping(value = "/posts/{postId}/edit", method = RequestMethod.GET) public ModelAndView editPage(@PathVariable(POST_ID) Long postId) throws NotFoundException { Post post = postService.get(postId); return new ModelAndView("topic/editPost") .addObject(POST_DTO, PostDto.getDtoFor(post)) .addObject(TOPIC_ID, post.getTopic().getId()) .addObject(POST_ID, postId) .addObject(TOPIC_TITLE, post.getTopic().getTitle()) .addObject("breadcrumbList", breadcrumbBuilder.getForumBreadcrumb(post.getTopic())); }
/** * {@inheritDoc} */ @Override public void filter(Collection<JCUser> users, SubscriptionAwareEntity entity) { if (entity instanceof Post && ((Post)entity).getTopic().getType().equals(QuestionsAndAnswersPlugin.TOPIC_TYPE)) { JCUser postCreator = ((Post)entity).getUserCreated(); boolean containsCreator = users.contains(postCreator); users.clear(); if (containsCreator) { users.add(((Post) entity).getUserCreated()); } } } }
/** * Update existing post * * @param postDto Dto populated in form * @param result validation result * @param postId the current postId * @return {@code ModelAndView} object which will be redirect to topic page * if saved successfully or show form with error message * @throws NotFoundException when topic, branch or post not found */ @RequestMapping(value = "/posts/{postId}/edit", method = RequestMethod.POST) public ModelAndView update(@Valid @ModelAttribute PostDto postDto, BindingResult result, @PathVariable(POST_ID) Long postId) throws NotFoundException { Post post = postService.get(postId); if (result.hasErrors()) { return new ModelAndView("topic/editPost") .addObject(TOPIC_ID, post.getTopic().getId()) .addObject(POST_ID, postId); } postService.updatePost(post, postDto.getBodyText()); return new ModelAndView("redirect:/posts/" + postId); }
/** * {@inheritDoc} */ @Override public int calculatePageForPost(Post post) { Topic topic = post.getTopic(); int index = topic.getPosts().indexOf(post) + 1; int pageSize = userService.getCurrentUser().getPageSize(); int pageNum = index / pageSize; if (index % pageSize == 0) { return pageNum; } else { return pageNum + 1; } }
/** * Delete post by given id * * @param postId post * @return redirect to post next to deleted one. Redirects to previous post in case if it's last post in topic. * @throws NotFoundException when post was not found */ @RequestMapping(method = RequestMethod.DELETE, value = "/posts/{postId}") public ModelAndView delete(@PathVariable(POST_ID) final Long postId) throws NotFoundException { final Post post = this.postService.get(postId); Post nextPost = post.getTopic().getNeighborPost(post); retryTemplate.execute(new RetryCallback<Object, NotFoundException>() { @Override public Object doWithRetry(RetryContext context) throws NotFoundException { Post post = postService.get(postId); postService.deletePost(post); return null; } }); return new ModelAndView("redirect:/posts/" + nextPost.getId()); }
/** * Redirects user to the topic view with the appropriate page selected. * Method clients should not wary about paging at all, post id * is enough to be transferred to the proper page. * * If post belongs to plugable topic and appropriated plugin is enabled redirects * to plugable topic view. * * @param postId unique post identifier * @return redirect view to the certain topic page * @throws NotFoundException is the is no post for the identifier given */ @RequestMapping(method = RequestMethod.GET, value = "/posts/{postId}") public String redirectToPageWithPost(@PathVariable Long postId) throws NotFoundException { Post post = postService.get(postId); int page = postService.calculatePageForPost(post); String topicUrl = converter.convertTopicToDto(post.getTopic()).getTopicUrl(); return "redirect:" + topicUrl + "?page=" + page + "#" + postId; }
/** * Deletes answer by given id * * @param answerId id of the answer * @return redirect to question page * @throws NotFoundException when answer was not found */ @RequestMapping(method = RequestMethod.DELETE, value = "post/{answerId}") public String deleteAnswer(@PathVariable Long answerId) throws NotFoundException { Post answer = getPluginPostService().get(answerId); Post neighborAnswer = answer.getTopic().getNeighborPost(answer); getPluginPostService().deletePost(answer); return "redirect:" + QuestionsAndAnswersPlugin.CONTEXT + "/" + answer.getTopic().getId() + "#" + neighborAnswer.getId(); }
/** * Remove the post from the topic. * * @param postToRemove post to remove */ public void removePost(Post postToRemove) { posts.remove(postToRemove); Topic topic = postToRemove.getTopic(); if (postToRemove.getCreationDate().withMillisOfSecond(0) .equals(topic.getModificationDate().withMillisOfSecond(0))) { topic.recalculateModificationDate(); } }
/** * Show edit answer page * * @param request HttpServletRequest * @param model model for transferring to jsp * @param id id of answer to edit * * @return plugin view name * @throws NotFoundException if answer with specified id not found */ @RequestMapping(value = "post/{id}/edit", method = RequestMethod.GET) public String editAnswerPage(HttpServletRequest request, Model model, @PathVariable("id") Long id) throws NotFoundException{ Post answer = getPluginPostService().get(id); PostDto answerDto = PostDto.getDtoFor(answer); VelocityEngine engine = new VelocityEngine(getProperties()); engine.init(); Map<String, Object> data = getDefaultModel(request); data.put(QEUSTION_TITLE, answer.getTopic().getTitle()); data.put(POST_DTO, answerDto); data.put(HTML_ESCAPER, htmlEscaper); model.addAttribute(CONTENT, getMergedTemplate(engine, ANSWER_FORM_TEMPLATE_PATH, "UTF-8", data)); return PLUGIN_VIEW_NAME; }
/** * Fill the post breadcrumb. * * @param post {@link org.jtalks.jcommune.model.entity.Post} the breadcrumbed post. * @return {@link Breadcrumb} the filled breadcrumb for the Post location. */ private Breadcrumb preparePostBreadcrumb(Post post) { Topic topic = post.getTopic(); return new Breadcrumb( topic.getId(), BreadcrumbLocation.TOPIC, topic.getTitle()); } }
/** * {@inheritDoc} */ @Override public Collection<JCUser> getAllowedSubscribers(SubscriptionAwareEntity entity){ if (entity instanceof Topic) { return this.topicDao.getAllowedSubscribers(entity); } else if (entity instanceof Post) { Post post = (Post) entity; Collection<JCUser> subscribers = topicDao.getAllowedSubscribers(post.getTopic()); /* Can't return Collections.emptyList() or Arrays.asList(...) may be problems with removing elements */ if (subscribers.contains(post.getUserCreated())) { List<JCUser> arrayList = new ArrayList<>(1); arrayList.add(post.getUserCreated()); return arrayList; } else { return new ArrayList<>(); } } else{ return this.branchDao.getAllowedSubscribers(entity); } }
/** * @param entity entity like "Branch/Topics" * @return title for Topic/Branch or "" if entity is not instanceof Topic/Branch */ private String getTitleName(Entity entity) { if (entity instanceof Topic) { Topic topic = (Topic) entity; return ": " + topic.getTitle(); } else if (entity instanceof Branch) { Branch branch = (Branch) entity; return ": " + branch.getName(); } else if (entity instanceof Post) { Post post = (Post) entity; return ": " + post.getTopic().getTitle(); } else { return ""; } }
/** * {@inheritDoc} */ @Override public PostComment addComment(Long postId, Map<String, String> attributes, String body) throws NotFoundException { Post targetPost = get(postId); JCUser currentUser = userService.getCurrentUser(); assertCommentAllowed(targetPost.getTopic()); PostComment comment = new PostComment(); comment.putAllAttributes(attributes); comment.setBody(body); comment.setCreationDate(new DateTime(System.currentTimeMillis())); comment.setAuthor(currentUser); if (currentUser.isAutosubscribe()) { targetPost.getTopic().getSubscribers().add(currentUser); } targetPost.addComment(comment); getDao().saveOrUpdate(targetPost); /** * Notify subscribers of topic if comment added */ notificationService.subscribedEntityChanged(targetPost.getTopic()); return comment; }
/** * Converts page of {@link Post} to page of {@link PostDto} * * @param source page of {@link Post} * * @return page of {@link PostDto} */ public Page<PostDto> convertPostPageToPostDtoPage(Page<Post> source) { List<Plugin> plugins = pluginLoader.getPlugins(new TypeFilter(TopicPlugin.class), new StateFilter(Plugin.State.ENABLED)); List<PostDto> dtos = new ArrayList<>(); for (Post post : source) { PostDto dto = PostDto.getDtoFor(post); dto.setTopicDto(createTopicDto(post.getTopic(), plugins)); dtos.add(dto); } return new PageImpl<>(dtos, PageRequest.fetchFromPage(source), source.getTotalElements()); }
/** * Performs update with security checking. * * @param post an instance of post, that will be updated * @param postContent new content of the post * @throws AccessDeniedException if user tries to update the first post of code review which should be impossible, * see <a href="http://jtalks.org/display/jcommune/1.1+Larks">Requirements</a> * for details */ @PreAuthorize("(hasPermission(#post.id, 'POST', 'GeneralPermission.WRITE') and " + "hasPermission(#post.topic.branch.id, 'BRANCH', 'BranchPermission.EDIT_OWN_POSTS')) or " + "(not hasPermission(#post.id, 'POST', 'GeneralPermission.WRITE') and " + "hasPermission(#post.topic.branch.id, 'BRANCH', 'BranchPermission.EDIT_OTHERS_POSTS'))") @Override public void updatePost(Post post, String postContent) { Topic postTopic = post.getTopic(); if (postTopic.isCodeReview() && postTopic.getPosts().get(0).getId() == post.getId()) { throw new AccessDeniedException("It is impossible to edit code review!"); } post.setPostContent(postContent); post.updateModificationDate(); this.getDao().saveOrUpdate(post); userService.notifyAndMarkNewlyMentionedUsers(post); logger.debug("Post id={} updated.", post.getId()); }
/** * Create dto * * @param post post for conversion * @return dto for post */ public static PostDto getDtoFor(Post post) { PostDto dto = new PostDto(); dto.setBodyText(post.getPostContent()); dto.setId(post.getId()); dto.setTopicId(post.getTopic().getId()); dto.setCreationDate(post.getCreationDate()); dto.setModificationDate(post.getModificationDate()); return dto; }
/** * Creates feed item with information about the post * * @param post post to add to the feed * @param componentUrl base url of the forum component * @return item for the RSS feed */ private Item createFeedItem(Post post, String componentUrl) { Item item = new Item(); Content content = new Content(); content.setType(Content.TEXT); content.setValue(post.getPostContent()); item.setContent(content); item.setTitle(post.getTopic().getTitle()); item.setAuthor(post.getUserCreated().getUsername()); item.setLink(componentUrl + "/posts/" + post.getId()); item.setPubDate(post.getCreationDate().toDate()); return item; }