/** * {@inheritDoc} * * <p> * The target URL has the next format http://{forum root}/branches/{id} */ @Override public String getUrlSuffix() { return URL_SUFFIX + getId(); }
/** * {@inheritDoc} */ @Override public <T extends SubscriptionAwareEntity> String getUnsubscribeLinkForSubscribersOf(Class<T> clazz) { if (Branch.class.isAssignableFrom(clazz)) { return String.format("/branches/%s/unsubscribe", getId()); } return null; }
/** * {@inheritDoc} */ @Override public List<Post> getLastPostsFor(Branch branch, int postCount) { return getDao().getLastPostsFor(Arrays.asList(branch.getId()), postCount); }
private List<Branch> getBranchesWithViewPermission(Long topicId, List<Branch> branches) { Topic topic = topicDao.get(topicId); List<Branch> result = new ArrayList<>(); for (Branch branch : branches) { if (permissionService.hasBranchPermission(branch.getId(), BranchPermission.VIEW_TOPICS)) { result.add(branch); } } result.remove(topic.getBranch()); return result; }
/** * Delete topic * * @param topicId topic id, this is the topic which contains the first post which should be deleted * @return redirect to branch page * @throws NotFoundException when topic not found */ @RequestMapping(value = "/topics/{topicId}", method = RequestMethod.DELETE) public ModelAndView deleteTopic(@PathVariable(TOPIC_ID) Long topicId) throws NotFoundException { Topic topic = topicFetchService.get(topicId); topicModificationService.deleteTopic(topic); return new ModelAndView("redirect:/branches/" + topic.getBranch().getId()); }
/** * Fill the branch breadcrumb. * * @param branch {@link org.jtalks.jcommune.model.entity.Branch} of the breadcrumbed topic. * @return {@link Breadcrumb} the filled breadcrumb for the Topic location. */ private Breadcrumb prepareTopicBreadcrumb(Branch branch) { return new Breadcrumb( branch.getId(), BreadcrumbLocation.BRANCH, branch.getName()); }
/** * Get last post that was posted in a topic of branch. * Uses hibernate criteria instead of invoking {@link #getLastPostsFor} method that uses hql query. * Done for better performance results. This solution can return only one last post so method * {@link #getLastPostsFor} stay without changes. * * @param branch in this branch post was posted * @return last post that was posted in a topic of branch */ @Override public Post getLastPostFor(Branch branch) { List<Post> posts = (List<Post>) session() .getNamedQuery("getLastPostForBranch") .setParameter("branchId", branch.getId()) .setMaxResults(1) .list(); if (!posts.isEmpty()) { return posts.get(0); } return null; }
/** * Converts branch list into branch dto array. * * @param branches branch list * @return branch dto array */ private BranchDto[] convertBranchesListToBranchDtoArray(List<Branch> branches) { List<BranchDto> dtos = project(branches, BranchDto.class, on(Branch.class).getId(), on(Branch.class).getName()); return dtos.toArray(new BranchDto[dtos.size()]); }
/** * Saves topic after edit topic form submission. * * @param topicDto Dto populated in form * @param result validation result * @param topicId the current topicId * @return {@code ModelAndView} with redirect to saved topic or the same page with validation errors, if any * @throws NotFoundException when topic or branch not found */ @RequestMapping(value = "/topics/{topicId}/edit", method = RequestMethod.POST) public ModelAndView editTopic(@Valid @ModelAttribute TopicDto topicDto, BindingResult result, @PathVariable(TOPIC_ID) Long topicId) throws NotFoundException { Topic topic = topicFetchService.get(topicId); if (result.hasErrors()) { 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)); } topicDto.fillTopic(topic); topicModificationService.updateTopic(topic, topicDto.getPoll()); return new ModelAndView(REDIRECT_URL + topicId); }
/** * 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)); }
/** * {@inheritDoc} */ @Override public Branch deleteAllTopics(long branchId) throws NotFoundException { Branch branch = get(branchId); // Create tmp list to avoid ConcurrentModificationException List<Topic> loopList = new ArrayList<>(branch.getTopics()); for (Topic topic : loopList) { topicService.deleteTopicSilent(topic.getId()); } logger.info("All topics for branch \"{}\" were deleted. " + "Branch id: {}", branch.getName(), branch.getId()); return branch; }
/** * Set mail about removing topic. * * @param recipient Recipient for which send notification * @param topic Current topic * @param curUser User that removed the topic */ public void sendRemovingTopicMail(JCUser recipient, Topic topic, String curUser) { Locale locale = recipient.getLanguage().getLocale(); Map<String, Object> model = new HashMap<>(); model.put(USER, recipient); model.put(RECIPIENT_LOCALE, locale); model.put(CUR_USER, curUser); //Topic not exist more and user not subscribed to branch, so simply redirect to branch model.put(LINK_UNSUBSCRIBE, this.getDeploymentRootUrl() + "/branches/" + topic.getBranch().getId()); model.put(TOPIC, topic); try { String subjectTemplate = REMOVE_TOPIC_SUBJECT_TEMPLATE; String messageBodyTemplate = REMOVE_TOPIC_MESSAGE_BODY_TEMPLATE; if (topic.isCodeReview()) { subjectTemplate = REMOVE_CODE_REVIEW_SUBJECT_TEMPLATE; messageBodyTemplate = REMOVE_CODE_REVIEW_MESSAGE_BODY_TEMPLATE; } String subject = messageSource.getMessage(subjectTemplate, new Object[]{}, locale); this.sendEmail(recipient.getEmail(), subject, model, messageBodyTemplate); } catch (MailingFailedException e) { LOGGER.error("Failed to sent mail about removing topic or code review for user: " + recipient.getUsername()); } }
/** * Checks if the current topic is closed for posting. * Some users, however, can add posts even to the closed branches. These * users are granted with BranchPermission.CLOSE_TOPICS permission. * * @param topic topic to be checked for if posting is allowed */ private void assertPostingIsAllowed(Topic topic) { Authentication auth = securityContextFacade.getContext().getAuthentication(); if (topic.isClosed() && !permissionEvaluator.hasPermission( auth, topic.getBranch().getId(), "BRANCH", "BranchPermission.CLOSE_TOPICS")) { // holy shit... throw new AccessDeniedException("Posting is forbidden for closed topics"); } }
final long branchId = topic.getBranch().getId(); Post newbie = retryTemplate.execute(new RetryCallback<Post, NotFoundException>() { @Override
Topic topic = topicFetchService.get(topicId); topicFetchService.checkViewTopicPermission(topic.getBranch().getId()); Page<Post> postsPage = postService.getPosts(topic, page);
/** * Checks if current user can create comments in specified topic * * @param topic topic to check permission * @throws AccessDeniedException if user can't create comments in specified topic */ private void assertCommentAllowed(Topic topic) { if (topic.isCodeReview()) { permissionService.checkPermission(topic.getBranch().getId(), AclClassName.BRANCH, BranchPermission.LEAVE_COMMENTS_IN_CODE_REVIEW); } else if (topic.isPlugable()) { assertCommentsAllowedForPlugableTopic(topic); } else { throw new AccessDeniedException("Adding comments not allowed for core topic types"); } if (topic.isClosed()) { permissionService.checkPermission(topic.getBranch().getId(), AclClassName.BRANCH, BranchPermission.CLOSE_TOPICS); } }
throws NotFoundException { Topic topic = getTypeAwarePluginTopicService().get(id, QuestionsAndAnswersPlugin.TOPIC_TYPE); getTypeAwarePluginTopicService().checkViewTopicPermission(topic.getBranch().getId());
/** * Checks if current user can create comments in specified plugable topic * * @param topic plugable topic to check permission * @throws AccessDeniedException if user not granted to create comments in specified topic type or if type of * current topic is unknown */ private void assertCommentsAllowedForPlugableTopic(Topic topic) { List<Plugin> topicPlugins = pluginLoader.getPlugins(new TypeFilter(TopicPlugin.class), new StateFilter(Plugin.State.ENABLED)); boolean pluginFound = false; for (Plugin plugin : topicPlugins) { TopicPlugin topicPlugin = (TopicPlugin)plugin; if (topicPlugin.getTopicType().equals(topic.getType())) { pluginFound = true; permissionService.checkPermission(topic.getBranch().getId(), AclClassName.BRANCH, topicPlugin.getCommentPermission()); break; } } if (!pluginFound) { throw new AccessDeniedException("Creation of comments not allowed for unknown topic type"); } } }
/** * Checks for plugable topic if current user is granted to create topics with type. * * @param topic topic to be checked * @throws AccessDeniedException if user not granted to create current topic type * or if type of current topic is unknown */ private void assertCreationAllowedForPlugableTopic(Topic topic) { if (topic.isPlugable()) { Authentication auth = securityContextFacade.getContext().getAuthentication(); List<Plugin> topicPlugins = pluginLoader.getPlugins(new TypeFilter(TopicPlugin.class), new StateFilter(Plugin.State.ENABLED)); boolean pluginFound = false; for (Plugin plugin : topicPlugins) { TopicPlugin topicPlugin = (TopicPlugin)plugin; if (topicPlugin.getTopicType().equals(topic.getType())) { pluginFound = true; if (!permissionEvaluator.hasPermission(auth, topic.getBranch().getId(), "BRANCH", topicPlugin.getCreateTopicPermission())) { throw new AccessDeniedException("Creating of topic with type " + topic.getType() + " is forbidden"); } } } if (!pluginFound) { throw new AccessDeniedException("Creating of unknown topic type is forbidden"); } } }
public static TopicDraft getDefaultTopicDraft() { JCUser user = persist(ObjectsFactory.getDefaultUser()); Branch branch = persist(ObjectsFactory.getDefaultBranch()); TopicDraft newTopicDraft = new TopicDraft(user, RandomStringUtils.random(5), RandomStringUtils.random(15)); newTopicDraft.setTopicType(TopicTypeName.DISCUSSION.getName()); newTopicDraft.setBranchId(branch.getId()); persist(newTopicDraft); return newTopicDraft; }