package fi.otavanopisto.muikku.plugins.forum; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.logging.Logger; import javax.inject.Inject; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Entities.EscapeMode; import org.jsoup.safety.Cleaner; import org.jsoup.safety.Whitelist; import fi.otavanopisto.muikku.controller.ResourceRightsController; import fi.otavanopisto.muikku.model.security.ResourceRights; import fi.otavanopisto.muikku.model.users.UserEntity; import fi.otavanopisto.muikku.model.workspace.WorkspaceEntity; import fi.otavanopisto.muikku.plugins.forum.dao.EnvironmentForumAreaDAO; import fi.otavanopisto.muikku.plugins.forum.dao.ForumAreaDAO; import fi.otavanopisto.muikku.plugins.forum.dao.ForumAreaGroupDAO; import fi.otavanopisto.muikku.plugins.forum.dao.ForumMessageDAO; import fi.otavanopisto.muikku.plugins.forum.dao.ForumThreadDAO; import fi.otavanopisto.muikku.plugins.forum.dao.ForumThreadReplyDAO; import fi.otavanopisto.muikku.plugins.forum.dao.WorkspaceForumAreaDAO; import fi.otavanopisto.muikku.plugins.forum.model.EnvironmentForumArea; import fi.otavanopisto.muikku.plugins.forum.model.ForumArea; import fi.otavanopisto.muikku.plugins.forum.model.ForumAreaGroup; import fi.otavanopisto.muikku.plugins.forum.model.ForumMessage; import fi.otavanopisto.muikku.plugins.forum.model.ForumThread; import fi.otavanopisto.muikku.plugins.forum.model.ForumThreadReply; import fi.otavanopisto.muikku.plugins.forum.model.WorkspaceForumArea; import fi.otavanopisto.muikku.schooldata.entity.User; import fi.otavanopisto.muikku.session.SessionController; import fi.otavanopisto.muikku.users.UserController; import fi.otavanopisto.muikku.users.UserEntityController; public class ForumController { @Inject private Logger logger; @Inject private SessionController sessionController; @Inject private EnvironmentForumAreaDAO environmentForumAreaDAO; @Inject private WorkspaceForumAreaDAO workspaceForumAreaDAO; @Inject private ForumAreaDAO forumAreaDAO; @Inject private ForumThreadDAO forumThreadDAO; @Inject private ForumMessageDAO forumMessageDAO; @Inject private ForumAreaGroupDAO forumAreaGroupDAO; @Inject private ForumThreadReplyDAO forumThreadReplyDAO; @Inject private ResourceRightsController resourceRightsController; @Inject private UserEntityController userEntityController; @Inject private UserController userController; private String clean(String html) { Document doc = Jsoup.parse(html); doc = new Cleaner(Whitelist.relaxed().addAttributes("a", "target")).clean(doc); doc.select("a[target]").attr("rel", "noopener noreferer"); doc.outputSettings().escapeMode(EscapeMode.xhtml); return doc.body().html(); } public ForumArea getForumArea(Long forumAreaId) { return forumAreaDAO.findById(forumAreaId); } public ForumThread getForumThread(Long threadId) { return forumThreadDAO.findById(threadId); } public ForumThreadReply getForumThreadReply(Long threadReplyId) { return forumThreadReplyDAO.findById(threadReplyId); } public EnvironmentForumArea createEnvironmentForumArea(String name, String description, Long groupId) { UserEntity owner = sessionController.getLoggedUserEntity(); ResourceRights rights = resourceRightsController.create(); ForumAreaGroup group = groupId != null ? findForumAreaGroup(groupId) : null; EnvironmentForumArea forumArea = environmentForumAreaDAO.create(name, description, group, false, owner, rights); return forumArea; } public WorkspaceForumArea createWorkspaceForumArea(WorkspaceEntity workspace, String name, String description, Long groupId) { UserEntity owner = sessionController.getLoggedUserEntity(); ResourceRights rights = resourceRightsController.create(); ForumAreaGroup group = groupId != null ? findForumAreaGroup(groupId) : null; WorkspaceForumArea forumArea = workspaceForumAreaDAO.create(workspace, name, description, group, false, owner, rights); return forumArea; } public void copyWorkspaceForumAreas(WorkspaceEntity sourceWorkspace, WorkspaceEntity targetWorkspace) { List<WorkspaceForumArea> forumAreas = listWorkspaceForumAreas(sourceWorkspace); for (WorkspaceForumArea forumArea : forumAreas) { createWorkspaceForumArea(targetWorkspace, forumArea.getName(), forumArea.getDescription(), forumArea.getGroup() == null ? null : forumArea.getGroup().getId()); } } public ForumArea updateForumAreaName(ForumArea forumArea, String name) { return forumAreaDAO.updateForumArea(forumArea, name); } public ForumArea updateForumAreaDescription(ForumArea forumArea, String description) { return forumAreaDAO.updateDescription(forumArea, description); } public void archiveArea(ForumArea forumArea) { forumAreaDAO.updateArchived(forumArea, true); } public void deleteArea(ForumArea forumArea) { forumAreaDAO.delete(forumArea); } public ForumArea findForumAreaById(Long forumAreaId) { return forumAreaDAO.findById(forumAreaId); } public ForumAreaGroup findForumAreaGroup(Long groupId) { return forumAreaGroupDAO.findById(groupId); } public ForumThread createForumThread(ForumArea forumArea, String title, String message, Boolean sticky, Boolean locked) { return forumThreadDAO.create(forumArea, title, clean(message), sessionController.getLoggedUserEntity(), sticky, locked); } public void archiveThread(ForumThread thread) { List<ForumThreadReply> replies = forumThreadReplyDAO.listByForumThread(thread); for (ForumThreadReply reply : replies) { forumThreadReplyDAO.updateArchived(reply, true); } forumThreadDAO.updateArchived(thread, true); } public void deleteThread(ForumThread thread) { List<ForumThreadReply> replies = forumThreadReplyDAO.listByForumThread(thread); for (ForumThreadReply reply : replies) { forumThreadReplyDAO.updateParentReply(reply, null); } for (ForumThreadReply reply : replies) { forumThreadReplyDAO.delete(reply); } forumThreadDAO.delete(thread); } public ForumThreadReply createForumThreadReply(ForumThread thread, String message, ForumThreadReply parentReply) { if (thread.getLocked()) { logger.severe("Tried to create a forum thread reply for locked thread"); return null; } else { ForumThreadReply reply = forumThreadReplyDAO.create(thread.getForumArea(), thread, clean(message), sessionController.getLoggedUserEntity(), parentReply); forumThreadDAO.updateThreadUpdated(thread, reply.getCreated()); return reply; } } public void archiveReply(ForumThreadReply reply) { forumThreadReplyDAO.updateArchived(reply, true); } public void updateReplyDeleted(ForumThreadReply reply, boolean deleted) { forumThreadReplyDAO.updateDeleted(reply, deleted); } public void deleteReply(ForumThreadReply reply) { forumThreadReplyDAO.delete(reply); } public List<EnvironmentForumArea> listEnvironmentForums() { return sessionController.filterResources( environmentForumAreaDAO.listAllNonArchived(), ForumResourcePermissionCollection.FORUM_ACCESSENVIRONMENTFORUM); } public List<WorkspaceForumArea> listWorkspaceForumAreas(WorkspaceEntity workspaceEntity) { return workspaceForumAreaDAO.listByWorkspaceEntity(workspaceEntity); } public List<ForumThread> listForumThreads(ForumArea forumArea, int firstResult, int maxResults) { return listForumThreads(forumArea, firstResult, maxResults, false); } public List<ForumThread> listForumThreads(ForumArea forumArea, int firstResult, int maxResults, boolean includeArchived) { return forumThreadDAO.listByForumAreaOrdered(forumArea, firstResult, maxResults, includeArchived); } public List<ForumThreadReply> listForumThreadReplies(ForumThread forumThread, Integer firstResult, Integer maxResults) { return listForumThreadReplies(forumThread, firstResult, maxResults, false); } public List<ForumThreadReply> listForumThreadReplies(ForumThread forumThread, Integer firstResult, Integer maxResults, boolean includeArchived) { return forumThreadReplyDAO.listByForumThread(forumThread, firstResult, maxResults, includeArchived); } public List<ForumThread> listLatestForumThreads(int firstResult, int maxResults) { List<EnvironmentForumArea> environmentForums = listEnvironmentForums(); // List<WorkspaceForumArea> workspaceForums = listCourseForums(); List<ForumArea> forumAreas = new ArrayList<ForumArea>(); // TODO: This could use some optimization for (EnvironmentForumArea ef : environmentForums) { forumAreas.add(ef); } // for (WorkspaceForumArea wf : workspaceForums) { // forumAreas.add(wf); // } List<ForumThread> threads; if (!forumAreas.isEmpty()) threads = forumThreadDAO.listLatestOrdered(forumAreas, firstResult, maxResults); else threads = new ArrayList<ForumThread>(); return threads; } public List<ForumThread> listLatestForumThreadsFromWorkspace(WorkspaceEntity workspaceEntity, Integer firstResult, Integer maxResults) { List<WorkspaceForumArea> workspaceForums = listWorkspaceForumAreas(workspaceEntity); List<ForumArea> forumAreas = new ArrayList<ForumArea>(); // TODO: This could use some optimization for (WorkspaceForumArea wf : workspaceForums) { forumAreas.add(wf); } List<ForumThread> threads; if (!forumAreas.isEmpty()) threads = forumThreadDAO.listLatestOrdered(forumAreas, firstResult, maxResults); else threads = new ArrayList<ForumThread>(); return threads; } public UserEntity findUserEntity(Long userEntityId) { return userEntityController.findUserEntityById(userEntityId); } public User findUser(UserEntity userEntity) { return userController.findUserByUserEntityDefaults(userEntity); } public boolean getUserHasPicture(UserEntity userEntity) { return false; // TODO } public ForumThreadReply getLatestReply(ForumThread thread) { return forumThreadReplyDAO.findLatestReplyByThread(thread); } public ForumMessage getLatestMessage(ForumArea area) { return forumMessageDAO.findLatestMessageByArea(area); } public Long getThreadReplyCount(ForumThread thread) { return forumThreadReplyDAO.countByThread(thread); } public Long getThreadCount(ForumArea area) { return forumThreadDAO.countByArea(area); } public Long getMessageCount(ForumArea area) { return forumMessageDAO.countByArea(area); } public void archiveMessage(ForumMessage message) { forumMessageDAO.archive(message); if (message instanceof ForumThreadReply) { ForumThreadReply reply = (ForumThreadReply) message; ForumThreadReply latestReply = getLatestReply(reply.getThread()); if (latestReply != null) forumThreadDAO.updateThreadUpdated(reply.getThread(), latestReply.getCreated()); else forumThreadDAO.updateThreadUpdated(reply.getThread(), reply.getThread().getCreated()); } } public void updateForumThread(ForumThread thread, String title, String message, Boolean sticky, Boolean locked) { UserEntity user = sessionController.getLoggedUserEntity(); forumThreadDAO.update(thread, title, clean(message), sticky, locked, new Date(), user); } public void updateForumThreadReply(ForumThreadReply reply, String message) { UserEntity user = sessionController.getLoggedUserEntity(); forumThreadReplyDAO.update(reply, clean(message), new Date(), user); } public List<ForumAreaGroup> listForumAreaGroups() { return forumAreaGroupDAO.listUnArchived(); } public ForumAreaGroup createForumAreaGroup(String name) { return forumAreaGroupDAO.create(name, Boolean.FALSE); } public void archiveAreaGroup(ForumAreaGroup forumAreaGroup) { forumAreaGroupDAO.updateArchived(forumAreaGroup, true); } public void deleteAreaGroup(ForumAreaGroup forumAreaGroup) { forumAreaGroupDAO.delete(forumAreaGroup); } public List<ForumMessage> listMessagesByWorkspace(WorkspaceEntity workspace) { return forumMessageDAO.listByWorkspace(workspace); } public List<ForumMessage> listByContributingUser(UserEntity userEntity) { return forumMessageDAO.listByContributingUser(userEntity); } public Long countUserEntityWorkspaceMessages(WorkspaceEntity workspaceEntity, UserEntity creator) { if (workspaceEntity == null) { logger.severe("Attempt to call countUserEntityWorkspaceMessages with null workspaceEntity"); return 0l; } if (creator == null) { logger.severe("Attempt to call countUserEntityWorkspaceMessages with null creator"); return 0l; } return forumMessageDAO.countByWorkspaceEntityAndCreator(workspaceEntity.getId(), creator.getId()); } public ForumMessage findUserEntitysLatestWorkspaceMessage(WorkspaceEntity workspaceEntity, UserEntity creator) { if (workspaceEntity == null) { logger.severe("Attempt to call countUserEntityWorkspaceMessages with null workspaceEntity"); return null; } if (creator == null) { logger.severe("Attempt to call countUserEntityWorkspaceMessages with null creator"); return null; } List<ForumMessage> messages = forumMessageDAO.listByWorkspaceEntityAndCreatorOrderByCreated(workspaceEntity.getId(), creator.getId(), 0, 1); if (messages.size() == 1) { return messages.get(0); } return null; } }