package org.iatoki.judgels.raguel.forum; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import org.iatoki.judgels.raguel.forum.member.ForumMemberDao; import org.iatoki.judgels.raguel.forum.module.ForumModuleDao; import org.iatoki.judgels.raguel.forum.thread.ForumThreadDao; import org.iatoki.judgels.raguel.user.item.UserItemDao; import org.iatoki.judgels.raguel.forum.module.ForumModuleModel; import org.iatoki.judgels.raguel.forum.thread.ForumThreadModel; import org.iatoki.judgels.raguel.forum.thread.ForumThreadModel_; import org.iatoki.judgels.raguel.user.item.UserItemModel; import org.iatoki.judgels.raguel.user.item.UserItemModel_; import org.iatoki.judgels.raguel.forum.module.ForumModule; import org.iatoki.judgels.raguel.forum.module.ForumModuleFactory; import org.iatoki.judgels.raguel.forum.module.ForumModules; import javax.inject.Inject; import javax.inject.Singleton; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Stack; import java.util.stream.Collectors; @Singleton public final class ForumServiceImpl implements ForumService { private final ForumDao forumDao; private final ForumLastPostDao forumLastPostDao; private final ForumMemberDao forumMemberDao; private final ForumModuleDao forumModuleDao; private final ForumModuleFactory forumModuleFactory; private final ForumThreadDao forumThreadDao; private final UserItemDao userItemDao; @Inject public ForumServiceImpl(ForumDao forumDao, ForumLastPostDao forumLastPostDao, ForumMemberDao forumMemberDao, ForumModuleDao forumModuleDao, ForumModuleFactory forumModuleFactory, ForumThreadDao forumThreadDao, UserItemDao userItemDao) { this.forumDao = forumDao; this.forumLastPostDao = forumLastPostDao; this.forumMemberDao = forumMemberDao; this.forumModuleDao = forumModuleDao; this.forumModuleFactory = forumModuleFactory; this.forumThreadDao = forumThreadDao; this.userItemDao = userItemDao; } @Override public boolean forumExistsByJid(String forumJid) { return forumDao.existsByJid(forumJid); } @Override public List<Forum> getAllForumsForReferences() { Stack<Forum> forumStack = new Stack<>(); forumStack.add(null); ImmutableList.Builder<Forum> forumBuilder = ImmutableList.builder(); while (!forumStack.isEmpty()) { Forum currentForum = forumStack.pop(); String currentJid; if (currentForum != null) { currentJid = currentForum.getJid(); forumBuilder.add(currentForum); } else { currentJid = ""; } List<ForumModel> forumModels = forumDao.findSortedByFiltersEq("id", "asc", "", ImmutableMap.of(ForumModel_.parentJid, currentJid), 0, -1); for (ForumModel forumModel : forumModels) { Forum forum = ForumServiceUtils.createPlainForumFromModel(forumModel, currentForum); if (currentForum != null) { currentForum.getSubforums().add(forum); } forumStack.push(forum); } } return forumBuilder.build(); } @Override public List<Forum> getChildForums(String parentJid, long maxDepth) { List<ForumModel> forumModels = forumDao.findSortedByFiltersEq("id", "asc", "", ImmutableMap.of(ForumModel_.parentJid, parentJid), 0, -1); List<Forum> forums = forumModels.stream().map(m -> ForumServiceUtils.createForumWithParentAndSubforumsUntilCertainDepthFromModel(forumDao, forumLastPostDao, forumModuleDao, forumModuleFactory, m, maxDepth)).collect(Collectors.toList()); return forums; } @Override public List<Forum> getAllowedChildForums(String parentJid, long maxDepth) { List<Forum> forums = getChildForums(parentJid, maxDepth); ImmutableList.Builder<Forum> allowedForums = ImmutableList.builder(); for (Forum forum : forums) { if (!forum.containModule(ForumModules.MEMBER)) { allowedForums.add(forum); } } return allowedForums.build(); } @Override public List<ForumWithStatus> getChildForumsWithStatus(String parentJid, String userJid, long maxDepth) { List<Forum> forums = getChildForums(parentJid, maxDepth); ImmutableList.Builder<ForumWithStatus> forumWithStatusesBuilder = ImmutableList.builder(); for (Forum forum : forums) { Stack<Forum> forumStack = new Stack<>(); forumStack.push(forum); boolean hasNewPost = false; while (!hasNewPost && !forumStack.isEmpty()) { Forum currentForum = forumStack.pop(); if (currentForum.containModule(ForumModules.THREAD)) { List<ForumThreadModel> forumThreadModels = forumThreadDao.findSortedByFiltersEq("id", "asc", "", ImmutableMap.of(ForumThreadModel_.forumJid, currentForum.getJid()), 0, -1); List<String> forumThreadJids = forumThreadModels.stream().map(t -> t.jid).collect(Collectors.toList()); List<UserItemModel> userItemModels = userItemDao.findSortedByFilters("id", "asc", "", ImmutableMap.of(UserItemModel_.userJid, userJid), ImmutableMap.of(UserItemModel_.itemJid, forumThreadJids), 0, -1); ImmutableMap.Builder<String, UserItemModel> mapItemJidToUserItemModelBuilder = ImmutableMap.builder(); for (UserItemModel userItemModel : userItemModels) { mapItemJidToUserItemModelBuilder.put(userItemModel.itemJid, userItemModel); } Map<String, UserItemModel> mapItemJidToUserItemModel = mapItemJidToUserItemModelBuilder.build(); for (int i = 0; !hasNewPost && (i < forumThreadModels.size()); ++i) { UserItemModel userItemModel = mapItemJidToUserItemModel.get(forumThreadModels.get(i).jid); hasNewPost = (userItemModel == null) || (userItemModel.timeUpdate < forumThreadModels.get(i).timeUpdate); } } if (!hasNewPost) { for (Forum childForum : currentForum.getSubforums()) { forumStack.push(childForum); } } } forumWithStatusesBuilder.add(new ForumWithStatus(forum, hasNewPost)); } return forumWithStatusesBuilder.build(); } @Override public List<ForumWithStatus> getAllowedChildForumsWithStatus(String parentJid, String userJid, long maxDepth) { List<ForumWithStatus> forumsWithStatus = getChildForumsWithStatus(parentJid, userJid, maxDepth); List<String> forumJidsWhereIsMember = forumMemberDao.getForumJidsByJid(userJid); ImmutableList.Builder<ForumWithStatus> allowedForumsWithStatus = ImmutableList.builder(); for (ForumWithStatus forumWithStatus : forumsWithStatus) { if (forumWithStatus.getForum().containOrInheritModule(ForumModules.MEMBER)) { Forum forumWithMember = forumWithStatus.getForum().getForumOrParentWithModule(ForumModules.MEMBER); if (forumJidsWhereIsMember.contains(forumWithMember.getJid())) { allowedForumsWithStatus.add(forumWithStatus); } } else { allowedForumsWithStatus.add(forumWithStatus); } } return allowedForumsWithStatus.build(); } @Override public Forum findForumById(long forumId) throws ForumNotFoundException { ForumModel intendedForumModel = forumDao.findById(forumId); if (intendedForumModel == null) { throw new ForumNotFoundException("Forum Not Found."); } return ForumServiceUtils.createForumWithParentAndSubforumsUntilCertainDepthFromModel(forumDao, forumLastPostDao, forumModuleDao, forumModuleFactory, intendedForumModel, 1); } @Override public Forum findForumByJid(String forumJid) { ForumModel intendedForumModel = forumDao.findByJid(forumJid); return ForumServiceUtils.createForumWithParentAndSubforumsUntilCertainDepthFromModel(forumDao, forumLastPostDao, forumModuleDao, forumModuleFactory, intendedForumModel, 1); } @Override public void createForum(Forum parentForum, String name, String description, String userJid, String userIpAddress) { ForumModel forumModel = new ForumModel(); if (parentForum == null) { forumModel.parentJid = ""; } else { forumModel.parentJid = parentForum.getJid(); } forumModel.name = name; forumModel.description = description; forumDao.persist(forumModel, userJid, userIpAddress); ForumServiceUtils.updateForumAndParents(forumDao, parentForum, userJid, userIpAddress); } @Override public void updateForum(Forum forum, Forum parentForum, String name, String description, String userJid, String userIpAddress) { ForumModel forumModel = forumDao.findByJid(forum.getJid()); if (parentForum == null) { forumModel.parentJid = ""; } else { forumModel.parentJid = parentForum.getJid(); } forumModel.name = name; forumModel.description = description; forumDao.edit(forumModel, userJid, userIpAddress); ForumServiceUtils.updateForumAndParents(forumDao, forum.getParentForum(), userJid, userIpAddress); ForumServiceUtils.updateForumAndParents(forumDao, parentForum, userJid, userIpAddress); } @Override public void updateForumModuleConfiguration(String forumJid, Collection<ForumModule> forumModules, String userJid, String userIpAddress) { for (ForumModule forumModule : forumModules) { ForumModuleModel forumModuleModel = forumModuleDao.findInForumByName(forumJid, forumModule.getType().name()); forumModuleModel.config = forumModule.toJSONString(); forumModuleDao.edit(forumModuleModel, userJid, userIpAddress); } ForumModel forumModel = forumDao.findByJid(forumJid); forumDao.edit(forumModel, userJid, userIpAddress); } }