/** * Returns the topic breadcrumbs. * * @param topic {@link org.jtalks.jcommune.model.entity.Topic} the breadcrumbed topic. * @return the breadcrumb list for the current <code>Topic</code> location. */ public List<Breadcrumb> getForumBreadcrumb(Topic topic) { List<Breadcrumb> breadcrumbList = getForumBreadcrumb(topic.getBranch()); breadcrumbList.add(prepareTopicBreadcrumb(topic.getBranch())); return breadcrumbList; }
/** * {@inheritDoc} */ @PreAuthorize("(hasPermission(#topic.branch.id, 'BRANCH', 'BranchPermission.DELETE_OWN_POSTS') and " + "#topic.containsOwnerPostsOnly and #topic.topicStarter.id == principal.id) or " + "(hasPermission(#topic.branch.id, 'BRANCH', 'BranchPermission.DELETE_OTHERS_POSTS') and " + "hasPermission(#topic.branch.id, 'BRANCH', 'BranchPermission.DELETE_OWN_POSTS'))") @Override public void deleteTopic(Topic topic) throws NotFoundException { deleteTopicSilent(topic); notificationService.sendNotificationAboutRemovingTopic(topic); logger.info("Deleted topic \"{}\". Topic id: {}", topic.getTitle(), topic.getId()); }
/** * Removes draft of specified user if exist * * @param user user to search draft */ public void removeDraftOfUser(JCUser user) { PostDraft draft = getDraftForUser(user); if (draft != null) { removeDraft(draft); } }
/** * Create dto from {@link Topic} * * @param topic topic for conversion */ public TopicDto(Topic topic) { this.topic = topic; if (!topic.getPosts().isEmpty()) { bodyText = topic.getBodyText(); } }
/** * Fills persistent topic object with data from the current dto * * @param persistentTopic persistent topic * @return the same topic with fields set from dto */ public Topic fillTopic(Topic persistentTopic) { persistentTopic.setTitle(topic.getTitle()); persistentTopic.getFirstPost().setPostContent(bodyText); persistentTopic.setAnnouncement(topic.isAnnouncement()); persistentTopic.setSticked(topic.isSticked()); return topic; } }
assertCreationAllowedForPlugableTopic(topicDto); JCUser currentUser = userService.getCurrentUser(); Branch branch = topicDto.getBranch(); Topic topic = new Topic(currentUser, topicDto.getTitle()); topic.setAnnouncement(topicDto.isAnnouncement()); topic.setSticked(topicDto.isSticked()); topic.setBranch(topicDto.getBranch()); if (topicDto.isCodeReview()) { bodyText = wrapWithCodeTag(bodyText); topic.setType(topicDto.getType()); topic.addPost(first); topic.setBranch(branch); branch.setLastPost(first); subscriptionService.subscribe(topic); createPoll(topicDto.getPoll(), topic); userService.notifyAndMarkNewlyMentionedUsers(topic.getFirstPost()); lastReadPostService.markTopicAsRead(topic); topicDraftService.deleteDraft(); logger.debug("Created new topic id={}, branch id={}, author={}", new Object[]{topic.getId(), topic.getBranch().getId(), currentUser.getUsername()}); return topic;
/** * {@inheritDoc} */ @PreAuthorize("hasPermission(#topic.branch.id, 'BRANCH', 'BranchPermission.MOVE_TOPICS')") @Override public void moveTopic(Topic topic, Long branchId) throws NotFoundException { Branch sourceBranch = topic.getBranch(); Branch targetBranch = branchDao.get(branchId); if (targetBranch == null) { throw new NotFoundException("Target branch not exist"); } targetBranch.addTopic(topic); branchDao.saveOrUpdate(targetBranch); List<Post> topicPosts = topic.getPosts(); if (topicPosts.contains(sourceBranch.getLastPost())) { branchLastPostService.refreshLastPostInBranch(sourceBranch); } branchLastPostService.refreshLastPostInBranch(targetBranch); notificationService.sendNotificationAboutTopicMoved(topic); logger.info("Moved topic \"{}\". Topic id: {}", topic.getTitle(), topic.getId()); }
Topic topic = getTypeAwarePluginTopicService().get(questionId, QuestionsAndAnswersPlugin.TOPIC_TYPE); if (result.hasErrors() || LIMIT_OF_POSTS_VALUE <= topic.getPostCount() - 1) { JCUser currentUser = getUserReader().getCurrentUser(); PostDraft draft = topic.getDraftForUser(currentUser); if (draft != null) { engine.init(); data.put(QUESTION, topic); data.put(POST_PAGE, new PageImpl<>(getSortedPosts(topic.getPosts()))); data.put(BREADCRUMB_LIST, breadcrumbBuilder.getForumBreadcrumb(topic)); data.put(SUBSCRIBED, false); postDto.getBodyText(), topic.getBranch().getId()); getPluginLastReadPostService().markTopicAsRead(newbie.getTopic()); return "redirect:" + QuestionsAndAnswersPlugin.CONTEXT + "/" + questionId + "#" + newbie.getId();
Topic topic = topicFetchService.get(topicId); topicFetchService.checkViewTopicPermission(topic.getBranch().getId()); Page<Post> postsPage = postService.getPosts(topic, page); if (request.checkNotModified(topic.getLastModificationPostDate().getMillis())) { return null; PostDraft draft = topic.getDraftForUser(currentUser); if (draft != null) { postDto = PostDto.getDtoFor(draft); .addObject("topic", topic) .addObject(POST_DTO, postDto) .addObject("subscribed", topic.getSubscribers().contains(currentUser)) .addObject(BREADCRUMB_LIST, breadcrumbBuilder.getForumBreadcrumb(topic)) .addObject("markAsReadLink", topic.getMarkAsReadUrl(currentUser, page).orNull());
Map<String, Object> data = getDefaultModel(request); if (result.hasErrors()) { topicDto.getTopic().setId(topic.getId()); topicDto.getTopic().setBranch(topic.getBranch()); VelocityEngine engine = new VelocityEngine(getProperties()); engine.init(); return "redirect:" + QuestionsAndAnswersPlugin.CONTEXT + "/" + topic.getId();
/** * {@inheritDoc} * * @throws AccessDeniedException besides other reasons, always throws this when Code Review is edited because it * shouldn't be possible to edit it. More details on requirements can be found here * <a href="http://jtalks.org/display/jcommune/1.1+Larks">here</a>. */ @Override @PreAuthorize("(hasPermission(#topic.id, 'TOPIC', 'GeneralPermission.WRITE') and " + "hasPermission(#topic.branch.id, 'BRANCH', 'BranchPermission.EDIT_OWN_POSTS')) or " + "(not hasPermission(#topic.id, 'TOPIC', 'GeneralPermission.WRITE') and " + "hasPermission(#topic.branch.id, 'BRANCH', 'BranchPermission.EDIT_OTHERS_POSTS'))") public void updateTopic(Topic topic, Poll poll) { if (topic.isCodeReview()) { throw new AccessDeniedException("It is not allowed to edit Code Review!"); } Post post = topic.getFirstPost(); post.updateModificationDate(); if (poll != null && poll.getEndingDate() != null) { topic.getPoll().setEndingDate(poll.getEndingDate()); } dao.saveOrUpdate(topic); logger.debug("Topic id={} updated", topic.getId()); }
/** * Performs actual topic deletion. Deletes all topic related data and * recalculates user's post count. * * @param topic topic to delete * @return branch without deleted topic */ private Branch deleteTopicSilent(Topic topic) { List<Post> topicPosts = topic.getPosts(); for (Post post : topicPosts) { JCUser user = post.getUserCreated(); user.setPostCount(user.getPostCount() - 1); } Branch branch = topic.getBranch(); Post lastPostInBranch = branch.getLastPost(); boolean branchLastPostFromDeletedTopic = topicPosts.contains(lastPostInBranch); if (branchLastPostFromDeletedTopic) { branch.clearLastPost(); } branch.deleteTopic(topic); branchDao.saveOrUpdate(branch); if (branchLastPostFromDeletedTopic) { branchLastPostService.refreshLastPostInBranch(branch); } securityService.deleteFromAcl(Topic.class, topic.getId()); return branch; }
/** * Find last read post in the list for given topic. * * @param lastReadPosts the list of last read posts where we are going to search * @param topicId an identifier of topic for which we find last read post in list * @return last read post for given topic */ private LastReadPost findLastReadPost(List<LastReadPost> lastReadPosts, long topicId) { for (LastReadPost lastReadPost : lastReadPosts) { if (lastReadPost.getTopic().getId() == topicId) { return lastReadPost; } } return null; }
throws NotFoundException { Topic topic = getTypeAwarePluginTopicService().get(id, QuestionsAndAnswersPlugin.TOPIC_TYPE); getTypeAwarePluginTopicService().checkViewTopicPermission(topic.getBranch().getId()); PostDraft draft = topic.getDraftForUser(currentUser); if (draft != null) { postDto = PostDto.getDtoFor(draft); data.put(POST_PAGE, new PageImpl<>(getSortedPosts(topic.getPosts()))); data.put(BREADCRUMB_LIST, breadcrumbBuilder.getForumBreadcrumb(topic)); data.put(SUBSCRIBED, false);
/** * Create news item * * @param topic news topic * @param url building URL * @return item for news feed */ private Item createFeedItem(Topic topic, String url) { Item item = new Item(); Description description = new Description(); description.setType("text"); String postContent = topic.getLastPost().getPostContent(); postContent = RssUtils.skipInValidXMLChars(postContent); description.setValue(postContent); Content content = new Content(); item.setContent(content); item.setTitle(topic.getTitle()); item.setAuthor(topic.getLastPost().getUserCreated().getUsername()); item.setLink(url + "/posts/" + topic.getLastPost().getId()); item.setComments(topic.getTopicStarter().getSignature()); item.setDescription(description); item.setPubDate(topic.getModificationDate().toDate()); return item; }
/** * {@inheritDoc} */ @Override public <T extends SubscriptionAwareEntity> String getUnsubscribeLinkForSubscribersOf(Class<T> clazz) { if (Branch.class.isAssignableFrom(clazz)) { return getBranch().getUnsubscribeLinkForSubscribersOf(clazz); } else { //In case of post unsubscribe from topic too return String.format("/topics/%s/unsubscribe", getId()); } }
/** * Shows edit topic page with form, populated with fields from topic. * * @param topicId the id of selected Topic * @return {@code ModelAndView} * @throws NotFoundException when topic or branch not found */ @RequestMapping(value = "/topics/{topicId}/edit", method = RequestMethod.GET) public ModelAndView editTopicPage(@PathVariable(TOPIC_ID) Long topicId) throws NotFoundException { Topic topic = topicFetchService.get(topicId); if (topic.isCodeReview()) { throw new AccessDeniedException("Edit page for code review"); } TopicDto topicDto = new TopicDto(topic); return new ModelAndView(TOPIC_VIEW) .addObject(BRANCH_ID, topic.getBranch().getId()) .addObject(TOPIC_DTO, topicDto) .addObject(POLL, topic.getPoll()) .addObject(SUBMIT_URL, "/topics/" + topicId + "/edit") .addObject(BREADCRUMB_LIST, breadcrumbBuilder.getForumBreadcrumb(topic)); }
/** * Returns first post that is newer then give time * @param time time to looking for newer post * @return first post that is newer then give time or first post if there is no post that is newer */ private Post getFirstNewerPost(DateTime time) { for (Post post : getPosts()) { if (post.getCreationDate().isAfter(time)) { return post; } } return getFirstPost(); }
/** * Shows page with form for new code review * * @param branchId {@link Branch} branch, where code review will be created * @return {@code ModelAndView} object with "codeReviewForm" view, new {@link TopicDto} and branch id * @throws NotFoundException when branch was not found */ @RequestMapping(value = "/reviews/new", method = RequestMethod.GET) public ModelAndView showNewCodeReviewPage(@RequestParam(BRANCH_ID) Long branchId) throws NotFoundException { TopicDraft draft = ObjectUtils.defaultIfNull( topicDraftService.getDraft(), new TopicDraft()); TopicDto dto = new TopicDto(draft); Branch branch = branchService.get(branchId); dto.getTopic().setBranch(branch); dto.getTopic().setType(TopicTypeName.CODE_REVIEW.getName()); return new ModelAndView(CODE_REVIEW_VIEW) .addObject(TOPIC_DTO, dto) .addObject(TOPIC_DRAFT, draft) .addObject(BRANCH_ID, branchId) .addObject(SUBMIT_URL, "/reviews/new?branchId=" + branchId) .addObject(BREADCRUMB_LIST, breadcrumbBuilder.getNewTopicBreadcrumb(branch)); }