Java tutorial
/*************************************************************************** * Copyright (C) 2003-2007 eXo Platform SAS. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Affero General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see<http://www.gnu.org/licenses/>. ***************************************************************************/ package org.exoplatform.forum.service.impl; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStream; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.Collections; import java.util.Date; import java.util.GregorianCalendar; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Queue; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.regex.Pattern; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; import javax.jcr.ImportUUIDBehavior; import javax.jcr.Node; import javax.jcr.NodeIterator; import javax.jcr.PathNotFoundException; import javax.jcr.RepositoryException; import javax.jcr.Session; import javax.jcr.nodetype.ConstraintViolationException; import javax.jcr.observation.Event; import javax.jcr.observation.ObservationManager; import javax.jcr.query.Query; import javax.jcr.query.QueryManager; import javax.jcr.query.QueryResult; import javax.transaction.NotSupportedException; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.apache.commons.lang.StringEscapeUtils; import org.apache.commons.lang.StringUtils; import org.exoplatform.commons.utils.ActivityTypeUtils; import org.exoplatform.commons.utils.CommonsUtils; import org.exoplatform.commons.utils.ISO8601; import org.exoplatform.container.ExoContainer; import org.exoplatform.container.ExoContainerContext; import org.exoplatform.container.component.ComponentPlugin; import org.exoplatform.forum.common.CommonUtils; import org.exoplatform.forum.common.TransformHTML; import org.exoplatform.forum.common.UserHelper; import org.exoplatform.forum.common.conf.RoleRulesPlugin; import org.exoplatform.forum.common.jcr.JCRSessionManager; import org.exoplatform.forum.common.jcr.JCRTask; import org.exoplatform.forum.common.jcr.KSDataLocation; import org.exoplatform.forum.common.jcr.KSDataLocation.Locations; import org.exoplatform.forum.common.jcr.PropertyReader; import org.exoplatform.forum.common.jcr.SessionManager; import org.exoplatform.forum.service.BufferAttachment; import org.exoplatform.forum.service.Category; import org.exoplatform.forum.service.DataStorage; import org.exoplatform.forum.service.EmailNotifyPlugin; import org.exoplatform.forum.service.Forum; import org.exoplatform.forum.service.ForumAdministration; import org.exoplatform.forum.service.ForumAttachment; import org.exoplatform.forum.service.ForumEventQuery; import org.exoplatform.forum.service.ForumLinkData; import org.exoplatform.forum.service.ForumNodeTypes; import org.exoplatform.forum.service.ForumPageList; import org.exoplatform.forum.service.ForumPrivateMessage; import org.exoplatform.forum.service.ForumSearchResult; import org.exoplatform.forum.service.ForumServiceUtils; import org.exoplatform.forum.service.ForumStatistic; import org.exoplatform.forum.service.ForumSubscription; import org.exoplatform.forum.service.InitializeForumPlugin; import org.exoplatform.forum.service.JCRPageList; import org.exoplatform.forum.service.LazyPageList; import org.exoplatform.forum.service.MessageBuilder; import org.exoplatform.forum.service.Post; import org.exoplatform.forum.service.PruneSetting; import org.exoplatform.forum.service.SendMessageInfo; import org.exoplatform.forum.service.SortSettings; import org.exoplatform.forum.service.SortSettings.Direction; import org.exoplatform.forum.service.SortSettings.SortField; import org.exoplatform.forum.service.Tag; import org.exoplatform.forum.service.Topic; import org.exoplatform.forum.service.TopicListAccess; import org.exoplatform.forum.service.UserProfile; import org.exoplatform.forum.service.Utils; import org.exoplatform.forum.service.Watch; import org.exoplatform.forum.service.conf.CategoryData; import org.exoplatform.forum.service.conf.ForumData; import org.exoplatform.forum.service.conf.ForumInitialDataPlugin; import org.exoplatform.forum.service.conf.PostData; import org.exoplatform.forum.service.conf.TopicData; import org.exoplatform.forum.service.conf.UpdateUserProfileJob; import org.exoplatform.forum.service.filter.model.CategoryFilter; import org.exoplatform.forum.service.filter.model.ForumFilter; import org.exoplatform.forum.service.impl.model.PostFilter; import org.exoplatform.forum.service.impl.model.TopicFilter; import org.exoplatform.forum.service.jcr.listener.CalculateModeratorEventListener; import org.exoplatform.forum.service.jcr.listener.DeletedUserCalculateEventListener; import org.exoplatform.forum.service.jcr.listener.StatisticEventListener; import org.exoplatform.forum.service.search.UnifiedSearchOrder; import org.exoplatform.forum.service.user.AutoPruneJob; import org.exoplatform.management.annotations.Managed; import org.exoplatform.management.annotations.ManagedDescription; import org.exoplatform.management.jmx.annotations.NameTemplate; import org.exoplatform.management.jmx.annotations.Property; import org.exoplatform.services.jcr.RepositoryService; import org.exoplatform.services.jcr.config.RepositoryConfigurationException; import org.exoplatform.services.jcr.config.RepositoryEntry; import org.exoplatform.services.jcr.ext.common.SessionProvider; import org.exoplatform.services.jcr.impl.core.query.QueryImpl; import org.exoplatform.services.jcr.util.IdGenerator; import org.exoplatform.services.log.ExoLogger; import org.exoplatform.services.log.Log; import org.exoplatform.services.mail.Message; import org.exoplatform.services.organization.User; import org.exoplatform.services.scheduler.JobInfo; import org.exoplatform.services.scheduler.JobSchedulerService; import org.exoplatform.services.scheduler.PeriodInfo; import org.exoplatform.ws.frameworks.cometd.ContinuationService; import org.exoplatform.ws.frameworks.json.impl.JsonGeneratorImpl; import org.exoplatform.ws.frameworks.json.value.JsonValue; import org.quartz.JobDataMap; import org.w3c.dom.Document; import com.sun.syndication.feed.synd.SyndContent; import com.sun.syndication.feed.synd.SyndContentImpl; import com.sun.syndication.feed.synd.SyndEntry; import com.sun.syndication.feed.synd.SyndEntryImpl; import com.sun.syndication.feed.synd.SyndFeed; import com.sun.syndication.feed.synd.SyndFeedImpl; import com.sun.syndication.io.FeedException; import com.sun.syndication.io.SyndFeedOutput; /** * JCR implementation of Forum Data Storage * * @author hung.nguyen@exoplatform.com * @author tu.duy@exoplatform.com * @version $Revision$ */ @Managed @NameTemplate({ @Property(key = "service", value = "forum"), @Property(key = "view", value = "storage") }) @ManagedDescription("Data Storage for this forum") @SuppressWarnings("unchecked") public class JCRDataStorage implements DataStorage, ForumNodeTypes { private static final Log LOG = ExoLogger.getLogger(JCRDataStorage.class); private Map<String, String> serverConfig = new HashMap<String, String>(); private Map<String, Object> infoMap = new HashMap<String, Object>(); final Queue<SendMessageInfo> pendingMessagesQueue = new ConcurrentLinkedQueue<SendMessageInfo>(); private List<RoleRulesPlugin> rulesPlugins = new ArrayList<RoleRulesPlugin>(); private List<InitializeForumPlugin> defaultPlugins = new ArrayList<InitializeForumPlugin>(); private List<ForumInitialDataPlugin> dataPlugins = new ArrayList<ForumInitialDataPlugin>(); private Map<String, Integer> updatingView = new ConcurrentHashMap<String, Integer>(); private Map<String, List<String>> updatingRead = new ConcurrentHashMap<String, List<String>>(); private SessionManager sessionManager; private KSDataLocation dataLocator; private String repository; private String workspace; private static final Pattern HIGHLIHT_PATTERN = Pattern.compile("(.*)<strong>(.*)</strong>(.*)"); private DataStorage cachedStorage; public JCRDataStorage() { } public JCRDataStorage(KSDataLocation dataLocator) { setDataLocator(dataLocator); } public DataStorage getCachedDataStorage() { if (cachedStorage == null) { cachedStorage = CommonsUtils.getService(DataStorage.class); } return cachedStorage; } @Managed @ManagedDescription("repository for forum storage") public String getRepository() { return repository; } @Managed @ManagedDescription("workspace for the forum storage") public String getWorkspace() { return workspace; } @Managed @ManagedDescription("data path for forum storage") public String getPath() { return dataLocator.getForumHomeLocation(); } protected Node getForumHomeNode(SessionProvider sProvider) throws Exception { String path = dataLocator.getForumHomeLocation(); return sessionManager.getSession(sProvider).getRootNode().getNode(path); } private Node getForumSystemHome(SessionProvider sProvider) throws Exception { String path = dataLocator.getForumSystemLocation(); return sessionManager.getSession(sProvider).getRootNode().getNode(path); } private Node getBanIPHome(SessionProvider sProvider) throws Exception { String path = dataLocator.getBanIPLocation(); return sessionManager.getSession(sProvider).getRootNode().getNode(path); } protected Node getStatisticHome(SessionProvider sProvider) throws Exception { String path = dataLocator.getStatisticsLocation(); return sessionManager.getSession(sProvider).getRootNode().getNode(path); } private Node getForumStatisticsNode(SessionProvider sProvider) throws Exception { String path = dataLocator.getForumStatisticsLocation(); return sessionManager.getSession(sProvider).getRootNode().getNode(path); } private Node getAdminHome(SessionProvider sProvider) throws Exception { String path = dataLocator.getAdministrationLocation(); return sessionManager.getSession(sProvider).getRootNode().getNode(path); } protected Node getUserProfileHome(SessionProvider sProvider) throws Exception { String path = dataLocator.getUserProfilesLocation(); return sessionManager.getSession(sProvider).getRootNode().getNode(path); } protected Node getUserProfileNode(SessionProvider sProvider, String userId) throws Exception { StringBuffer path = new StringBuffer(dataLocator.getUserProfilesLocation()).append("/").append(userId); return sessionManager.getSession(sProvider).getRootNode().getNode(path.toString()); } private Node getUserProfileHome() throws Exception { return getNodeAt(dataLocator.getUserProfilesLocation()); } private Node getCategoryHome(SessionProvider sProvider) throws Exception { String path = dataLocator.getForumCategoriesLocation(); return sessionManager.getSession(sProvider).getRootNode().getNode(path); } private Node getTagHome(SessionProvider sProvider) throws Exception { String path = dataLocator.getTagsLocation(); return sessionManager.getSession(sProvider).getRootNode().getNode(path); } private Node getKSUserAvatarHomeNode() throws Exception { return getNodeAt(dataLocator.getAvatarsLocation()); } private Node getForumBanNode(SessionProvider sProvider) throws Exception { String path = dataLocator.getForumBanIPLocation(); return sessionManager.getSession(sProvider).getRootNode().getNode(path); } private Node getBBCodesHome(SessionProvider sProvider) throws Exception { String path = dataLocator.getBBCodesLocation(); return sessionManager.getSession(sProvider).getRootNode().getNode(path); } /** * Get a Node by path using the current session of {@link JCRSessionManager}.<br/> * Note that a session must have been initalized by {@link JCRSessionManager#openSession() before calling this method * @param relPath path relative to root node of the workspace * @return JCR node located at relPath relative path from root node of the current workspace */ private Node getNodeAt(String relPath) throws Exception { return sessionManager.getCurrentSession().getRootNode().getNode(relPath); } private Node getNodeAt(SessionProvider sProvider, String relPath) throws Exception { if (relPath.indexOf(CommonUtils.SLASH) == 0) { relPath = relPath.substring(1); } else if (relPath.indexOf(Utils.CATEGORY) == 0) { relPath = dataLocator.getForumCategoriesLocation() + CommonUtils.SLASH + relPath; } return sessionManager.getSession(sProvider).getRootNode().getNode(relPath); } public void addPlugin(ComponentPlugin plugin) throws Exception { try { if (plugin instanceof EmailNotifyPlugin) { serverConfig = ((EmailNotifyPlugin) plugin).getServerConfiguration(); } } catch (Exception e) { LOG.error("Failed to add plugin", e); } } public void addRolePlugin(ComponentPlugin plugin) throws Exception { if (plugin instanceof RoleRulesPlugin) { rulesPlugins.add((RoleRulesPlugin) plugin); } } public void addInitialDefaultDataPlugin(ComponentPlugin plugin) throws Exception { if (plugin instanceof InitializeForumPlugin) { defaultPlugins.add((InitializeForumPlugin) plugin); } } public void addInitialDataPlugin(ComponentPlugin plugin) throws Exception { if (plugin instanceof ForumInitialDataPlugin) { dataPlugins.add((ForumInitialDataPlugin) plugin); } } public void addDeletedUserCalculateListener() { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { Node profileHome = getUserProfileHome(sProvider); if (profileHome.hasNode(Utils.USER_PROFILE_DELETED)) { deletedUserCalculateListener(profileHome.getNode(Utils.USER_PROFILE_DELETED)); } } catch (Exception e) { LOG.error("Can not add caculation listerner for deleted user", e); } finally { sProvider.close(); } } protected void deletedUserCalculateListener(Node node) throws Exception { try { ObservationManager observation = node.getSession().getWorkspace().getObservationManager(); DeletedUserCalculateEventListener deleteUserListener = new DeletedUserCalculateEventListener(); observation.addEventListener(deleteUserListener, Event.NODE_ADDED | Event.NODE_REMOVED, node.getPath(), false, new String[] { EXO_FORUM_USER_PROFILE }, null, false); } catch (Exception e) { LOG.error("Can not add listener for node " + node.getName(), e); } } public void initCategoryListener() { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { ObservationManager observation = sessionManager.getSession(sProvider).getWorkspace() .getObservationManager(); // CalculateModeratorEventListener moderatorListener = new CalculateModeratorEventListener(); observation.addEventListener(moderatorListener, Event.NODE_ADDED | Event.NODE_REMOVED | Event.PROPERTY_CHANGED, "/", true, null, new String[] { EXO_CATEGORY_HOME, EXO_FORUM_CATEGORY, EXO_FORUM }, false); // statistic listener StatisticEventListener sListener = new StatisticEventListener(); observation.addEventListener(sListener, Event.NODE_ADDED | Event.NODE_REMOVED, "/", true, null, new String[] { EXO_FORUM, EXO_TOPIC }, false); } catch (Exception e) { LOG.error("Failed to init category listenner", e); } finally { sProvider.close(); } } private NodeIterator getNodeIteratorAutoPruneSetting(SessionProvider sProvider, boolean isActive) throws Exception { StringBuilder pathQuery = new StringBuilder("SELECT * FROM ").append(EXO_PRUNE_SETTING); if (isActive) { pathQuery.append(" WHERE ").append(EXO_IS_ACTIVE).append("='true'"); } else { pathQuery.append(" ORDER BY ").append(EXO_ID).append(ASC); } return getNodeIteratorBySQLQuery(sProvider, pathQuery.toString(), 0, 0, false); } public void initAutoPruneSchedules() { RepositoryService repositoryService = getDataLocation().getRepositoryService(); List<RepositoryEntry> entries = repositoryService.getConfig().getRepositoryConfigurations(); String currentRepo = null; try { currentRepo = repositoryService.getCurrentRepository().getConfiguration().getName(); for (RepositoryEntry repositoryEntry : entries) { repositoryService.setCurrentRepositoryName(repositoryEntry.getName()); SessionProvider sProvider = SessionProvider.createSystemProvider(); try { NodeIterator iter = getNodeIteratorAutoPruneSetting(sProvider, true); while (iter.hasNext()) { addOrRemoveSchedule(getPruneSetting(iter.nextNode())); } } catch (Exception e) { if (LOG.isDebugEnabled()) { LOG.debug("Could not perform pruning!", e); } } finally { sProvider.close(); } } } catch (Exception e) { LOG.error("Repository is error!", e); } if (currentRepo != null) { try { repositoryService.setCurrentRepositoryName(currentRepo); } catch (RepositoryConfigurationException e) { LOG.error("Could not reset current repository's name", e); } } } public boolean isAdminRole(String userName) throws Exception { return isAdminRole(CommonUtils.createSystemProvider(), userName); } private boolean isAdminRole(SessionProvider sProvider, String userName) throws Exception { if (Utils.isEmpty(userName) || UserProfile.USER_GUEST.equals(userName)) { return false; } if (isAdminRoleConfig(userName)) { return true; } else { Node userHome = getUserProfileHome(sProvider); if (userHome.hasNode(userName)) { return (new PropertyReader(userHome.getNode(userName)).l(EXO_USER_ROLE, 2) == UserProfile.ADMIN); } } return false; } public boolean isAdminRoleConfig(String userName) throws Exception { if (Utils.isEmpty(userName)) { return false; } for (int i = 0; i < rulesPlugins.size(); ++i) { List<String> list = new ArrayList<String>(); list.addAll(rulesPlugins.get(i).getRules(Utils.ADMIN_ROLE)); if (list.contains(userName)) return true; String[] adminrules = Utils.getStringsInList(list); if (ForumServiceUtils.hasPermission(adminrules, userName)) return true; } return false; } /** * {@inheritDoc} */ public void setDefaultAvatar(String userName) { Boolean wasReset = sessionManager.executeAndSave(new ResetAvatarTask(userName)); if (LOG.isDebugEnabled()) { LOG.debug("Avatar for user " + userName + " was " + (wasReset ? "" : "not") + " reset"); } } /** * Task that reset the user avatar * * @author <a href="mailto:patrice.lamarque@exoplatform.com">Patrice Lamarque</a> * @version $Revision$ */ public class ResetAvatarTask implements JCRTask<Boolean> { String username; public ResetAvatarTask(String username) { this.username = username; } /** * Remove the nt:file node used as avatar for the given username username is used as the name of the avatar node */ public Boolean execute(Session session) throws Exception { Boolean wasReset = false; Node ksAvatarHomnode = getKSUserAvatarHomeNode(); if (ksAvatarHomnode.hasNode(username)) { Node node = ksAvatarHomnode.getNode(username); if (node.isNodeType(NT_FILE)) { node.remove(); ksAvatarHomnode.save(); wasReset = true; } } return wasReset; } } /** * {@inheritDoc} */ public ForumAttachment getUserAvatar(String userName) throws Exception { ForumAttachment avatar = sessionManager.execute(new LoadAvatarTask(userName)); return avatar; } /** * Loads an avatar for a given user * * @author <a href="mailto:patrice.lamarque@exoplatform.com">Patrice Lamarque</a> * @version $Revision$ */ class LoadAvatarTask implements JCRTask<ForumAttachment> { String username; public LoadAvatarTask(String username) { this.username = username; } /** * Load the avatar file from JCR. The username is the name of a nt:file node looked inside the avatar home * * @see JCRDataStorage#getKSUserAvatarHomeNode() */ public ForumAttachment execute(Session session) throws Exception { Node ksAvatarHomnode = getKSUserAvatarHomeNode(); if (ksAvatarHomnode.hasNode(username)) { return getAttachment(ksAvatarHomnode.getNode(username)); } else { return null; } } } /** * {@inheritDoc} */ public void saveUserAvatar(String userId, ForumAttachment fileAttachment) throws Exception { Boolean wasNew = sessionManager.executeAndSave(new SaveAvatarTask(userId, fileAttachment)); if (LOG.isDebugEnabled()) { LOG.error("avatar was " + ((wasNew) ? "added" : "updated") + " for user " + userId + ": " + fileAttachment); } } /** * Unit of work for saving an Avatar * * @author <a href="mailto:patrice.lamarque@exoplatform.com">Patrice Lamarque</a> * @version $Revision$ */ class SaveAvatarTask implements JCRTask<Boolean> { String userId; ForumAttachment fileAttachment; /** * @param userId * owner of the avatar * @param fileAttachment * file for the avatar picture to save */ public SaveAvatarTask(String userId, ForumAttachment fileAttachment) { this.userId = userId; this.fileAttachment = fileAttachment; } /** * Create or update an nt:file node represented by the ForumAttachement. All permissions are granted to any on that file (!) * * @param session * unused */ public Boolean execute(Session session) throws Exception { Node ksAvatarHomnode = getKSUserAvatarHomeNode(); Node avatarNode = null; Boolean wasNew = false; if (ksAvatarHomnode.hasNode(userId)) { avatarNode = ksAvatarHomnode.getNode(userId); } else { avatarNode = ksAvatarHomnode.addNode(userId, NT_FILE); wasNew = true; } ForumServiceUtils.reparePermissions(avatarNode, "any"); Node nodeContent = null; if (avatarNode.hasNode(JCR_CONTENT)) { nodeContent = avatarNode.getNode(JCR_CONTENT); } else { nodeContent = avatarNode.addNode(JCR_CONTENT, NT_RESOURCE); } nodeContent.setProperty(JCR_MIME_TYPE, fileAttachment.getMimeType()); nodeContent.setProperty(JCR_DATA, fileAttachment.getInputStream()); nodeContent.setProperty(JCR_LAST_MODIFIED, Calendar.getInstance().getTimeInMillis()); return wasNew; } } public void saveForumAdministration(ForumAdministration forumAdministration) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); try { Node administrationHome = getAdminHome(sProvider); Node forumAdminNode; try { forumAdminNode = administrationHome.getNode(Utils.FORUMADMINISTRATION); } catch (PathNotFoundException e) { forumAdminNode = administrationHome.addNode(Utils.FORUMADMINISTRATION, EXO_ADMINISTRATION); } forumAdminNode.setProperty(EXO_FORUM_SORT_BY, forumAdministration.getForumSortBy()); forumAdminNode.setProperty(EXO_FORUM_SORT_BY_TYPE, forumAdministration.getForumSortByType()); forumAdminNode.setProperty(EXO_TOPIC_SORT_BY, forumAdministration.getTopicSortBy()); forumAdminNode.setProperty(EXO_TOPIC_SORT_BY_TYPE, forumAdministration.getTopicSortByType()); forumAdminNode.setProperty(EXO_CENSORED_KEYWORD, forumAdministration.getCensoredKeyword()); forumAdminNode.setProperty(EXO_ENABLE_HEADER_SUBJECT, forumAdministration.getEnableHeaderSubject()); forumAdminNode.setProperty(EXO_HEADER_SUBJECT, forumAdministration.getHeaderSubject()); forumAdminNode.setProperty(EXO_NOTIFY_EMAIL_CONTENT, forumAdministration.getNotifyEmailContent()); forumAdminNode.setProperty(EXO_NOTIFY_EMAIL_MOVED, forumAdministration.getNotifyEmailMoved()); if (forumAdminNode.isNew()) { forumAdminNode.getSession().save(); } else { forumAdminNode.save(); } } catch (Exception e) { LOG.error("Failed to save forum administration.", e); } } public ForumAdministration getForumAdministration() throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); ForumAdministration forumAdministration = new ForumAdministration(); try { Node forumAdminNode = getAdminHome(sProvider).getNode(Utils.FORUMADMINISTRATION); PropertyReader reader = new PropertyReader(forumAdminNode); forumAdministration.setForumSortBy(reader.string(EXO_FORUM_SORT_BY)); forumAdministration.setForumSortByType(reader.string(EXO_FORUM_SORT_BY_TYPE)); forumAdministration.setTopicSortBy(reader.string(EXO_TOPIC_SORT_BY)); forumAdministration.setTopicSortByType(reader.string(EXO_TOPIC_SORT_BY_TYPE)); forumAdministration.setCensoredKeyword(reader.string(EXO_CENSORED_KEYWORD)); forumAdministration.setEnableHeaderSubject(reader.bool(EXO_ENABLE_HEADER_SUBJECT)); forumAdministration.setHeaderSubject(reader.string(EXO_HEADER_SUBJECT)); forumAdministration.setNotifyEmailContent(reader.string(EXO_NOTIFY_EMAIL_CONTENT)); forumAdministration.setNotifyEmailMoved(reader.string(EXO_NOTIFY_EMAIL_MOVED)); return forumAdministration; } catch (PathNotFoundException e) { return forumAdministration; } } public SortSettings getForumSortSettings() { SessionProvider sProvider = CommonUtils.createSystemProvider(); try { Node adminHome = getAdminHome(sProvider); if (adminHome.hasNode(Utils.FORUMADMINISTRATION)) { Node forumAdminNode = getAdminHome(sProvider).getNode(Utils.FORUMADMINISTRATION); PropertyReader reader = new PropertyReader(forumAdminNode); return new SortSettings(reader.string(EXO_FORUM_SORT_BY, SortField.ORDER.toString()), reader.string(EXO_FORUM_SORT_BY_TYPE, Direction.ASC.toString())); } else { Node forumAdminNode = getAdminHome(sProvider).addNode(Utils.FORUMADMINISTRATION, EXO_ADMINISTRATION); forumAdminNode.setProperty(EXO_FORUM_SORT_BY, SortField.ORDER.toString()); forumAdminNode.setProperty(EXO_FORUM_SORT_BY_TYPE, Direction.ASC.toString()); forumAdminNode.getSession().save(); } return new SortSettings(SortField.ORDER, Direction.ASC); } catch (Exception e) { return new SortSettings(SortField.ORDER, Direction.ASC); } } public SortSettings getTopicSortSettings() throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); try { Node forumAdminNode = getAdminHome(sProvider).getNode(Utils.FORUMADMINISTRATION); PropertyReader reader = new PropertyReader(forumAdminNode); return new SortSettings(reader.string(EXO_TOPIC_SORT_BY, SortField.LASTPOST.toString()), reader.string(EXO_TOPIC_SORT_BY_TYPE, Direction.DESC.toString())); } catch (Exception e) { Node forumAdminNode = getAdminHome(sProvider).addNode(Utils.FORUMADMINISTRATION, EXO_ADMINISTRATION); forumAdminNode.getSession().save(); } return new SortSettings(SortField.LASTPOST, Direction.DESC); } public void initDataPlugin() throws Exception { for (ForumInitialDataPlugin pln : dataPlugins) { List<ByteArrayInputStream> arrayInputStreams = pln.importData(); if (arrayInputStreams != null) { for (ByteArrayInputStream bis : arrayInputStreams) { importXML(dataLocator.getForumHomeLocation(), bis, ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW); } } } } public void initDefaultData() throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); Set<String> set = new HashSet<String>(); try { Node categoryHome = getCategoryHome(sProvider); if (categoryHome.hasNodes()) return; List<CategoryData> categories; String ct = ""; for (InitializeForumPlugin pln : defaultPlugins) { categories = pln.getForumInitialData().getCategories(); for (CategoryData categoryData : categories) { Category category = new Category(); category.setCategoryName(categoryData.getName()); category.setDescription(categoryData.getDescription()); category.setOwner(categoryData.getOwner()); this.saveCategory(category, true); List<ForumData> forums = categoryData.getForums(); for (ForumData forumData : forums) { Forum forum = new Forum(); forum.setForumName(forumData.getName()); forum.setDescription(forumData.getDescription()); forum.setOwner(forumData.getOwner()); this.saveForum(category.getId(), forum, true); List<TopicData> topics = forumData.getTopics(); for (TopicData topicData : topics) { Topic topic = new Topic(); topic.setTopicName(topicData.getName()); ct = topicData.getContent(); ct = StringUtils.replace(ct, "\\n", "<br/>"); ct = Utils.removeCharterStrange(ct); topic.setDescription(ct); topic.setOwner(topicData.getOwner()); topic.setIcon(topicData.getIcon()); this.saveTopic(category.getId(), forum.getId(), topic, true, false, new MessageBuilder()); set.add(topic.getOwner()); List<PostData> posts = topicData.getPosts(); for (PostData postData : posts) { Post post = new Post(); post.setName(postData.getName()); ct = postData.getContent(); ct = StringUtils.replace(ct, "\\n", "<br/>"); ct = Utils.removeCharterStrange(ct); post.setMessage(ct); post.setOwner(postData.getOwner()); post.setIcon(postData.getIcon()); MessageBuilder messageBuilder = new MessageBuilder(); messageBuilder.setLink("link"); this.savePost(category.getId(), forum.getId(), topic.getId(), post, true, messageBuilder); set.add(post.getOwner()); } } } } } Node forumStatisticNode = getForumStatisticsNode(sProvider); PropertyReader reader = new PropertyReader(forumStatisticNode); forumStatisticNode.setProperty(EXO_MEMBERS_COUNT, (reader.l(EXO_MEMBERS_COUNT) + set.size())); forumStatisticNode.save(); } catch (Exception e) { LOG.error("Init default data is failed!!", e); } finally { sProvider.close(); } } public List<Category> getCategories() { return getCategories(CommonUtils.EMPTY_STR); } private NodeIterator getCategories(SessionProvider sProvider, String strQuery) throws Exception { String categoryHomePath = "/" + dataLocator.getForumCategoriesLocation(); StringBuilder sqlQuery = jcrPathLikeAndNotLike(EXO_FORUM_CATEGORY, categoryHomePath); // if (!Utils.isEmpty(strQuery)) { sqlQuery.append(" AND ").append(strQuery); } // order sqlQuery.append(" ORDER BY ").append(EXO_CATEGORY_ORDER).append(ASC).append(", ").append(EXO_CREATED_DATE) .append(ASC); return getNodeIteratorBySQLQuery(sProvider, sqlQuery.toString(), 0, 0, false); } private List<Category> getCategories(String strQuery) { SessionProvider sProvider = CommonUtils.createSystemProvider(); List<Category> categories = new ArrayList<Category>(); try { NodeIterator iter = getCategories(sProvider, strQuery); while (iter.hasNext()) { Node cateNode = iter.nextNode(); try { categories.add(getCategory(cateNode)); } catch (RepositoryException e) { if (LOG.isDebugEnabled()) { LOG.debug("Failed to achieve category" + cateNode.getName(), e); } } } return categories; } catch (Exception e) { if (LOG.isDebugEnabled()) { LOG.debug("Can not get all categories.", e); } return categories; } } public Category getCategory(String categoryId) { SessionProvider sProvider = CommonUtils.createSystemProvider(); try { return getCategory(getCategoryHome(sProvider).getNode(categoryId)); } catch (Exception e) { if (LOG.isDebugEnabled()) { LOG.debug("Failed to get category, categoryId: " + categoryId, e); } return null; } } public Category getCategoryIncludedSpace() { Category category = getCategory(Utils.CATEGORY_SPACE_ID_PREFIX); if (category == null) { List<Category> categories = getCategories( new StringBuffer(EXO_INCLUDED_SPACE).append("='true'").toString()); category = (categories.size() >= 1) ? categories.get(0) : null; } return category; } public String[] getPermissionTopicByCategory(String categoryId, String type) throws Exception { String[] canCreated = new String[] { " " }; SessionProvider sProvider = CommonUtils.createSystemProvider(); try { Node cateNode = getCategoryHome(sProvider).getNode(categoryId); canCreated = new PropertyReader(cateNode).strings(type, new String[] { "" }); } catch (Exception e) { LOG.error("Failed to get permission topic by category", e); } return canCreated; } private Category getCategory(Node cateNode) throws RepositoryException { Category cat = new Category(cateNode.getName()); cat.setPath(cateNode.getPath()); PropertyReader reader = new PropertyReader(cateNode); cat.setOwner(reader.string(EXO_OWNER)); cat.setCategoryName(reader.string(EXO_NAME)); cat.setCategoryOrder(reader.l(EXO_CATEGORY_ORDER)); cat.setCreatedDate(reader.date(EXO_CREATED_DATE)); cat.setDescription(reader.string(EXO_DESCRIPTION)); cat.setModifiedBy(reader.string(EXO_MODIFIED_BY)); cat.setModifiedDate(reader.date(EXO_MODIFIED_DATE)); cat.setUserPrivate(reader.strings(EXO_USER_PRIVATE)); cat.setModerators(reader.strings(EXO_MODERATORS)); cat.setForumCount(reader.l(EXO_FORUM_COUNT)); if (cateNode.isNodeType(EXO_FORUM_WATCHING)) { cat.setEmailNotification(reader.strings(EXO_EMAIL_WATCHING)); } cat.setViewer(reader.strings(EXO_VIEWER)); cat.setCreateTopicRole(reader.strings(EXO_CREATE_TOPIC_ROLE)); cat.setPoster(reader.strings(EXO_POSTER)); cat.setIncludedSpace(reader.bool(EXO_INCLUDED_SPACE)); return cat; } public void saveCategory(Category category, boolean isNew) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); Node catNode = null; try { Node categoryHome = getCategoryHome(sProvider); if (isNew) { catNode = categoryHome.addNode(category.getId(), EXO_FORUM_CATEGORY); catNode.setProperty(EXO_ID, category.getId()); catNode.setProperty(EXO_OWNER, category.getOwner()); catNode.setProperty(EXO_CREATED_DATE, getGreenwichMeanTime()); boolean isIncludedSpace = category.isIncludedSpace() || category.getId().contains(Utils.CATEGORY_SPACE); try { catNode.setProperty(EXO_INCLUDED_SPACE, isIncludedSpace); } catch (Exception e) { catNode.addMixin("mix:forumCategory"); catNode.setProperty(EXO_INCLUDED_SPACE, isIncludedSpace); } categoryHome.getSession().save(); // addModeratorCalculateListener(catNode); } else { catNode = categoryHome.getNode(category.getId()); String[] oldcategoryMod = new PropertyReader(catNode).strings(EXO_MODERATORS, new String[] { "" }); catNode.setProperty(EXO_TEMP_MODERATORS, oldcategoryMod); } catNode.setProperty(EXO_NAME, category.getCategoryName()); catNode.setProperty(EXO_CATEGORY_ORDER, category.getCategoryOrder()); catNode.setProperty(EXO_DESCRIPTION, category.getDescription()); catNode.setProperty(EXO_MODIFIED_BY, category.getModifiedBy()); catNode.setProperty(EXO_MODIFIED_DATE, getGreenwichMeanTime()); catNode.setProperty(EXO_USER_PRIVATE, convertArray(category.getUserPrivate())); catNode.setProperty(EXO_CREATE_TOPIC_ROLE, convertArray(category.getCreateTopicRole())); catNode.setProperty(EXO_POSTER, convertArray(category.getPoster())); catNode.setProperty(EXO_VIEWER, convertArray(category.getViewer())); category.setPath(catNode.getPath()); catNode.save(); try { if ((isNew && category.getModerators().length > 0) || !isNew) { catNode.setProperty(EXO_MODERATORS, category.getModerators()); catNode.save(); } } catch (Exception e) { LOG.debug("Failed to save category moderators ", e); } } catch (Exception e) { LOG.error("Failed to save category", e); throw e; } } public void saveModOfCategory(List<String> moderatorCate, String userId, boolean isAdd) { SessionProvider sProvider = CommonUtils.createSystemProvider(); try { Node cateHome = getCategoryHome(sProvider); Node cateNode = null; boolean isAddNew; List<String> list; List<String> listTemp; for (String cateId : moderatorCate) { isAddNew = true; try { cateNode = cateHome.getNode(cateId); listTemp = Utils.valuesToList(cateNode.getProperty(EXO_MODERATORS).getValues()); list = new ArrayList<String>(); list.addAll(listTemp); if (isAdd) { if (list.isEmpty() || (list.size() == 1 && Utils.isEmpty(list.get(0)))) { list = new ArrayList<String>(); list.add(userId); } else if (!list.contains(userId)) { list.add(userId); } else { isAddNew = false; } if (isAddNew) { cateNode.setProperty(EXO_TEMP_MODERATORS, Utils.getStringsInList(listTemp)); cateNode.setProperty(EXO_MODERATORS, Utils.getStringsInList(list)); } } else { if (!list.isEmpty()) { if (list.contains(userId)) { list.remove(userId); if (list.isEmpty()) list.add(""); cateNode.setProperty(EXO_MODERATORS, Utils.getStringsInList(list));// cateNode.setProperty(EXO_TEMP_MODERATORS, Utils.getStringsInList(listTemp)); } } } } catch (Exception e) { LOG.debug("Failed to save moderater of categoryId: " + cateId, e); } } cateHome.save(); } catch (Exception e) { LOG.error("Failed to save moderator of category", e); } } public void calculateModerator(String nodePath, boolean isNew) throws Exception { try { JCRSessionManager manager = new JCRSessionManager(workspace); Session session = manager.createSession(); try { Node node = (Node) session.getItem(nodePath); if (node.isNodeType(EXO_FORUM) == false && node.isNodeType(EXO_FORUM_CATEGORY) == false) { return; } PropertyReader reader = new PropertyReader(node); String[] modTemp = reader.strings(EXO_TEMP_MODERATORS, new String[] {}); if (node.isNodeType(EXO_FORUM_CATEGORY)) { Category category = new Category(node.getName()); category.setCategoryName(reader.string(EXO_NAME)); category.setModerators(reader.strings(EXO_MODERATORS, new String[] {})); if (isNew || Utils.arraysHaveDifferentContent(modTemp, category.getModerators())) { updateModeratorInForums(node, category.getModerators()); updateUserProfileModInCategory(session, node, modTemp, category, isNew); } } else if (node.isNodeType(EXO_FORUM)) { Forum forum = new Forum(); forum.setId(node.getName()); forum.setForumName(reader.string(EXO_NAME, "")); forum.setModerators(reader.strings(EXO_MODERATORS, new String[] {})); if (isNew || Utils.arraysHaveDifferentContent(modTemp, forum.getModerators())) { String categoryId = nodePath.substring(nodePath.indexOf(Utils.CATEGORY), nodePath.lastIndexOf("/")); setModeratorForum(session, forum.getModerators(), modTemp, forum, categoryId, isNew); } } node.setProperty(EXO_TEMP_MODERATORS, new String[] {}); node.save(); } finally { session.logout(); } } catch (Exception e) { if (LOG.isDebugEnabled()) { LOG.debug("PathNotFoundException category node or forum node not found"); } } } private void updateModeratorInForums(Node cateNode, String[] moderatorCat) throws RepositoryException { NodeIterator iter = cateNode.getNodes(); List<String> list; String[] oldModeratoForums; String[] strModerators; while (iter.hasNext()) { list = new ArrayList<String>(); Node node = iter.nextNode(); if (node.isNodeType(EXO_FORUM)) { oldModeratoForums = new PropertyReader(node).strings(EXO_MODERATORS, new String[] {}); list.addAll(Arrays.asList(oldModeratoForums)); for (int i = 0; i < moderatorCat.length; i++) { if (!list.contains(moderatorCat[i])) { list.add(moderatorCat[i]); } } strModerators = Utils.getStringsInList(list); node.setProperty(EXO_MODERATORS, strModerators); node.setProperty(EXO_TEMP_MODERATORS, oldModeratoForums); } } cateNode.save(); } private void updateUserProfileModInCategory(Session session, Node catNode, String[] oldcategoryMod, Category category, boolean isNew) throws Exception { Node userProfileHomeNode = session.getRootNode().getNode(dataLocator.getUserProfilesLocation()); Node userProfileNode; String categoryId = category.getId(), cateName = category.getCategoryName(); List<String> moderators = ForumServiceUtils.getUserPermission(category.getModerators()); if (!moderators.isEmpty()) { for (String string : moderators) { try { boolean isAdd = true; userProfileNode = userProfileHomeNode.getNode(string); List<String> moderateCategory = new ArrayList<String>(); try { moderateCategory = Utils .valuesToList(userProfileNode.getProperty(EXO_MODERATE_CATEGORY).getValues()); } catch (Exception e) { if (LOG.isDebugEnabled()) { LOG.debug("Failed to get list of moderated Category", e); } } for (String string2 : moderateCategory) { if (string2.indexOf(categoryId) > 0) { isAdd = false; break; } } if (isAdd) { moderateCategory.add(cateName + "(" + categoryId); userProfileNode.setProperty(EXO_MODERATE_CATEGORY, Utils.getStringsInList(moderateCategory)); } } catch (Exception e) { if (LOG.isDebugEnabled()) { LOG.debug("Failed to get user profile ", e); } } } } if (!isNew && oldcategoryMod != null && oldcategoryMod.length > 0 && !Utils.isEmpty(oldcategoryMod[0])) { if (Utils.arraysHaveDifferentContent(oldcategoryMod, category.getModerators())) { // calculate moderator of category removed List<String> olds = new ArrayList<String>(Arrays.asList(oldcategoryMod)); String[] mods = category.getModerators(); for (int i = 0; i < mods.length; i++) { if (olds.contains(mods[i])) { olds.remove(mods[i]); } } List<String> oldmoderators = ForumServiceUtils .getUserPermission(olds.toArray(new String[olds.size()])); for (String oldUserId : oldmoderators) { if (moderators.contains(oldUserId)) continue; // edit profile of old user. userProfileNode = userProfileHomeNode.getNode(oldUserId); List<String> moderateList = new ArrayList<String>(); try { moderateList = Utils .valuesToList(userProfileNode.getProperty(EXO_MODERATE_CATEGORY).getValues()); } catch (Exception e) { if (LOG.isDebugEnabled()) { LOG.debug("Failed to get list of moderated Category", e); } } for (String string2 : moderateList) { if (string2.indexOf(categoryId) > 0) { moderateList.remove(string2); userProfileNode.setProperty(EXO_MODERATE_CATEGORY, Utils.getStringsInList(moderateList)); break; } } moderateList = Utils.valuesToList(userProfileNode.getProperty(EXO_MODERATE_FORUMS).getValues()); NodeIterator iter = catNode.getNodes(); while (iter.hasNext()) { Node node = iter.nextNode(); if (node.isNodeType(EXO_FORUM)) { for (String str : moderateList) { if (str.indexOf(node.getName()) >= 0) { moderateList.remove(str); break; } } List<String> forumMode = Utils .valuesToList(node.getProperty(EXO_MODERATORS).getValues()); List<String> forumModeTemp = new ArrayList<String>(); forumModeTemp.addAll(forumMode); for (String old : olds) { if (forumMode.contains(old)) { forumMode.remove(old); } } node.setProperty(EXO_MODERATORS, Utils.getStringsInList(forumMode)); node.setProperty(EXO_TEMP_MODERATORS, Utils.getStringsInList(forumModeTemp)); } } catNode.save(); if (moderateList.isEmpty() || (moderateList.size() == 1 && Utils.isEmpty(moderateList.get(0)))) { //hasRole == fasle or hasRole =true && is Moderator = true; if (userProfileNode.hasProperty(EXO_USER_ROLE) == false || userProfileNode .hasProperty(EXO_USER_ROLE) && userProfileNode.getProperty(EXO_USER_ROLE).getLong() == UserProfile.MODERATOR) { userProfileNode.setProperty(EXO_USER_ROLE, UserProfile.USER); userProfileNode.setProperty(EXO_USER_TITLE, Utils.USER); } } else { // moderator > 0 userProfileNode.setProperty(EXO_USER_ROLE, UserProfile.MODERATOR); userProfileNode.setProperty(EXO_USER_TITLE, Utils.MODERATOR); } userProfileNode.setProperty(EXO_MODERATE_FORUMS, Utils.getStringsInList(moderateList)); } } } if (userProfileHomeNode.isNew()) { session.save(); } else { userProfileHomeNode.save(); } } public Category removeCategory(String categoryId) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); try { Node categoryHome = getCategoryHome(sProvider); Node categoryNode = categoryHome.getNode(categoryId); Map<String, Long> userPostMap = getDeletePostByUser(sProvider, categoryNode); Category category = getCategory(categoryNode); Set<String> users = new HashSet<String>(); PropertyReader reader; try { reader = new PropertyReader(categoryNode); users.addAll(reader.list(EXO_MODERATORS, new ArrayList<String>())); categoryNode.setProperty(EXO_TEMP_MODERATORS, reader.strings(EXO_MODERATORS, new String[] { "" })); categoryNode.setProperty(EXO_MODERATORS, new String[] { "" }); NodeIterator iter = categoryNode.getNodes(); while (iter.hasNext()) { Node node = iter.nextNode(); if (node.isNodeType(EXO_FORUM)) { reader = new PropertyReader(node); users.addAll(reader.list(EXO_MODERATORS, new ArrayList<String>())); node.setProperty(EXO_TEMP_MODERATORS, reader.strings(EXO_MODERATORS, new String[] { "" })); node.setProperty(EXO_MODERATORS, new String[] { "" }); } } categoryNode.save(); } catch (Exception e) { if (LOG.isDebugEnabled()) { LOG.debug("Failed to get list of moderators", e); } } categoryNode.remove(); categoryHome.save(); addUpdateUserProfileJob(userPostMap); getTotalJobWatting(sProvider, users); return category; } catch (Exception e) { LOG.error("failed to remove category " + categoryId); return null; } } @Deprecated public List<Forum> getForums(String categoryId, String strQuery) throws Exception { return getForums(new ForumFilter(categoryId, false).strQuery(strQuery)); } @Deprecated public List<Forum> getForumSummaries(String categoryId, String strQuery) throws Exception { return getForums(new ForumFilter(categoryId, true).strQuery(strQuery)); } private List<Forum> getForumsPublic(ForumFilter filter) { StringBuilder sqlQuery = new StringBuilder(); sqlQuery.append(Utils.getSQLQueryByProperty("", EXO_IS_CLOSED, "false")) .append(Utils.getSQLQueryByProperty("", EXO_IS_LOCK, "false")); return getForums(filter, sqlQuery.toString()); } private List<Forum> getForumsOfCategoryByUser(ForumFilter filter) { try { StringBuilder sqlQuery = new StringBuilder(); if (Utils.CATEGORY_SPACE_ID_PREFIX.equals(filter.categoryId())) { if (UserProfile.USER_GUEST.equals(filter.userId())) { return new ArrayList<Forum>(); } String querySpace = Utils.buildSQLQueryForumInSpaceOfUser(filter.userId()); if (Utils.isEmpty(querySpace)) { return new ArrayList<Forum>(); } else { sqlQuery.append(querySpace); } } boolean isAdmin = getCachedDataStorage().isAdminRole(filter.userId()); if (isAdmin == false) { sqlQuery.append(" AND (").append(Utils.getSQLQueryByProperty("", EXO_IS_CLOSED, "false")) .append(" OR (").append(Utils.buildSQLByUserInfo(EXO_MODERATORS, UserHelper.getAllGroupAndMembershipOfUser(filter.userId()))) .append("))"); } return getForums(filter, sqlQuery.toString()); } catch (Exception e) { LOG.warn(String.format("Failed to get forums of category %s by user %s", filter.categoryId(), filter.userId()), e); } return new ArrayList<Forum>(); } @Override public List<Forum> getForums(ForumFilter filter) { if (Utils.isEmpty(filter.userId()) == false) { return getForumsOfCategoryByUser(filter); } else if (filter.isPublic()) { return getForumsPublic(filter); } else { return getForums(filter, filter.strQuery()); } } private List<Forum> getForums(ForumFilter filter, String strQuery) { SessionProvider sProvider = CommonUtils.createSystemProvider(); try { SortSettings sort = getForumSortSettings(); SortField orderBy = sort.getField(); Direction orderType = sort.getDirection(); Node catNode = getCategoryHome(sProvider).getNode(filter.categoryId()); StringBuilder sqlQuery = jcrPathLikeAndNotLike(EXO_FORUM, catNode.getPath()); if (!Utils.isEmpty(strQuery)) { sqlQuery.append(" AND ").append(strQuery); } // order sqlQuery.append(" ORDER BY exo:").append(orderBy).append(" ").append(orderType); if (orderBy != SortField.ORDER) { sqlQuery.append(", ").append(EXO_FORUM_ORDER).append(ASC); if (orderBy != SortField.CREATED) { sqlQuery.append(", ").append(EXO_CREATED_DATE).append(ASC); } } else { sqlQuery.append(", ").append(EXO_CREATED_DATE).append(ASC); } NodeIterator iter = getNodeIteratorBySQLQuery(sProvider, sqlQuery.toString(), filter.offset(), filter.limit(), true); List<Forum> forums = new ArrayList<Forum>(); while (iter.hasNext()) { Node forumNode = null; try { forumNode = iter.nextNode(); if (filter.isSummary()) { forums.add(getForum(forumNode)); } else { forums.add(getForumSummary(forumNode)); } } catch (Exception e) { LOG.debug("Failed to load forum node " + forumNode.getPath(), e); } } return forums; } catch (Exception e) { if (LOG.isDebugEnabled()) { LOG.debug("Failed to retrieving forums for category " + filter.categoryId(), e); } return new ArrayList<Forum>(); } } private List<String> getCategoriesCanCreateTopics(SessionProvider sProvider, List<String> listOfUser, boolean isIgnoreSpace) throws Exception { Set<String> canCreateTopicIds = new HashSet<String>(); // get all categories not in space that user can create topics StringBuilder cateBuilder = new StringBuilder(); if (isIgnoreSpace) { cateBuilder.append(EXO_INCLUDED_SPACE).append("='false' AND exo:id <> '") .append(Utils.CATEGORY_SPACE_ID_PREFIX).append("'"); } cateBuilder.append((isIgnoreSpace) ? " AND " : "").append(getCanCreateTopicQuery(listOfUser, true)); NodeIterator iter = getCategories(sProvider, cateBuilder.toString()); while (iter.hasNext()) { canCreateTopicIds.add(iter.nextNode().getName()); } return new ArrayList<String>(canCreateTopicIds); } private String getCanCreateTopicQuery(List<String> listOfUser, boolean isForCategory) { StringBuilder strQuery = new StringBuilder("( (") .append(Utils.buildSQLByUserInfo(EXO_CREATE_TOPIC_ROLE, listOfUser)).append(") OR (") .append(Utils.buildSQLByUserInfo(EXO_MODERATORS, listOfUser)).append(") OR (") .append(Utils.buildSQLHasProperty(EXO_CREATE_TOPIC_ROLE)); strQuery.append(") )"); if (isForCategory) { strQuery.append(" AND (").append(Utils.buildSQLByUserInfo(EXO_USER_PRIVATE, listOfUser)).append(" OR ") .append(Utils.buildSQLHasProperty(EXO_USER_PRIVATE)).append(")"); } return strQuery.toString(); } public List<CategoryFilter> filterForumByName(String forumNameFilter, String userName, int maxSize) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); try { Node categoryHome = getCategoryHome(sProvider); List<String> listOfUser = UserHelper.getAllGroupAndMembershipOfUser(userName); // get can create topic List<String> categoriesCanCreateTopics = getCategoriesCanCreateTopics(sProvider, listOfUser, true); Category cate = getCachedDataStorage().getCategoryIncludedSpace(); // query forum by input-key StringBuffer strQuery = new StringBuffer("SELECT * FROM "); strQuery.append(EXO_FORUM).append(" WHERE ").append(JCR_PATH).append(" LIKE '") .append(categoryHome.getPath()).append("/%' AND "); if (cate != null) { strQuery.append(" NOT ").append(JCR_PATH).append(" LIKE '").append(cate.getPath()) .append("/%' AND "); } strQuery.append("( UPPER(").append(EXO_NAME).append(") LIKE '").append(forumNameFilter.toUpperCase()) .append("%' OR UPPER(").append(EXO_NAME).append(") LIKE '% ") .append(forumNameFilter.toUpperCase()).append("%')") .append(Utils.getSQLQueryByProperty("AND", EXO_IS_CLOSED, "false")) .append(Utils.getSQLQueryByProperty("AND", EXO_IS_LOCK, "false")).append(" AND ") .append(getCanCreateTopicQuery(listOfUser, false)).append(" ORDER BY ").append(EXO_NAME); QueryManager qm = categoryHome.getSession().getWorkspace().getQueryManager(); Query query = qm.createQuery(strQuery.toString(), Query.SQL); QueryImpl queryImpl = (QueryImpl) query; queryImpl.setCaseInsensitiveOrder(true); long totalSize, nextOffset = 0, gotItemNumber = 0; if (maxSize > 0) { totalSize = maxSize; } else { totalSize = query.execute().getNodes().getSize(); } LinkedHashMap<String, CategoryFilter> categoryFilters = new LinkedHashMap<String, CategoryFilter>(); QueryResult qr; CategoryFilter categoryFilter; String categoryId, categoryName, forumId, forumName; NodeIterator iter; // while (gotItemNumber < totalSize && nextOffset < totalSize) { queryImpl.setOffset(nextOffset); queryImpl.setLimit(totalSize); qr = queryImpl.execute(); iter = qr.getNodes(); if (iter.getSize() <= 0) { return new ArrayList<CategoryFilter>(categoryFilters.values()); } // while (iter.hasNext()) { Node node = iter.nextNode(); categoryId = node.getParent().getName(); forumId = node.getName(); // can create topic in category/forum if (categoriesCanCreateTopics.contains(categoryId)) { if (categoryFilters.containsKey(categoryId)) { categoryFilter = categoryFilters.get(categoryId); } else { categoryName = node.getParent().getProperty(EXO_NAME).getString(); categoryFilter = new CategoryFilter(categoryId, categoryName); categoryFilters.put(categoryId, categoryFilter); } forumName = node.getProperty(EXO_NAME).getString(); if (categoryFilter.setForumFilter(forumId, forumName)) { gotItemNumber++; if (gotItemNumber == totalSize) { break; } } } } nextOffset += totalSize; } return new ArrayList<CategoryFilter>(categoryFilters.values()); } catch (Exception e) { if (LOG.isDebugEnabled()) { LOG.debug("\nCould not filter forum by name: " + forumNameFilter + e.getCause()); } } return new ArrayList<CategoryFilter>(); } public Forum getForum(String categoryId, String forumId) { SessionProvider sProvider = CommonUtils.createSystemProvider(); try { Node forumNode = getCategoryHome(sProvider).getNode(categoryId + "/" + forumId); return getForum(forumNode); } catch (Exception e) { if (LOG.isDebugEnabled()) { LOG.debug("\nCould not get " + forumId + " in " + categoryId + " fail: " + e.getCause()); } return null; } } public void modifyForum(Forum forum, int type) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); try { Node forumHomeNode = getForumHomeNode(sProvider); String forumPath = forum.getPath(); Node forumNode = (Node) forumHomeNode.getSession().getItem(forumPath); switch (type) { case Utils.CLOSE: { forumNode.setProperty(EXO_IS_CLOSED, forum.getIsClosed()); setActiveTopicByForum(sProvider, forumNode, forum.getIsClosed()); break; } case Utils.LOCK: { forumNode.setProperty(EXO_IS_LOCK, forum.getIsLock()); break; } default: break; } forumNode.getSession().save(); } catch (RepositoryException e) { LOG.error("Failed to modify forum " + forum.getForumName(), e); } } /** * Update the exo:moderators of a Node. Avoids duplicate. * * @param node Forum node * @param mods list of values to add * @return The merged list of moderators without duplicates * @throws Exception */ String[] updateModeratorInForum(Node node, String[] mods) throws Exception { PropertyReader reader = new PropertyReader(node); Set<String> set = reader.set(EXO_MODERATORS); if (set == null || set.contains("")) { return mods; } for (String mod : mods) { if (!mod.isEmpty()) { set.add(mod); } } return set.toArray(new String[set.size()]); } public void saveForum(String categoryId, Forum forum, boolean isNew) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); Node forumNode = null; String[] strModerators = forum.getModerators(); try { Node catNode = getCategoryHome(sProvider).getNode(categoryId); boolean isNewModerateTopic = forum.getIsModerateTopic(); boolean isModerateTopic = isNewModerateTopic; String[] oldMod = new String[] {}; if (isNew) { forumNode = catNode.addNode(forum.getId(), EXO_FORUM); forumNode.setProperty(EXO_ID, forum.getId()); forumNode.setProperty(EXO_OWNER, forum.getOwner()); forumNode.setProperty(EXO_CREATED_DATE, getGreenwichMeanTime()); forumNode.setProperty(EXO_LAST_TOPIC_PATH, forum.getLastTopicPath()); forumNode.setProperty(EXO_POST_COUNT, 0); forumNode.setProperty(EXO_TOPIC_COUNT, 0); forumNode.setProperty(EXO_BAN_I_PS, new String[] {}); forum.setPath(forumNode.getPath()); long forumCount = 1; if (catNode.hasProperty(EXO_FORUM_COUNT)) forumCount = catNode.getProperty(EXO_FORUM_COUNT).getLong() + 1; catNode.setProperty(EXO_FORUM_COUNT, forumCount); forumNode.setProperty(EXO_MODERATORS, strModerators); } else { forumNode = catNode.getNode(forum.getId()); oldMod = Utils.valuesToArray(forumNode.getProperty(EXO_MODERATORS).getValues()); forumNode.setProperty(EXO_MODERATORS, strModerators); forumNode.setProperty(EXO_TEMP_MODERATORS, oldMod); if (forumNode.hasProperty(EXO_IS_MODERATE_TOPIC)) isModerateTopic = forumNode.getProperty(EXO_IS_MODERATE_TOPIC).getBoolean(); } forumNode.setProperty(EXO_NAME, forum.getForumName()); forumNode.setProperty(EXO_FORUM_ORDER, forum.getForumOrder()); forumNode.setProperty(EXO_MODIFIED_BY, forum.getModifiedBy()); forumNode.setProperty(EXO_MODIFIED_DATE, getGreenwichMeanTime()); forumNode.setProperty(EXO_DESCRIPTION, forum.getDescription()); forumNode.setProperty(EXO_IS_AUTO_ADD_EMAIL_NOTIFY, forum.getIsAutoAddEmailNotify()); forumNode.setProperty(EXO_NOTIFY_WHEN_ADD_POST, forum.getNotifyWhenAddPost()); forumNode.setProperty(EXO_NOTIFY_WHEN_ADD_TOPIC, forum.getNotifyWhenAddTopic()); forumNode.setProperty(EXO_IS_MODERATE_TOPIC, isNewModerateTopic); forumNode.setProperty(EXO_IS_MODERATE_POST, forum.getIsModeratePost()); forumNode.setProperty(EXO_IS_CLOSED, forum.getIsClosed()); forumNode.setProperty(EXO_IS_LOCK, forum.getIsLock()); forumNode.setProperty(EXO_CREATE_TOPIC_ROLE, convertArray(forum.getCreateTopicRole())); forumNode.setProperty(EXO_POSTER, convertArray(forum.getPoster())); // set from category strModerators = updateModeratorInForum(catNode, strModerators); boolean isEditMod = isNew; if (!isNew && Utils.arraysHaveDifferentContent(oldMod, strModerators)) { isEditMod = true; } // save list moderators in property categoryPrivate when list userPrivate of parent category not empty. if (isEditMod) { if (strModerators != null && strModerators.length > 0 && !Utils.isEmpty(strModerators[0])) { if (catNode.hasProperty(EXO_USER_PRIVATE)) { List<String> listPrivate = new ArrayList<String>(); listPrivate.addAll(Utils.valuesToList(catNode.getProperty(EXO_USER_PRIVATE).getValues())); if (listPrivate.size() > 0 && !Utils.isEmpty(listPrivate.get(0))) { for (int i = 0; i < strModerators.length; i++) { if (!listPrivate.contains(strModerators[i])) { listPrivate.add(strModerators[i]); } } catNode.setProperty(EXO_USER_PRIVATE, listPrivate.toArray(new String[listPrivate.size()])); } } } } forumNode.setProperty(EXO_VIEWER, convertArray(forum.getViewer())); catNode.getSession().save(); PropertyReader reader = new PropertyReader(forumNode); forum.setPath(forumNode.getPath()); forum.setTopicCount(reader.l(EXO_TOPIC_COUNT)); forum.setPostCount(reader.l(EXO_POST_COUNT)); forum.setLastTopicPath(getLastTopicPath(reader, forum)); forum.setModerators(strModerators); StringBuilder id = new StringBuilder(); id.append(catNode.getProperty(EXO_CATEGORY_ORDER).getString()); id.append(catNode.getProperty(EXO_CREATED_DATE).getDate().getTimeInMillis()); id.append(forum.getForumOrder()); if (isNew) { id.append(getGreenwichMeanTime()); PruneSetting pruneSetting = new PruneSetting(); pruneSetting.setId(id.toString()); pruneSetting.setForumPath(forum.getPath()); savePruneSetting(pruneSetting); } else { id.append(forum.getCreatedDate().getTime()); if (isModerateTopic != isNewModerateTopic) { queryLastTopic(sProvider, forumNode.getPath()); } // updatePruneId Node pruneSetting = forumNode.getNode(Utils.PRUNESETTING); pruneSetting.setProperty(EXO_ID, id.toString()); pruneSetting.save(); } } catch (Exception e) { LOG.error("Failed to save forum " + forum.getForumName(), e); } } /** * Converts the arrays String what has NULL or EMPTY to "" * It will be applied for these cases such as categories, forums, and topics with fields: * exo:userPrivate, exo:viewer, exo:canView, exo:createTopicRole, exo:poster, exo:canPost * * @param strs * @return */ private static String[] convertArray(String[] strs) { if (Utils.isEmpty(strs)) { return new String[] { "" }; } return strs; } private void setModeratorForum(Session session, String[] strModerators, String[] oldModeratoForums, Forum forum, String categoryId, boolean isNew) throws Exception { Node userProfileHomeNode = session.getRootNode().getNode(dataLocator.getUserProfilesLocation()); Node userProfileNode; List<String> moderators = ForumServiceUtils.getUserPermission(strModerators); if (moderators.size() > 0) { for (String string : moderators) { string = string.trim(); List<String> list = new ArrayList<String>(); try { userProfileNode = userProfileHomeNode.getNode(string); List<String> moderatorForums = new ArrayList<String>(); if (userProfileNode.hasProperty(EXO_MODERATE_FORUMS)) { moderatorForums = PropertyReader .valuesToList(userProfileNode.getProperty(EXO_MODERATE_FORUMS).getValues()); } boolean hasMod = false; for (String string2 : moderatorForums) { if (string2.indexOf(forum.getId()) > 0) { hasMod = true; } if (!Utils.isEmpty(string2)) { list.add(string2); } } if (userProfileNode.getProperty(EXO_USER_ROLE).getLong() >= 2) { userProfileNode.setProperty(EXO_USER_ROLE, 1); userProfileNode.setProperty(EXO_USER_TITLE, Utils.MODERATOR); } if (!hasMod) { list.add(forum.getForumName() + "(" + categoryId + "/" + forum.getId()); userProfileNode.setProperty(EXO_MODERATE_FORUMS, Utils.getStringsInList(list)); getTotalJobWaitingForModerator(session, string); } } catch (PathNotFoundException e) { userProfileNode = userProfileHomeNode.addNode(string, EXO_FORUM_USER_PROFILE); String[] strings = new String[] { (forum.getForumName() + "(" + categoryId + "/" + forum.getId()) }; userProfileNode.setProperty(EXO_MODERATE_FORUMS, strings); userProfileNode.setProperty(EXO_USER_ROLE, 1); userProfileNode.setProperty(EXO_USER_TITLE, Utils.MODERATOR); if (userProfileNode.isNew()) { userProfileNode.getSession().save(); } else { userProfileNode.save(); } getTotalJobWaitingForModerator(session, string); } } } // remove if (!isNew) { List<String> oldmoderators = ForumServiceUtils.getUserPermission(oldModeratoForums); for (String string : oldmoderators) { boolean isDelete = true; if (moderators.contains(string)) { isDelete = false; } if (isDelete) { try { List<String> list = new ArrayList<String>(); userProfileNode = userProfileHomeNode.getNode(string); String[] moderatorForums = PropertyReader .valuesToArray(userProfileNode.getProperty(EXO_MODERATE_FORUMS).getValues()); for (String string2 : moderatorForums) { if (string2.indexOf(forum.getId()) < 0) { list.add(string2); } } userProfileNode.setProperty(EXO_MODERATE_FORUMS, Utils.getStringsInList(list)); if (list.isEmpty()) { //hasRole == fasle or hasRole =true && is Moderator = true; if (userProfileNode.hasProperty(EXO_USER_ROLE) == false || userProfileNode.hasProperty(EXO_USER_ROLE) && userProfileNode .getProperty(EXO_USER_ROLE).getLong() == UserProfile.MODERATOR) { userProfileNode.setProperty(EXO_USER_ROLE, UserProfile.USER); userProfileNode.setProperty(EXO_USER_TITLE, Utils.USER); } } else { // moderator > 0 userProfileNode.setProperty(EXO_USER_ROLE, UserProfile.MODERATOR); userProfileNode.setProperty(EXO_USER_TITLE, Utils.MODERATOR); } } catch (Exception e) { logDebug("Failed to removing forumId storage in property moderator of user: " + string); } } } } if (userProfileHomeNode.isNew()) { userProfileHomeNode.getSession().save(); } else { userProfileHomeNode.save(); } } public void saveModerateOfForums(List<String> forumPaths, String userName, boolean isDelete) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); Node categoryHomeNode = getCategoryHome(sProvider); for (String path : forumPaths) { String forumPath = categoryHomeNode.getPath() + "/" + path; Node forumNode; try { forumNode = (Node) categoryHomeNode.getSession().getItem(forumPath); Node cateNode = forumNode.getParent(); if (isDelete) { String[] cateMods = PropertyReader .valuesToArray(cateNode.getProperty(EXO_MODERATORS).getValues()); if (cateMods != null && cateMods.length > 0 && !Utils.isEmpty(cateMods[0])) { if (ForumServiceUtils.hasPermission(cateMods, userName)) continue; } if (forumNode.hasProperty(EXO_MODERATORS)) { String[] oldUserNamesModerate = PropertyReader .valuesToArray(forumNode.getProperty(EXO_MODERATORS).getValues()); List<String> list = new ArrayList<String>(); for (String string : oldUserNamesModerate) { if (!string.equals(userName)) { list.add(string); } } forumNode.setProperty(EXO_MODERATORS, Utils.getStringsInList(list)); forumNode.setProperty(EXO_TEMP_MODERATORS, oldUserNamesModerate); } } else { String[] oldUserNamesModerate = new String[] {}; if (forumNode.hasProperty(EXO_MODERATORS)) { oldUserNamesModerate = PropertyReader .valuesToArray(forumNode.getProperty(EXO_MODERATORS).getValues()); } List<String> list = new ArrayList<String>(); for (String string : oldUserNamesModerate) { if (!string.equals(userName)) { list.add(string); } } list.add(userName); forumNode.setProperty(EXO_MODERATORS, Utils.getStringsInList(list)); forumNode.setProperty(EXO_TEMP_MODERATORS, oldUserNamesModerate); if (cateNode.hasProperty(EXO_USER_PRIVATE)) { list = Utils.valuesToList(cateNode.getProperty(EXO_USER_PRIVATE).getValues()); if (list.size() > 0 && !Utils.isEmpty(list.get(0)) && !list.contains(userName)) { String[] strings = new String[list.size() + 1]; int i = 0; for (String string : list) { strings[i] = string; ++i; } strings[i] = userName; cateNode.setProperty(EXO_USER_PRIVATE, strings); } } } } catch (Exception e) { LOG.error("Failed to save moderate of forums", e); } } if (categoryHomeNode.isNew()) { categoryHomeNode.getSession().save(); } else { categoryHomeNode.save(); } } /** * Loads only part of the forum properties * * @param forumNode * @return * @throws Exception */ private Forum getForumSummary(Node forumNode) throws Exception { Forum forum = new Forum(); PropertyReader reader = new PropertyReader(forumNode); forum.setId(forumNode.getName()); forum.setPath(forumNode.getPath()); forum.setForumName(reader.string(EXO_NAME)); forum.setDescription(reader.string(EXO_DESCRIPTION)); forum.setModerators(reader.strings(EXO_MODERATORS)); forum.setPostCount(reader.l(EXO_POST_COUNT)); forum.setTopicCount(reader.l(EXO_TOPIC_COUNT)); forum.setIsModerateTopic(reader.bool(EXO_IS_MODERATE_TOPIC)); forum.setLastTopicPath(getLastTopicPath(reader, forum)); forum.setIsClosed(reader.bool(EXO_IS_CLOSED)); forum.setIsLock(reader.bool(EXO_IS_LOCK)); return forum; } private String getLastTopicPath(PropertyReader reader, Forum forum) { String lastTopic = reader.string(EXO_LAST_TOPIC_PATH, CommonUtils.EMPTY_STR); if (!Utils.isEmpty(lastTopic)) { lastTopic = Utils.getTopicId(lastTopic); lastTopic = new StringBuilder(forum.getPath()).append(CommonUtils.SLASH).append(lastTopic).toString(); } return lastTopic; } private Forum getForum(Node forumNode) throws Exception { if (forumNode == null) return null; Forum forum = new Forum(); PropertyReader reader = new PropertyReader(forumNode); forum.setId(forumNode.getName()); forum.setPath(forumNode.getPath()); forum.setOwner(reader.string(EXO_OWNER)); forum.setForumName(reader.string(EXO_NAME)); forum.setForumOrder(Integer.valueOf(reader.string(EXO_FORUM_ORDER))); forum.setCreatedDate(reader.date(EXO_CREATED_DATE)); forum.setModifiedBy(reader.string(EXO_MODIFIED_BY)); forum.setModifiedDate(reader.date(EXO_MODIFIED_DATE)); forum.setLastTopicPath(getLastTopicPath(reader, forum)); forum.setDescription(reader.string(EXO_DESCRIPTION)); forum.setPostCount(reader.l(EXO_POST_COUNT)); forum.setTopicCount(reader.l(EXO_TOPIC_COUNT)); forum.setIsModerateTopic(reader.bool(EXO_IS_MODERATE_TOPIC)); forum.setIsModeratePost(reader.bool(EXO_IS_MODERATE_POST)); forum.setIsClosed(reader.bool(EXO_IS_CLOSED)); forum.setIsLock(reader.bool(EXO_IS_LOCK)); forum.setIsAutoAddEmailNotify(reader.bool(EXO_IS_AUTO_ADD_EMAIL_NOTIFY, false)); forum.setNotifyWhenAddPost(reader.strings(EXO_NOTIFY_WHEN_ADD_POST)); forum.setNotifyWhenAddTopic(reader.strings(EXO_NOTIFY_WHEN_ADD_TOPIC)); forum.setViewer(reader.strings(EXO_VIEWER)); forum.setCreateTopicRole(reader.strings(EXO_CREATE_TOPIC_ROLE)); forum.setPoster(reader.strings(EXO_POSTER)); forum.setModerators(reader.strings(EXO_MODERATORS)); forum.setBanIP(reader.list(EXO_BAN_I_PS)); if (forumNode.isNodeType(EXO_FORUM_WATCHING)) { if (forumNode.hasProperty(EXO_EMAIL_WATCHING)) forum.setEmailNotification(reader.strings(EXO_EMAIL_WATCHING)); } return forum; } public Forum removeForum(String categoryId, String forumId) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); Forum forum = null; try { Node catNode = getCategoryHome(sProvider).getNode(categoryId); Node forumNode = catNode.getNode(forumId); Map<String, Long> userPostMap = getDeletePostByUser(sProvider, forumNode); forum = getForum(forumNode); forumNode.setProperty(EXO_TEMP_MODERATORS, forum.getModerators()); forumNode.setProperty(EXO_MODERATORS, new String[] { " " }); forumNode.save(); forumNode.remove(); catNode.setProperty(EXO_FORUM_COUNT, catNode.getProperty(EXO_FORUM_COUNT).getLong() - 1); catNode.save(); addUpdateUserProfileJob(userPostMap); getTotalJobWatting(sProvider, new HashSet<String>(Arrays.asList(forum.getModerators()))); } catch (Exception e) { logDebug("Failed to remove forum: " + forumId); return null; } return forum; } public void moveForum(List<Forum> forums, String destCategoryPath) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); try { Node forumHomeNode = getForumHomeNode(sProvider); String oldCatePath = ""; if (!forums.isEmpty()) { String forumPath = forums.get(0).getPath(); oldCatePath = forumPath.substring(0, forumPath.lastIndexOf("/")); } else { return; } Node oldCatNode = (Node) forumHomeNode.getSession().getItem(oldCatePath); Node newCatNode = (Node) forumHomeNode.getSession().getItem(destCategoryPath); for (Forum forum : forums) { String newForumPath = destCategoryPath + "/" + forum.getId(); forumHomeNode.getSession().getWorkspace().move(forum.getPath(), newForumPath); Node forumNode = (Node) forumHomeNode.getSession().getItem(newForumPath); forumNode.setProperty(EXO_PATH, newForumPath); String[] strModerators = forum.getModerators(); forumNode.setProperty(EXO_MODERATORS, strModerators); if (strModerators != null && strModerators.length > 0 && !Utils.isEmpty(strModerators[0])) { if (newCatNode.hasProperty(EXO_USER_PRIVATE)) { List<String> listPrivate = new ArrayList<String>(); listPrivate .addAll(Utils.valuesToList(newCatNode.getProperty(EXO_USER_PRIVATE).getValues())); if (!Utils.isEmpty(listPrivate.get(0))) { for (int i = 0; i < strModerators.length; i++) { if (!listPrivate.contains(strModerators[i])) { listPrivate.add(strModerators[i]); } } newCatNode.setProperty(EXO_USER_PRIVATE, listPrivate.toArray(new String[listPrivate.size()])); } } } } long forumCount = forums.size(); oldCatNode.setProperty(EXO_FORUM_COUNT, oldCatNode.getProperty(EXO_FORUM_COUNT).getLong() - forumCount); if (newCatNode.hasProperty(EXO_FORUM_COUNT)) forumCount = newCatNode.getProperty(EXO_FORUM_COUNT).getLong() + forumCount; newCatNode.setProperty(EXO_FORUM_COUNT, forumCount); if (forumHomeNode.isNew()) { forumHomeNode.getSession().save(); } else { forumHomeNode.save(); } } catch (Exception e) { LOG.error("Failed to move forum", e); } } private void setActiveTopicByForum(SessionProvider sProvider, Node forumNode, boolean isClosed) throws Exception { NodeIterator iter = forumNode.getNodes(); Node topicNode = null; isClosed = !isClosed; while (iter.hasNext()) { topicNode = iter.nextNode(); if (topicNode.isNodeType(EXO_TOPIC)) { topicNode.setProperty(EXO_IS_ACTIVE_BY_FORUM, isClosed); setActivePostByTopic(sProvider, topicNode, isClosed); } } if (forumNode.isNew()) { forumNode.getSession().save(); } else { forumNode.save(); } } private void setActivePostByTopic(SessionProvider sProvider, Node topicNode, boolean isActiveTopic) throws Exception { PropertyReader reader = new PropertyReader(topicNode); if (isActiveTopic) isActiveTopic = reader.bool(EXO_IS_APPROVED); if (isActiveTopic) isActiveTopic = !(reader.bool(EXO_IS_WAITING)); if (isActiveTopic) isActiveTopic = !(reader.bool(EXO_IS_CLOSED)); if (isActiveTopic) isActiveTopic = reader.bool(EXO_IS_ACTIVE); Node postNode = null; NodeIterator iter = topicNode.getNodes(); while (iter.hasNext()) { postNode = iter.nextNode(); if (postNode.isNodeType(EXO_POST)) { postNode.setProperty(EXO_IS_ACTIVE_BY_TOPIC, isActiveTopic); } } if (topicNode.isNew()) { topicNode.getSession().save(); } else { topicNode.save(); } } /** * @deprecated use {@link #getTopics(TopicFilter, int, int) */ public JCRPageList getPageTopic(String categoryId, String forumId, String strQuery, String strOrderBy) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); try { Node categoryNode = getCategoryHome(sProvider).getNode(categoryId); Node forumNode = categoryNode.getNode(forumId); String forumPath = forumNode.getPath(); String pathQuery = Utils.buildTopicQuery(getForumSortSettings(), strQuery, strOrderBy, forumPath); QueryManager qm = categoryNode.getSession().getWorkspace().getQueryManager(); Query query = qm.createQuery(pathQuery, Query.XPATH); QueryResult result = query.execute(); NodeIterator iter = result.getNodes(); JCRPageList pagelist = new ForumPageList(iter, 10, pathQuery, true); return pagelist; } catch (Exception e) { return null; } } /** * @deprecated use {@link #getTopics(TopicFilter, int, int) */ public LazyPageList<Topic> getTopicList(String categoryId, String forumId, String xpathConditions, String strOrderBy, int pageSize) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); try { Node categoryNode = getCategoryHome(sProvider).getNode(categoryId); Node forumNode = categoryNode.getNode(forumId); String forumPath = forumNode.getPath(); if (xpathConditions != null && xpathConditions.length() > 0 && xpathConditions.contains("topicPermission")) { String str = buildXpath(sProvider, forumNode); if (str.length() > 0) { xpathConditions = StringUtils.replace(xpathConditions, "topicPermission", "(" + str + "))"); } } String topicQuery = Utils.buildTopicQuery(getForumSortSettings(), xpathConditions, strOrderBy, forumPath); TopicListAccess topicListAccess = new TopicListAccess(sessionManager, topicQuery); return new LazyPageList<Topic>(topicListAccess, pageSize); } catch (Exception e) { if (LOG.isDebugEnabled()) { LOG.debug("Failed to retrieve topic list for forum " + forumId, e); } return null; } } // private String buildXpath(SessionProvider sProvider, Node forumNode) throws Exception { QueryManager qm = getCategoryHome(sProvider).getSession().getWorkspace().getQueryManager(); StringBuilder qrBuilder = new StringBuilder(JCR_ROOT); qrBuilder.append(forumNode.getPath()).append("/element(*,").append(EXO_TOPIC).append(")[@") .append(EXO_IS_WAITING).append("='false' and @").append(EXO_IS_ACTIVE).append("='true' and @") .append(EXO_IS_CLOSED).append("='false' and (not(@").append(EXO_CAN_VIEW).append(") or @") .append(EXO_CAN_VIEW).append("='' or @").append(EXO_CAN_VIEW).append("=' ')]"); Query query = qm.createQuery(qrBuilder.toString(), Query.XPATH); QueryResult result = query.execute(); NodeIterator iter = result.getNodes(); StringBuilder builder = new StringBuilder(); boolean isOr = false; while (iter.hasNext()) { Node node = iter.nextNode(); if (isOr) builder.append(" and "); builder.append("@").append(EXO_ID).append("!='").append(node.getName()).append("'"); isOr = true; } return builder.toString(); } public List<Topic> getTopics(TopicFilter filter, int offset, int limit) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); try { NodeIterator iter = getNodeIteratorBySQLQuery(sProvider, buildTopicQuery(filter, true), offset, limit, true); List<Topic> topicList = new ArrayList<Topic>(); if (iter != null && iter.getSize() > 0) { while (iter.hasNext()) { topicList.add(getTopicNode(iter.nextNode())); } } return topicList; } catch (Exception e) { if (LOG.isDebugEnabled()) { LOG.debug("Failed to retrieve topic list for forum " + filter.forumId(), e); } return null; } } private String buildTopicQuery(TopicFilter filter, boolean hasOrder) throws Exception { SortSettings sortSettings = getTopicSortSettings(); SortField orderBy = sortSettings.getField(); Direction orderType = sortSettings.getDirection(); String forumPath = new StringBuilder("/").append(dataLocator.getForumCategoriesLocation()).append("/") .append(filter.categoryId()).append("/").append(filter.forumId()).toString(); StringBuilder sqlBuilder = jcrPathLikeAndNotLike(EXO_TOPIC, forumPath); if (filter.isAdmin() == false) { StringBuilder strQuery = new StringBuilder(); strQuery.append(Utils.getSQLQueryByProperty("AND", EXO_IS_WAITING, "false")) .append(Utils.getSQLQueryByProperty("AND", EXO_IS_ACTIVE, "true")) .append(Utils.getSQLQueryByProperty("AND", EXO_IS_CLOSED, "false")); if (filter.isApproved()) { strQuery.append(Utils.getSQLQueryByProperty("AND", EXO_IS_APPROVED, "true")); } if (Utils.isEmpty(filter.viewers()) == true) { // public from parent ==> user is owner or user in can view or can view is empty strQuery.append(" AND (").append(Utils.EXO_OWNER).append("='").append(filter.userLogin()) .append("' OR ") .append(Utils.buildSQLByUserInfo(EXO_CAN_VIEW, UserHelper.getAllGroupAndMembershipOfUser(null))) .append(" OR ").append(Utils.buildSQLHasProperty(EXO_CAN_VIEW)).append(")"); } else if (ForumServiceUtils.hasPermission(filter.viewers(), filter.userLogin()) == false) { // has not permission from parent ==> user is owner or user in can view strQuery.append(" AND (").append(Utils.EXO_OWNER).append("='").append(filter.userLogin()) .append("' OR ").append(Utils.buildSQLByUserInfo(EXO_CAN_VIEW, UserHelper.getAllGroupAndMembershipOfUser(null))) .append(")"); } else { // has permission from parent ==> empty } sqlBuilder.append(strQuery); } if (hasOrder == true) { sqlBuilder.append(" ORDER BY ").append(EXO_IS_STICKY).append(DESC); String strOrderBy = filter.orderBy(); if (strOrderBy == null || Utils.isEmpty(strOrderBy)) { if (orderBy != null) { sqlBuilder.append(", exo:").append(orderBy.toString()).append(" ").append(orderType); if (!orderBy.equals(SortField.LASTPOST)) { sqlBuilder.append(", ").append(EXO_LAST_POST_DATE).append(DESC); } } else { sqlBuilder.append(", ").append(EXO_LAST_POST_DATE).append(DESC); } } else { sqlBuilder.append(", exo:").append(strOrderBy); if (strOrderBy.indexOf(SortField.LASTPOST.toString()) < 0) { sqlBuilder.append(", ").append(EXO_LAST_POST_DATE).append(DESC); } } } return sqlBuilder.toString(); } public int getTopicsCount(TopicFilter filter) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); try { NodeIterator iter = null; if (Utils.isEmpty(filter.userName()) == false) { iter = getNodeIteratorBySQLQuery(sProvider, buildQueryTopicsByUser(filter, false), 0, 0, false); } else { iter = getNodeIteratorBySQLQuery(sProvider, buildTopicQuery(filter, false), 0, 0, false); } return (int) ((iter != null) ? iter.getSize() : 0); } catch (Exception e) { return 0; } } public List<Topic> getTopics(String categoryId, String forumId) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); List<Topic> topics = new ArrayList<Topic>(); try { Node forumNode = getCategoryHome(sProvider).getNode(categoryId).getNode(forumId); NodeIterator iter = forumNode.getNodes(); while (iter.hasNext()) { try { Node topicNode = iter.nextNode(); if (topicNode.isNodeType(EXO_TOPIC)) topics.add(getTopicNode(topicNode)); } catch (Exception e) { if (LOG.isDebugEnabled()) { LOG.debug("Can not get topic", e); } } } } catch (Exception e) { return null; } return topics; } public void setViewCountTopic(String path, String userRead) { if (userRead != null && userRead.length() > 0 && !userRead.equals(UserProfile.USER_GUEST)) { if (updatingView.containsKey(path)) { int value = updatingView.get((path)); updatingView.put(path, value + 1); } else { updatingView.put(path, 1); } } } public void writeViews() { // Map<String, Integer> map = updatingView; updatingView = new ConcurrentHashMap<String, Integer>(); // SessionProvider sProvider = CommonUtils.createSystemProvider(); for (Map.Entry<String, Integer> entry : map.entrySet()) { try { Node topicNode = getCategoryHome(sProvider).getNode(entry.getKey()); long newViewCount = new PropertyReader(topicNode).l(EXO_VIEW_COUNT) + entry.getValue(); topicNode.setProperty(EXO_VIEW_COUNT, newViewCount); if (topicNode.isNew()) { topicNode.getSession().save(); } else { topicNode.save(); } } catch (Exception e) { if (LOG.isDebugEnabled()) { LOG.debug(String.format("Failed to set view number for topic with path %s", entry.getKey()), e); } } } } public Topic getTopic(String categoryId, String forumId, String topicId, String userRead) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); try { Node topicNode = getCategoryHome(sProvider).getNode(categoryId + "/" + forumId + "/" + topicId); return getTopicNode(topicNode); } catch (Exception e) { if (LOG.isDebugEnabled()) { LOG.debug("Getting Topic fail: " + e.getMessage() + "\n" + e.getCause()); } return null; } } public Topic getTopicSummary(String topicPath) { try { return getTopicSummary(topicPath, false); } catch (Exception e) { return null; } } @Override public boolean topicHasPoll(String topicPath) { try { return new PropertyReader(getTopicNodeByPath(topicPath, false)).bool(EXO_IS_POLL, false); } catch (Exception e) { return false; } } public Topic getTopicSummary(String topicPath, boolean isLastPost) throws Exception { return getTopicNodeSummary(getTopicNodeByPath(topicPath, isLastPost)); } public Topic getTopicByPath(String topicPath, boolean isLastPost) throws Exception { return getTopicNode(getTopicNodeByPath(topicPath, isLastPost)); } private Node getTopicNodeByPath(String topicPath, boolean isLastPost) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); try { Node catogoryHome = getCategoryHome(sProvider); if (topicPath == null || topicPath.length() <= 0) return null; if (topicPath.indexOf(catogoryHome.getName()) < 0) topicPath = catogoryHome.getPath() + "/" + topicPath; Node topicNode = (Node) catogoryHome.getSession().getItem(topicPath); if (topicNode == null && isLastPost) { String forumPath = Utils.getForumPath(topicPath); topicNode = queryLastTopic(sProvider, forumPath); } return topicNode; } catch (RepositoryException e) { if (topicPath != null && topicPath.length() > 0 && isLastPost) { String forumPath = Utils.getForumPath(topicPath); return queryLastTopic(sProvider, forumPath); } } catch (Exception e) { return null; } return null; } private Node queryLastTopic(SessionProvider sProvider, String forumPath) throws Exception { try { Node forumHomeNode = getForumHomeNode(sProvider); Node forumNode = (Node) forumHomeNode.getSession().getItem(forumPath); StringBuilder sqlQuery = jcrPathLikeAndNotLike(EXO_TOPIC, forumPath); sqlQuery.append(Utils.getSQLQueryByProperty("AND", EXO_IS_WAITING, "false")) .append(Utils.getSQLQueryByProperty("AND", EXO_IS_CLOSED, "false")) .append(Utils.getSQLQueryByProperty("AND", EXO_IS_ACTIVE, "true")).append(" ORDER BY ") .append(EXO_LAST_POST_DATE).append(DESC); NodeIterator iter = getNodeIteratorBySQLQuery(sProvider, sqlQuery.toString(), 0, 0, false); String lastTopicPath = StringUtils.EMPTY; boolean isModerateTopic = new PropertyReader(forumNode).bool(EXO_IS_MODERATE_TOPIC); Node topicNode = null; while (iter.hasNext()) { topicNode = iter.nextNode(); if (isModerateTopic == false || topicNode.getProperty(EXO_IS_APPROVED).getBoolean()) { lastTopicPath = topicNode.getName(); break; } } forumNode.setProperty(EXO_LAST_TOPIC_PATH, lastTopicPath); forumNode.getSession().save(); return topicNode; } catch (PathNotFoundException e) { if (LOG.isDebugEnabled()) { LOG.debug("Failed to query last topic", e); } return null; } } private Topic getTopicNodeSummary(Node topicNode) throws RepositoryException { if (topicNode == null) return null; Topic topicNew = new Topic(); PropertyReader reader = new PropertyReader(topicNode); topicNew.setId(topicNode.getName()); topicNew.setPath(topicNode.getPath()); topicNew.setIcon(reader.string(EXO_ICON)); topicNew.setTopicName(reader.string(EXO_NAME)); topicNew.setLastPostBy(reader.string(EXO_LAST_POST_BY)); topicNew.setLastPostDate(reader.date(EXO_LAST_POST_DATE)); topicNew.setIsClosed(reader.bool(EXO_IS_CLOSED)); topicNew.setIsApproved(reader.bool(EXO_IS_APPROVED)); topicNew.setIsActive(reader.bool(EXO_IS_ACTIVE)); topicNew.setIsPoll(reader.bool(EXO_IS_POLL)); topicNew.setCanView(reader.strings(EXO_CAN_VIEW, new String[] {})); return topicNew; } private Topic getTopicUpdate(Node topicNode, Topic topic, boolean isSummary) throws Exception { PropertyReader reader = new PropertyReader(topicNode); if (isSummary) { topic.setLastPostDate(reader.date(EXO_LAST_POST_DATE)); topic.setLastPostBy(reader.string(EXO_LAST_POST_BY)); topic.setOwner(reader.string(EXO_OWNER)); topic.setTopicName(reader.string(EXO_NAME)); topic.setDescription(reader.string(EXO_DESCRIPTION)); topic.setPostCount(reader.l(EXO_POST_COUNT)); topic.setViewCount(reader.l(EXO_VIEW_COUNT)); topic.setNumberAttachment(reader.l(EXO_NUMBER_ATTACHMENTS)); topic.setIsSticky(reader.bool(EXO_IS_STICKY)); topic.setUserVoteRating(reader.strings(EXO_USER_VOTE_RATING)); topic.setVoteRating(reader.d(EXO_VOTE_RATING)); } // some properties get again because update new data. topic.setIsWaiting(reader.bool(EXO_IS_WAITING)); topic.setIsActive(reader.bool(EXO_IS_ACTIVE)); topic.setIsActiveByForum(reader.bool(EXO_IS_ACTIVE_BY_FORUM)); if (topicNode.getParent().getProperty(EXO_IS_LOCK).getBoolean()) topic.setIsLock(true); else topic.setIsLock(reader.bool(EXO_IS_LOCK)); topic.setIsClosed(reader.bool(EXO_IS_CLOSED)); // update more properties for topic. topic.setCreatedDate(reader.date(EXO_CREATED_DATE)); topic.setModifiedBy(reader.string(EXO_MODIFIED_BY)); topic.setModifiedDate(reader.date(EXO_MODIFIED_DATE)); topic.setIsModeratePost(reader.bool(EXO_IS_MODERATE_POST)); topic.setIsNotifyWhenAddPost(reader.string(EXO_IS_NOTIFY_WHEN_ADD_POST, null)); topic.setLink(reader.string(EXO_LINK)); topic.setTagId(reader.strings(EXO_TAG_ID)); topic.setCanView(reader.strings(EXO_CAN_VIEW, new String[] {})); topic.setCanPost(reader.strings(EXO_CAN_POST, new String[] {})); if (topicNode.isNodeType(EXO_FORUM_WATCHING)) topic.setEmailNotification(reader.strings(EXO_EMAIL_WATCHING, new String[] {})); try { if (reader.l(EXO_NUMBER_ATTACHMENTS) > 0) { String idFirstPost = topicNode.getName().replaceFirst(Utils.TOPIC, Utils.POST); Node FirstPostNode = topicNode.getNode(idFirstPost); topic.setAttachments(getAttachmentsByNode(FirstPostNode)); } } catch (Exception e) { if (LOG.isDebugEnabled()) { LOG.debug("Failed to set attachments in topic.", e); } } return topic; } public Topic getTopicUpdate(Topic topic, boolean isSummary) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); try { Node forumHomeNode = getForumHomeNode(sProvider); Node topicNode = (Node) forumHomeNode.getSession().getItem(topic.getPath()); return getTopicUpdate(topicNode, topic, isSummary); } catch (Exception e) { if (LOG.isDebugEnabled()) { LOG.debug("Failed to get topic", e); } } return topic; } public Topic getTopicNode(Node topicNode) throws Exception { if (topicNode == null) return null; Topic topic = getTopicNodeSummary(topicNode); return getTopicUpdate(topicNode, topic, true); } /** * @deprecated use {@link #getTopicsByDate(long, String, int, int)} */ public JCRPageList getPageTopicOld(long date, String forumPatch) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); try { String sqlQuery = buildSQLQueryGetTopicByDate(date, forumPatch); NodeIterator iter = getNodeIteratorBySQLQuery(sProvider, sqlQuery, 0, 0, false); return new ForumPageList(iter, 10, sqlQuery, true); } catch (Exception e) { return null; } } public List<Topic> getTopicsByDate(long date, String forumPath, int offset, int limit) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); try { List<Topic> topics = new ArrayList<Topic>(); NodeIterator iter = getNodeIteratorBySQLQuery(sProvider, buildSQLQueryGetTopicByDate(date, forumPath), offset, limit, false); while (iter.hasNext()) { Node node = iter.nextNode(); topics.add(getTopicNode(node)); } return topics; } catch (Exception e) { return null; } } private String buildSQLQueryGetTopicByDate(long date, String forumPath) throws Exception { StringBuilder sqlBuilder = new StringBuilder("SELECT * FROM ").append(EXO_TOPIC); sqlBuilder.append(" WHERE ").append(JCR_PATH).append(" LIKE '"); if (Utils.isEmpty(forumPath) == false) { sqlBuilder.append(forumPath).append("/%' AND NOT ").append(JCR_PATH).append(" LIKE '").append(forumPath) .append("/%/%'"); } else { sqlBuilder.append("/").append(dataLocator.getForumCategoriesLocation()).append("/%'"); } Calendar newDate = getGreenwichMeanTime(); newDate.setTimeInMillis(newDate.getTimeInMillis() - date * 86400000); sqlBuilder.append(" AND (").append(EXO_LAST_POST_DATE).append(" <= TIMESTAMP '") .append(ISO8601.format(newDate)).append("') ORDER BY ").append(EXO_CREATED_DATE).append(ASC); return sqlBuilder.toString(); } public List<Topic> getAllTopicsOld(long date, String forumPath) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); List<Topic> topics = new ArrayList<Topic>(); try { NodeIterator iter = getNodeIteratorBySQLQuery(sProvider, buildSQLQueryGetTopicByDate(date, forumPath), 0, 0, false); Topic topic; while (iter.hasNext()) { Node node = iter.nextNode(); topic = new Topic(); topic.setId(node.getName()); topic.setPath(node.getPath()); topic.setIsActive(node.getProperty(EXO_IS_ACTIVE).getBoolean()); topic.setPostCount(node.getProperty(EXO_POST_COUNT).getLong()); topics.add(topic); } } catch (Exception e) { if (LOG.isDebugEnabled()) { LOG.debug("Failed to get all topic old", e); } } return topics; } public long getTotalTopicOld(long date, String forumPath) { SessionProvider sProvider = CommonUtils.createSystemProvider(); try { NodeIterator iter = getNodeIteratorBySQLQuery(sProvider, buildSQLQueryGetTopicByDate(date, forumPath), 0, 0, false); return iter.getSize(); } catch (Exception e) { return 0; } } /** * @deprecated use {@link #getTopicsByUser(TopicFilter, int, int)} */ public JCRPageList getPageTopicByUser(String userName, boolean isMod, String strOrderBy) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); try { TopicFilter filter = new TopicFilter(userName, isMod, strOrderBy); String sqlQuery = buildQueryTopicsByUser(filter, true); NodeIterator iter = getNodeIteratorBySQLQuery(sProvider, sqlQuery, 0, 0, false); return new ForumPageList(iter, 10, sqlQuery, true); } catch (Exception e) { return null; } } private String buildQueryTopicsByUser(TopicFilter filter, boolean hasOrder) { StringBuilder sqlQuery = new StringBuilder("SELECT * FROM ").append(EXO_TOPIC); sqlQuery.append(" WHERE ").append(Utils.getSQLQueryByProperty("", EXO_OWNER, filter.userName())); if (filter.isAdmin() == false) { sqlQuery.append(Utils.getSQLQueryByProperty("AND", EXO_IS_CLOSED, "false")) .append(Utils.getSQLQueryByProperty("AND", EXO_IS_WAITING, "false")) .append(Utils.getSQLQueryByProperty("AND", EXO_IS_ACTIVE, "true")) .append(Utils.getSQLQueryByProperty("AND", EXO_IS_ACTIVE_BY_FORUM, "true")) .append(Utils.getSQLQueryByProperty("AND", EXO_IS_APPROVED, "true")); } if (hasOrder == true) { sqlQuery.append(" ORDER BY ").append(EXO_IS_STICKY).append(DESC); if (Utils.isEmpty(filter.orderBy()) == false) { sqlQuery.append(",exo:").append(filter.orderBy()); if (EXO_CREATED_DATE.indexOf(filter.orderBy()) < 0) { sqlQuery.append(", ").append(EXO_CREATED_DATE).append(ASC); } } else { sqlQuery.append(", ").append(EXO_CREATED_DATE).append(ASC); } } return sqlQuery.toString(); } public List<Topic> getTopicsByUser(TopicFilter filter, int offset, int limit) throws Exception { // String userName, boolean isAdmin, String orderBy SessionProvider sProvider = CommonUtils.createSystemProvider(); try { NodeIterator iter = getNodeIteratorBySQLQuery(sProvider, buildQueryTopicsByUser(filter, true), offset, limit, true); List<Topic> topics = new ArrayList<Topic>(); while (iter.hasNext()) { Node node = iter.nextNode(); topics.add(getTopicNode(node)); } return topics; } catch (Exception e) { return null; } } public void modifyTopic(List<Topic> topics, int type) { SessionProvider sProvider = CommonUtils.createSystemProvider(); try { Node forumHomeNode = getForumHomeNode(sProvider); long topicCount = 0; long postCount = 0; Node forumNode = null; try { String topicPath = topics.get(0).getPath(); forumNode = (Node) forumHomeNode.getSession().getItem(topicPath).getParent(); topicCount = forumNode.getProperty(EXO_TOPIC_COUNT).getLong(); postCount = forumNode.getProperty(EXO_POST_COUNT).getLong(); } catch (PathNotFoundException e) { if (LOG.isDebugEnabled()) { LOG.debug("Failed to get node by path", e); } } Set<String> userIdsp = new HashSet<String>( new PropertyReader(forumNode).list(EXO_MODERATORS, new ArrayList<String>())); for (Topic topic : topics) { try { String topicPath = topic.getPath(); Node topicNode = (Node) forumHomeNode.getSession().getItem(topicPath); switch (type) { case Utils.CLOSE: { topicNode.setProperty(EXO_IS_CLOSED, topic.getIsClosed()); setActivePostByTopic(sProvider, topicNode, !(topic.getIsClosed())); break; } case Utils.LOCK: { topicNode.setProperty(EXO_IS_LOCK, topic.getIsLock()); break; } case Utils.APPROVE: { topicNode.setProperty(EXO_IS_APPROVED, topic.getIsApproved()); sendNotification(topicNode.getParent(), topic, null, new MessageBuilder(), true); setActivePostByTopic(sProvider, topicNode, topic.getIsApproved()); getTotalJobWatting(sProvider, userIdsp); break; } case Utils.STICKY: { topicNode.setProperty(EXO_IS_STICKY, topic.getIsSticky()); break; } case Utils.WAITING: { boolean isWaiting = topic.getIsWaiting(); topicNode.setProperty(EXO_IS_WAITING, isWaiting); setActivePostByTopic(sProvider, topicNode, !(isWaiting)); if (!isWaiting) { sendNotification(topicNode.getParent(), topic, null, new MessageBuilder(), true); } getTotalJobWatting(sProvider, userIdsp); break; } case Utils.ACTIVE: { topicNode.setProperty(EXO_IS_ACTIVE, topic.getIsActive()); setActivePostByTopic(sProvider, topicNode, topic.getIsActive()); getTotalJobWatting(sProvider, userIdsp); break; } case Utils.CHANGE_NAME: { topicNode.setProperty(EXO_NAME, topic.getTopicName()); try { Node nodeFirstPost = topicNode .getNode(topicNode.getName().replaceFirst(Utils.TOPIC, Utils.POST)); nodeFirstPost.setProperty(EXO_NAME, topic.getTopicName()); } catch (PathNotFoundException e) { if (LOG.isDebugEnabled()) { LOG.debug("Failed to get node by path", e); } } break; } case Utils.VOTE_RATING: { topicNode.setProperty(EXO_USER_VOTE_RATING, topic.getUserVoteRating()); topicNode.setProperty(EXO_VOTE_RATING, topic.getVoteRating()); break; } default: break; } if (type == Utils.APPROVE || type == Utils.WAITING) { if (!topic.getIsWaiting() && topic.getIsApproved()) { topicCount = topicCount + 1; postCount = postCount + (topicNode.getProperty(EXO_POST_COUNT).getLong() + 1); } } if ((type == Utils.APPROVE || type == Utils.WAITING || type == Utils.ACTIVE || type == Utils.CLOSE) || forumNode.hasProperty(EXO_LAST_TOPIC_PATH) || (forumNode.getProperty(EXO_LAST_TOPIC_PATH).getString().equals(topicNode.getName()) || Utils.isEmpty(forumNode.getProperty(EXO_LAST_TOPIC_PATH).getString()))) { queryLastTopic(sProvider, forumNode.getPath()); } } catch (PathNotFoundException e) { if (LOG.isDebugEnabled()) { LOG.debug("Failed to get node by path", e); } } } if (type == Utils.APPROVE || type == Utils.WAITING) { forumNode.setProperty(EXO_TOPIC_COUNT, topicCount); forumNode.setProperty(EXO_POST_COUNT, postCount); } if (forumNode.isNew()) { forumNode.getSession().save(); } else { forumNode.save(); } } catch (Exception e) { LOG.error("Failed to modify topic.", e); } } public void updateProfileAddTopic(String owner) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { Node profileHomeNode = getUserProfileHome(sProvider); if (profileHomeNode.hasNode(owner)) { Node profileNode = profileHomeNode.getNode(owner); long totalTopicByUser = profileNode.getProperty(EXO_TOTAL_TOPIC).getLong(); profileNode.setProperty(EXO_TOTAL_TOPIC, totalTopicByUser + 1); } else if (Utils.isEmpty(owner) == false) { Node newProfileNode = profileHomeNode.addNode(owner, EXO_FORUM_USER_PROFILE); newProfileNode.setProperty(EXO_USER_ID, owner); newProfileNode.setProperty(EXO_USER_TITLE, Utils.USER); if (isAdminRole(sProvider, owner)) { newProfileNode.setProperty(EXO_USER_TITLE, Utils.ADMIN); } newProfileNode.setProperty(EXO_TOTAL_TOPIC, 1); } // profileHomeNode.getSession().save(); } catch (Exception e) { LOG.warn("Failed to update user profile when add topic", e); } finally { sProvider.close(); } } public String getOwner(String path) { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { Node node = getNodeAt(sProvider, path); return new PropertyReader(node).string(EXO_OWNER, ""); } catch (Exception e) { return null; } finally { sProvider.close(); } } public void saveTopic(String categoryId, String forumId, Topic topic, boolean isNew, boolean isMove, MessageBuilder messageBuilder) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); try { Node forumNode = getCategoryHome(sProvider).getNode(categoryId + "/" + forumId); Node topicNode; boolean isChangeClose = false; if (isNew) { topicNode = forumNode.addNode(topic.getId(), EXO_TOPIC); topicNode.setProperty(EXO_ID, topic.getId()); topicNode.setProperty(EXO_OWNER, topic.getOwner()); Calendar calendar = getGreenwichMeanTime(); topic.setCreatedDate(calendar.getTime()); topicNode.setProperty(EXO_CREATED_DATE, calendar); topicNode.setProperty(EXO_LAST_POST_BY, topic.getOwner()); if (isMove && topic.getLastPostDate() != null) { calendar.setTime(topic.getLastPostDate()); } topicNode.setProperty(EXO_LAST_POST_DATE, calendar); topicNode.setProperty(EXO_POST_COUNT, -1); topicNode.setProperty(EXO_VIEW_COUNT, 0); topicNode.setProperty(EXO_TAG_ID, topic.getTagId()); topicNode.setProperty(EXO_IS_ACTIVE_BY_FORUM, true); topicNode.setProperty(EXO_IS_POLL, topic.getIsPoll()); topicNode.setProperty(EXO_LINK, topic.getLink()); topicNode.setProperty(EXO_PATH, forumId); if (!forumNode.getProperty(EXO_IS_MODERATE_TOPIC).getBoolean() && !topic.getIsWaiting()) { long newTopicCount = forumNode.getProperty(EXO_TOPIC_COUNT).getLong() + 1; forumNode.setProperty(EXO_TOPIC_COUNT, newTopicCount); } // sendNotification(forumNode, topic, null, messageBuilder, true); } else { topicNode = forumNode.getNode(topic.getId()); isChangeClose = (topic.getIsClosed() != topicNode.getProperty(EXO_IS_CLOSED).getBoolean()); } topicNode.setProperty(EXO_NAME, topic.getTopicName()); topicNode.setProperty(EXO_MODIFIED_BY, topic.getModifiedBy()); topicNode.setProperty(EXO_MODIFIED_DATE, getGreenwichMeanTime()); topicNode.setProperty(EXO_DESCRIPTION, topic.getDescription()); topicNode.setProperty(EXO_ICON, topic.getIcon()); topicNode.setProperty(EXO_IS_MODERATE_POST, topic.getIsModeratePost()); topicNode.setProperty(EXO_IS_NOTIFY_WHEN_ADD_POST, topic.getIsNotifyWhenAddPost()); topicNode.setProperty(EXO_IS_CLOSED, topic.getIsClosed()); topicNode.setProperty(EXO_IS_LOCK, topic.getIsLock()); topicNode.setProperty(EXO_IS_APPROVED, topic.getIsApproved()); topicNode.setProperty(EXO_IS_STICKY, topic.getIsSticky()); topicNode.setProperty(EXO_IS_WAITING, topic.getIsWaiting()); topicNode.setProperty(EXO_IS_ACTIVE, topic.getIsActive()); topicNode.setProperty(EXO_USER_VOTE_RATING, topic.getUserVoteRating()); topicNode.setProperty(EXO_VOTE_RATING, topic.getVoteRating()); topicNode.setProperty(EXO_NUMBER_ATTACHMENTS, topic.getNumberAttachment()); topicNode.setProperty(EXO_CAN_POST, convertArray(topic.getCanPost())); topicNode.setProperty(EXO_CAN_VIEW, convertArray(topic.getCanView())); if (isNew) { forumNode.getSession().save(); } else { forumNode.save(); } // topic.setPath(topicNode.getPath()); // if (topic.getIsWaiting() || !topic.getIsApproved()) { getTotalJobWatting(sProvider, new HashSet<String>( new PropertyReader(forumNode).list(EXO_MODERATORS, new ArrayList<String>()))); } if (isNew || isChangeClose) { queryLastTopic(sProvider, forumNode.getPath()); } if (!isMove) { if (isNew) { // createPost first String id = topic.getId().replaceFirst(Utils.TOPIC, Utils.POST); Post post = new Post(); post.setId(id); post.setOwner(topic.getOwner()); post.setCreatedDate(new Date()); post.setName(topic.getTopicName()); post.setMessage(topic.getDescription()); post.setRemoteAddr(""); post.setIcon(topic.getIcon()); post.setIsApproved(true); post.setAttachments(topic.getAttachments()); post.setUserPrivate(new String[] { EXO_USER_PRI }); post.setLink(topic.getLink()); post.setRemoteAddr(topic.getRemoteAddr()); savePost(categoryId, forumId, topic.getId(), post, true, messageBuilder); } else { String id = topic.getId().replaceFirst(Utils.TOPIC, Utils.POST); if (topicNode.hasNode(id)) { Node fistPostNode = topicNode.getNode(id); Post post = getPost(fistPostNode); post.setModifiedBy(topic.getModifiedBy()); post.setModifiedDate(new Date()); post.setEditReason(topic.getEditReason()); post.setName(topic.getTopicName()); post.setMessage(topic.getDescription()); post.setIcon(topic.getIcon()); post.setAttachments(topic.getAttachments()); savePost(categoryId, forumId, topic.getId(), post, false, messageBuilder); } } } } catch (Exception e) { LOG.error("Failed to save topic", e); } } private Map<String, Long> getDeletePostByUser(SessionProvider sProvider, Node node) throws Exception { Map<String, Long> userPostMap = new HashMap<String, Long>(); StringBuilder sqlQuery = new StringBuilder(); if (node.isNodeType(EXO_TOPIC)) { sqlQuery = jcrPathLikeAndNotLike(EXO_POST, node.getPath()); } else if (node.isNodeType(EXO_FORUM) || node.isNodeType(EXO_FORUM_CATEGORY)) { sqlQuery.append("SELECT * FROM ").append(EXO_POST).append(" WHERE ").append(JCR_PATH).append(" LIKE '") .append(node.getPath()).append("/%'"); } NodeIterator iter = getNodeIteratorBySQLQuery(sProvider, sqlQuery.toString(), 0, 0, false); Node post = null; String owner = null; while (iter.hasNext()) { post = iter.nextNode(); try { owner = post.getProperty(EXO_OWNER).getString(); userPostMap.put(owner, (userPostMap.get(owner) != null ? userPostMap.get(owner) : 0) + 1); } catch (Exception e) { } } return userPostMap; } public void updateUserProfileInfo(String name) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); try { Node userProfileHome = getUserProfileHome(sProvider); Node userNode = null; Map<String, Long> userPostMap = (HashMap<String, Long>) infoMap.get(name); for (Map.Entry<String, Long> entry : userPostMap.entrySet()) { String user = entry.getKey(); try { userNode = userProfileHome.getNode(user); long totalPost = userNode.getProperty(EXO_TOTAL_POST).getLong(); userNode.setProperty(EXO_TOTAL_POST, totalPost - userPostMap.get(user)); userNode.save(); } catch (PathNotFoundException e) { LOG.debug("UserProfile of user: " + user + " not existing."); } } infoMap.remove(name); } catch (Exception e) { if (LOG.isDebugEnabled()) { LOG.debug("Failed to update user profile info", e); } } } private void addUpdateUserProfileJob(Map<String, Long> userPostMap) { try { Calendar cal = new GregorianCalendar(); PeriodInfo periodInfo = new PeriodInfo(cal.getTime(), null, 1, 86400000); String name = String.valueOf(cal.getTime().getTime()); JobInfo info = new JobInfo(name, KNOWLEDGE_SUITE_FORUM_JOBS, UpdateUserProfileJob.class); JobSchedulerService schedulerService = CommonsUtils.getService(JobSchedulerService.class); String repoName = CommonsUtils.getRepository().getConfiguration().getName(); JobDataMap jdatamap = new JobDataMap(); jdatamap.put(Utils.CACHE_REPO_NAME, repoName); infoMap.put(name, userPostMap); schedulerService.addPeriodJob(info, periodInfo, jdatamap); } catch (Exception e) { if (LOG.isDebugEnabled()) { LOG.debug("Failed to add job for update user profile ", e); } } } public Topic removeTopic(String categoryId, String forumId, String topicId) { SessionProvider sProvider = CommonUtils.createSystemProvider(); try { Node forumNode = getCategoryHome(sProvider).getNode(categoryId + "/" + forumId); Topic topic = getTopic(categoryId, forumId, topicId, UserProfile.USER_GUEST); Node topicNode = forumNode.getNode(topicId); PropertyReader readerFor = new PropertyReader(forumNode); Map<String, Long> userPostMap = getDeletePostByUser(sProvider, topicNode); if (topic.getIsApproved() && !topic.getIsWaiting()) { // update TopicCount for Forum forumNode.setProperty(EXO_TOPIC_COUNT, readerFor.l(EXO_TOPIC_COUNT) - 1); // update PostCount for Forum long newPostCount = readerFor.l(EXO_POST_COUNT) - (topic.getPostCount() + 1); forumNode.setProperty(EXO_POST_COUNT, (newPostCount > 0) ? newPostCount : 0); } topicNode.remove(); forumNode.save(); if (!topic.getIsActive() || !topic.getIsApproved() || topic.getIsWaiting()) { getTotalJobWatting(sProvider, new HashSet<String>(readerFor.list(EXO_MODERATORS, new ArrayList<String>()))); } queryLastTopic(sProvider, forumNode.getPath()); try { calculateLastRead(sProvider, null, forumId, topicId); } catch (Exception e) { if (LOG.isDebugEnabled()) { LOG.debug("Failed to update last read topic", e); } } addUpdateUserProfileJob(userPostMap); return topic; } catch (Exception e) { LOG.error("Failed to remove topic", e); return null; } } private String getEmailUser(SessionProvider sProvider, String userId) throws Exception { return new PropertyReader(getUserProfileNode(sProvider, userId)).string(EXO_EMAIL, CommonUtils.EMPTY_STR); } public void moveTopic(List<Topic> topics, String destForumPath, String mailContent, String link) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); Node forumHomeNode = getForumHomeNode(sProvider); long tmp = 0; String forumName = null; Node destForumNode = (Node) forumHomeNode.getSession().getItem(destForumPath); PropertyReader destForumReader = new PropertyReader(destForumNode); forumName = destForumReader.string(EXO_NAME); String owner = destForumReader.string(EXO_OWNER); if (!Utils.isEmpty(owner) && owner.indexOf(":") > 0) { owner = ForumServiceUtils.getUserPermission(new String[] { owner }).get(0); } if (Utils.isEmpty(owner)) { owner = topics.get(0).getEditReason(); } String headerSubject = new StringBuilder("[") .append(new PropertyReader(destForumNode.getParent()).string(EXO_NAME)).append("][") .append(forumName).append("] ").toString(); MessageBuilder messageBuilder = getInfoMessageMove(sProvider, mailContent, headerSubject, true); messageBuilder.setOwner(getScreenName(sProvider, owner)); messageBuilder.setAddType(forumName); messageBuilder.setTypes(Utils.FORUM, Utils.TOPIC, CommonUtils.EMPTY_STR, CommonUtils.EMPTY_STR); // ----------------------- finish ---------------------- String destForumId = destForumNode.getName(), srcForumId = CommonUtils.EMPTY_STR; for (Topic topic : topics) { String topicPath = topic.getPath(); String newTopicPath = destForumPath + "/" + topic.getId(); // Forum remove Topic(srcForum) Node srcForumNode = (Node) forumHomeNode.getSession().getItem(topicPath).getParent(); srcForumId = srcForumNode.getName(); // Move Topic forumHomeNode.getSession().getWorkspace().move(topicPath, newTopicPath); // Set TopicCount srcForum tmp = srcForumNode.getProperty(EXO_TOPIC_COUNT).getLong(); if (tmp > 0) tmp = tmp - 1; else tmp = 0; srcForumNode.setProperty(EXO_TOPIC_COUNT, tmp); // setPath for srcForum queryLastTopic(sProvider, srcForumNode.getPath()); // Topic Move Node topicNode = (Node) forumHomeNode.getSession().getItem(newTopicPath); topicNode.setProperty(EXO_PATH, destForumNode.getName()); long topicPostCount = topicNode.getProperty(EXO_POST_COUNT).getLong() + 1; // Forum add Topic (destForum) destForumNode.setProperty(EXO_TOPIC_COUNT, destForumReader.l(EXO_TOPIC_COUNT) + 1); // setPath destForum queryLastTopic(sProvider, destForumNode.getPath()); // Set PostCount tmp = srcForumNode.getProperty(EXO_POST_COUNT).getLong(); if (tmp > topicPostCount) tmp = tmp - topicPostCount; else tmp = 0; srcForumNode.setProperty(EXO_POST_COUNT, tmp); destForumNode.setProperty(EXO_POST_COUNT, destForumReader.l(EXO_POST_COUNT) + topicPostCount); // send email after move topic: messageBuilder.setObjName(topic.getTopicName()); messageBuilder.setHeaderSubject(messageBuilder.getHeaderSubject() + topic.getTopicName()); messageBuilder.setLink(link.replaceFirst("pathId", topic.getId())); Set<String> set = new HashSet<String>(); // set email author this topic set.add(getEmailUser(sProvider, topic.getOwner())); // set email watch this topic, forum, category parent of this topic set.addAll(calculateMoveEmail(topicNode)); // set email watch old category, forum parent of this topic set.addAll(calculateMoveEmail(srcForumNode)); if (!Utils.isEmpty(set.toArray(new String[set.size()]))) { sendEmailNotification(new ArrayList<String>(set), messageBuilder.getContentEmailMoved()); } try { calculateLastRead(sProvider, destForumId, srcForumId, topic.getId()); } catch (Exception e) { if (LOG.isDebugEnabled()) { LOG.debug("Failed to calculate last read", e); } } } if (forumHomeNode.isNew()) { forumHomeNode.getSession().save(); } else { forumHomeNode.save(); } } private Set<String> calculateMoveEmail(Node node) throws Exception { Set<String> set = new HashSet<String>(); while (!node.getName().equals(KSDataLocation.Locations.FORUM_CATEGORIES_HOME)) { if (node.isNodeType(EXO_FORUM_WATCHING)) { set.addAll(new PropertyReader(node).list(EXO_EMAIL_WATCHING, new ArrayList<String>())); } node = node.getParent(); } return set; } private void calculateLastRead(SessionProvider sProvider, String destForumId, String srcForumId, String topicId) throws Exception { Node profileHome = getUserProfileHome(sProvider); StringBuilder sqlQuery = jcrPathLikeAndNotLike(EXO_FORUM_USER_PROFILE, profileHome.getPath()); sqlQuery.append(" AND ").append(EXO_LAST_READ_POST_OF_FORUM).append(" LIKE '%").append(topicId) .append("%'"); // sqlQuery.append("AND (CONTAINS (").append(EXO_LAST_READ_POST_OF_FORUM).append(", '").append(topicId).append("'))"); NodeIterator iter = getNodeIteratorBySQLQuery(sProvider, sqlQuery.toString(), 0, 0, false); List<String> list; List<String> list2; while (iter.hasNext()) { list = new ArrayList<String>(); list2 = new ArrayList<String>(); Node profileNode = iter.nextNode(); PropertyReader reader = new PropertyReader(profileNode); list = reader.list(EXO_LAST_READ_POST_OF_FORUM, new ArrayList<String>()); list2 = new ArrayList<String>(list); boolean isRead = false; for (String string : list) { if (destForumId != null && string.indexOf(destForumId) >= 0) { // this forum is read, can check last access topic of forum and topic isRead = true; try { long lastAccessTopicTime = 0; long lastAccessForumTime = 0; // check last read of src topic List<String> readTopics = reader.list(EXO_READ_TOPIC, new ArrayList<String>()); for (String tpId : readTopics) {// for only run one. String[] info = tpId.split(CommonUtils.COLON); if (tpId.indexOf(topicId) >= 0 && info.length > 1) { lastAccessTopicTime = Long.parseLong(info[1]); if (lastAccessTopicTime > 0) {// check last read dest forum List<String> values = reader.list(EXO_READ_FORUM, new ArrayList<String>()); for (String str : values) {// for only run one. if (str.indexOf(destForumId) >= 0) { if (str.indexOf(CommonUtils.COLON) > 0) { lastAccessForumTime = Long .parseLong(str.split(CommonUtils.COLON)[1]); break; } } } } if (lastAccessTopicTime > lastAccessForumTime) { list2.remove(string); list2.add(destForumId + CommonUtils.COMMA + info[0] + CommonUtils.SLASH + info[1]); // replace topic,postId } break; } } } catch (Exception e) { LOG.warn("Can not calculate last read of user: " + profileNode.getName()); } } if (string.indexOf(srcForumId) >= 0) {// remove last read src forum if last read this forum is this topic. list2.remove(string); } } if (!isRead && destForumId != null) { list2.add(destForumId + CommonUtils.COMMA + topicId + CommonUtils.SLASH + topicId.replace(Utils.TOPIC, Utils.POST)); } profileNode.setProperty(EXO_LAST_READ_POST_OF_FORUM, list2.toArray(new String[list2.size()])); } profileHome.save(); } public long getLastReadIndex(String path, String isApproved, String isHidden, String userLogin) { SessionProvider sProvider = CommonUtils.createSystemProvider(); try { Node catNode = getCategoryHome(sProvider); Node postNode = catNode.getNode(path); if (postNode != null) { String topicPath = postNode.getParent().getPath(); StringBuilder sqlQuery = jcrPathLikeAndNotLike(EXO_POST, topicPath); String query = Utils.getSQLQuery(isApproved, isHidden, isHidden, userLogin).toString(); if (query.isEmpty() == false) { sqlQuery.append(" AND (").append(sqlQuery).append(")"); } Calendar cal = postNode.getProperty(EXO_CREATED_DATE).getDate(); sqlQuery.append(" AND (").append(EXO_CREATED_DATE).append(" <= TIMESTAMP '") .append(ISO8601.format(cal)).append("')"); // NodeIterator iter = getNodeIteratorBySQLQuery(sProvider, sqlQuery.toString(), 0, 0, false); long size = iter.getSize(); boolean isView = false; while (iter.hasNext()) { if (iter.nextNode().getName().equals(postNode.getName())) { isView = true; break; } } // if user can not view post open, return page 1. if (isView == false) { size = 1; } return size; } } catch (Exception e) { if (LOG.isDebugEnabled()) { LOG.debug("Exception occurs when get last read index", e); } } return 0; } /** * @deprecated use {@link #getPostsSplitTopic(PostFilter, int, int)} */ public JCRPageList getPostForSplitTopic(String topicPath) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); try { PostFilter filter = new PostFilter(topicPath); String sqlQuery = makePostsSplitSQLQuery(filter, true); NodeIterator iter = getNodeIteratorBySQLQuery(sProvider, sqlQuery, 0, 0, false); return new ForumPageList(iter, 10, sqlQuery.toString(), true); } catch (PathNotFoundException e) { if (LOG.isDebugEnabled()) { LOG.debug("Failed to get post for split topic.", e); } } return null; } private String makePostsSplitSQLQuery(PostFilter filter, boolean hasOrder) throws Exception { StringBuilder topicPath = new StringBuilder(); if (filter.getTopicPath().indexOf(dataLocator.getForumCategoriesLocation()) > 0) { topicPath.append(filter.getTopicPath()); } else { topicPath.append("/").append(dataLocator.getForumCategoriesLocation()).append("/") .append(filter.getTopicPath()); } StringBuilder sqlQuery = jcrPathLikeAndNotLike(EXO_POST, topicPath.toString()); sqlQuery.append(Utils.getSQLQueryByProperty("AND", EXO_USER_PRIVATE, EXO_USER_PRIVATE)) .append(Utils.getSQLQueryByProperty("AND", EXO_IS_FIRST_POST, "false")); if (hasOrder) { sqlQuery.append(" ORDER BY ").append(EXO_CREATED_DATE).append(" ASC"); } return sqlQuery.toString(); } public List<Post> getPostsSplitTopic(PostFilter filter, int offset, int limit) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); try { String sqlQuery = makePostsSplitSQLQuery(filter, true); // NodeIterator iter = getNodeIteratorBySQLQuery(sProvider, sqlQuery, 0, 0, false); return getPosts(iter); } catch (PathNotFoundException e) { if (LOG.isDebugEnabled()) { LOG.debug("Failed to get post for split topic.", e); } } return null; } /** * @deprecated use {@link #getPosts(PostFilter, int, int)} */ public JCRPageList getPosts(String categoryId, String forumId, String topicId, String isApproved, String isHidden, String strQuery, String userLogin) throws Exception { try { String isWaiting = strQuery.equals("true") || strQuery.equals("false") ? strQuery : ""; PostFilter filter = new PostFilter(categoryId, forumId, topicId, isApproved, isHidden, isWaiting, userLogin); if (!Utils.isEmpty(strQuery)) { throw new NotSupportedException("The method not support add more query."); } return new ForumPageList(null, 10, makePostsSQLQuery(filter, true), true); } catch (PathNotFoundException e) { return null; } } private String makePostsSQLQuery(PostFilter filter, boolean hasOrder) throws Exception { String topicPath = filter.getTopicPath(); if (Utils.isEmpty(topicPath)) { topicPath = new StringBuffer("/").append(dataLocator.getForumCategoriesLocation()).append("/") .append(filter.getCategoryId()).append("/").append(filter.getForumId()).append("/") .append(filter.getTopicId()).toString(); } StringBuilder strBuilder = jcrPathLikeAndNotLike(EXO_POST, topicPath); String sqlQuery = Utils.getSQLQuery(filter.getIsApproved(), filter.getIsHidden(), filter.getIsWaiting(), filter.getUserLogin()).toString(); if (sqlQuery.isEmpty() == false) { strBuilder.append(" AND (").append(sqlQuery).append(")"); } if (hasOrder) { strBuilder.append(" ORDER BY ").append(EXO_CREATED_DATE).append(ASC); } return strBuilder.toString(); } @Override public List<Post> getPosts(PostFilter filter, int offset, int limit) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); try { NodeIterator iter = getNodeIteratorBySQLQuery(sProvider, makePostsSQLQuery(filter, true), offset, limit, false); return getPosts(iter); } catch (Exception e) { logDebug("Failed to get posts by filter of topic " + filter.getTopicId(), e); return new ArrayList<Post>(); } } private List<Post> getPosts(NodeIterator iter) throws Exception { Node currentNode = null; List<Post> posts = new ArrayList<Post>((int) iter.getSize()); while (iter.hasNext()) { currentNode = iter.nextNode(); posts.add(getPost(currentNode)); } return posts; } public int getPostsCount(PostFilter filter) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); try { if (filter.isSplit()) { return (int) getNodeIteratorBySQLQuery(sProvider, makePostsSplitSQLQuery(filter, false), 0, 0, false).getSize(); } else if (Utils.isEmpty(filter.userName()) == false) { return (int) getNodeIteratorBySQLQuery(sProvider, queryPostsByUser(filter, false), 0, 0, false) .getSize(); } else if (Utils.isEmpty(filter.getIP()) == false) { return (int) getNodeIteratorBySQLQuery(sProvider, queryPostsByIP(filter, false), 0, 0, false) .getSize(); } // return (int) getNodeIteratorBySQLQuery(sProvider, makePostsSQLQuery(filter, false), 0, 0, false) .getSize(); } catch (Exception e) { return 0; } } public long getAvailablePost(String categoryId, String forumId, String topicId, String isApproved, String isHidden, String userLogin) throws Exception { PostFilter filter = new PostFilter(categoryId, forumId, topicId, isApproved, isHidden, isHidden, userLogin); return getPostsCount(filter); } public JCRPageList getPagePostByUser(String userName, String userId, boolean isMod, String strOrderBy) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); try { String query = queryPostsByUser(new PostFilter(userName, userId, isMod, strOrderBy), true); NodeIterator iter = getNodeIteratorBySQLQuery(sProvider, query, 0, 0, false); return new ForumPageList(iter, 10, query, true); } catch (Exception e) { return null; } } private String queryPostsByUser(PostFilter filter, boolean hasOrder) { StringBuilder sqlQuery = new StringBuilder("SELECT * FROM ").append(EXO_POST); sqlQuery.append(" WHERE ").append(Utils.getSQLQueryByProperty("", EXO_IS_FIRST_POST, "false")) .append(Utils.getSQLQueryByProperty("", EXO_OWNER, filter.userName())); if (filter.isAdmin() == false) { sqlQuery.append(Utils.getSQLQueryByProperty("AND", EXO_IS_APPROVED, "true")) .append(Utils.getSQLQueryByProperty("AND", EXO_IS_HIDDEN, "false")) .append(Utils.getSQLQueryByProperty("AND", EXO_IS_ACTIVE_BY_TOPIC, "true")) .append(Utils.getSQLQueryByProperty("AND", EXO_IS_WAITING, "false")); } sqlQuery.append(" AND (").append(Utils.getSQLQueryByProperty("", EXO_USER_PRIVATE, filter.getUserLogin())) .append(Utils.getSQLQueryByProperty("OR", EXO_USER_PRIVATE, EXO_USER_PRI)).append(")"); if (hasOrder) { sqlQuery.append(" ORDER BY "); if (!Utils.isEmpty(filter.orderBy())) { sqlQuery.append(filter.orderBy()); if (filter.orderBy().indexOf(EXO_CREATED_DATE) < 0) { sqlQuery.append(", ").append(EXO_CREATED_DATE).append(DESC); } } else { sqlQuery.append(EXO_CREATED_DATE).append(DESC); } } return sqlQuery.toString(); } public List<Post> getPostsByUser(PostFilter filter, int offset, int limit) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); try { String sqlQuery = queryPostsByUser(filter, true); NodeIterator iter = getNodeIteratorBySQLQuery(sProvider, sqlQuery, offset, limit, false); return getPosts(iter); } catch (Exception e) { return null; } } public Post getPost(String categoryId, String forumId, String topicId, String postId) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); try { Node categoryHome = getCategoryHome(sProvider); Node postNode; if (postId.lastIndexOf("/") > 0) { if (postId.indexOf(categoryHome.getName()) < 0) postId = categoryHome.getPath() + "/" + postId; postNode = (Node) categoryHome.getSession().getItem(postId); } else { postNode = categoryHome.getNode(categoryId + "/" + forumId + "/" + topicId + "/" + postId); } return getPost(postNode); } catch (PathNotFoundException e) { return null; } } public JCRPageList getListPostsByIP(String ip, String strOrderBy) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); try { String pathQuery = queryPostsByIP(new PostFilter(ip, strOrderBy), true); // NodeIterator iter = getNodeIteratorBySQLQuery(sProvider, pathQuery, 0, 0, false); return new ForumPageList(iter, 5, pathQuery, true); } catch (Exception e) { return null; } } private String queryPostsByIP(PostFilter filter, boolean hasOrder) { StringBuilder sqlQuery = new StringBuilder("SELECT ").append(EXO_REMOTE_ADDR).append(" FROM ") .append(EXO_POST); sqlQuery.append(" WHERE ").append(Utils.getSQLQueryByProperty("", EXO_REMOTE_ADDR, filter.getIP())); if (hasOrder) { if (Utils.isEmpty(filter.orderBy())) { sqlQuery.append(" ORDER BY ").append(EXO_LAST_POST_DATE).append(DESC); } else { sqlQuery.append(" ORDER BY exo:").append(filter.orderBy()); if (EXO_LAST_POST_DATE.indexOf(filter.orderBy()) < 0) { sqlQuery.append(", ").append(EXO_LAST_POST_DATE).append(DESC); } } } return sqlQuery.toString(); } public List<Post> getPostsByIP(PostFilter filter, int offset, int limit) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); try { NodeIterator iter = getNodeIteratorBySQLQuery(sProvider, queryPostsByIP(filter, true), offset, limit, false); List<Post> posts = new ArrayList<Post>((int) iter.getSize()); Node currentNode; while (iter.hasNext()) { currentNode = iter.nextNode(); posts.add(getPost(currentNode)); } return posts; } catch (Exception e) { return null; } } public Post getPost(Node postNode) throws Exception { Post postNew = new Post(); PropertyReader reader = new PropertyReader(postNode); postNew.setId(postNode.getName()); postNew.setPath(postNode.getPath()); postNew.setOwner(reader.string(EXO_OWNER)); postNew.setCreatedDate(reader.date(EXO_CREATED_DATE)); postNew.setModifiedBy(reader.string(EXO_MODIFIED_BY)); postNew.setModifiedDate(reader.date(EXO_MODIFIED_DATE)); postNew.setEditReason(reader.string(EXO_EDIT_REASON)); postNew.setName(reader.string(EXO_NAME)); postNew.setMessage(reader.string(EXO_MESSAGE)); postNew.setRemoteAddr(reader.string(EXO_REMOTE_ADDR)); postNew.setIcon(reader.string(EXO_ICON)); postNew.setLink(reader.string(EXO_LINK)); postNew.setIsApproved(reader.bool(EXO_IS_APPROVED)); postNew.setIsHidden(reader.bool(EXO_IS_HIDDEN)); postNew.setIsWaiting(reader.bool(EXO_IS_WAITING)); postNew.setFirstPost(reader.bool(EXO_IS_FIRST_POST)); postNew.setIsActiveByTopic(reader.bool(EXO_IS_ACTIVE_BY_TOPIC)); postNew.setUserPrivate(reader.strings(EXO_USER_PRIVATE)); postNew.setNumberAttach(reader.l(EXO_NUMBER_ATTACH)); if (postNew.getNumberAttach() > 0) { postNew.setAttachments(getAttachmentsByNode(postNode)); } return postNew; } private static ForumAttachment getAttachment(Node nodeContent) throws Exception { try { if (nodeContent.isNodeType(EXO_FORUM_ATTACHMENT) || nodeContent.isNodeType(NT_FILE)) { BufferAttachment attachment = new BufferAttachment(); PropertyReader readerContent = new PropertyReader(nodeContent.getNode(JCR_CONTENT)); attachment.setId(nodeContent.getName()); attachment.setPathNode(nodeContent.getPath()); attachment.setMimeType(readerContent.string(JCR_MIME_TYPE, CommonUtils.EMPTY_STR)); attachment.setSize(readerContent.stream(JCR_DATA).available()); String workspace = nodeContent.getSession().getWorkspace().getName(); attachment.setWorkspace(workspace); attachment.setPath(CommonUtils.SLASH + workspace + nodeContent.getPath()); String fileName = readerContent.string(EXO_FILE_NAME); if (CommonUtils.isEmpty(fileName)) { String type = attachment.getMimeType(); if (type.indexOf(CommonUtils.SLASH) > 0) { type = type.substring(type.indexOf(CommonUtils.SLASH) + 1); } fileName = "avatar." + type; } attachment.setName(fileName); return attachment; } } catch (Exception e) { logDebug("Failed to get attachment in node: " + nodeContent.getName()); } return null; } public static List<ForumAttachment> getAttachmentsByNode(Node node) throws Exception { List<ForumAttachment> attachments = new ArrayList<ForumAttachment>(); NodeIterator postAttachments = node.getNodes(); while (postAttachments.hasNext()) { Node nodeAttatch = postAttachments.nextNode(); ForumAttachment attachment = getAttachment(nodeAttatch); if (attachment != null) { attachments.add(attachment); } } return attachments; } public void updateProfileAddPost(String owner) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { Node profileHomeNode = getUserProfileHome(sProvider); if (profileHomeNode.hasNode(owner)) { Node profileNode = profileHomeNode.getNode(owner); long totalPostByUser = 0; totalPostByUser = profileNode.getProperty(EXO_TOTAL_POST).getLong(); profileNode.setProperty(EXO_TOTAL_POST, totalPostByUser + 1); profileNode.setProperty(EXO_LAST_POST_DATE, getGreenwichMeanTime()); } else if (Utils.isEmpty(owner) == false) { Node profileNode = profileHomeNode.addNode(owner, EXO_FORUM_USER_PROFILE); profileNode.setProperty(EXO_USER_ID, owner); profileNode.setProperty(EXO_USER_TITLE, Utils.USER); if (isAdminRole(sProvider, owner)) { profileNode.setProperty(EXO_USER_TITLE, Utils.ADMIN); } profileNode.setProperty(EXO_TOTAL_POST, 1); profileNode.setProperty(EXO_LAST_POST_DATE, getGreenwichMeanTime()); } profileHomeNode.getSession().save(); } catch (Exception e) { LOG.warn("Failed to save user profile of user: " + owner); } finally { sProvider.close(); } } private void postSaveProperties(Node postNode, Post post) throws Exception { if (post.getModifiedBy() != null && post.getModifiedBy().length() > 0) { postNode.setProperty(EXO_MODIFIED_BY, post.getModifiedBy()); postNode.setProperty(EXO_MODIFIED_DATE, getGreenwichMeanTime()); postNode.setProperty(EXO_EDIT_REASON, post.getEditReason()); } postNode.setProperty(EXO_NAME, post.getName()); postNode.setProperty(EXO_MESSAGE, post.getMessage()); postNode.setProperty(EXO_REMOTE_ADDR, post.getRemoteAddr()); postNode.setProperty(EXO_ICON, post.getIcon()); postNode.setProperty(EXO_IS_APPROVED, post.getIsApproved()); postNode.setProperty(EXO_IS_HIDDEN, post.getIsHidden()); postNode.setProperty(EXO_IS_WAITING, post.getIsWaiting()); postNode.setProperty(EXO_NUMBER_ATTACH, post.getNumberAttach()); } private List<String> postAttachment(Node postNode, Post post) { List<String> listFileName = new ArrayList<String>(); List<ForumAttachment> attachments = post.getAttachments(); if (attachments != null) { Iterator<ForumAttachment> it = attachments.iterator(); for (ForumAttachment attachment : attachments) { BufferAttachment file = null; listFileName.add(attachment.getId()); try { file = (BufferAttachment) it.next(); Node nodeFile = null; if (!postNode.hasNode(file.getId())) nodeFile = postNode.addNode(file.getId(), EXO_FORUM_ATTACHMENT); else nodeFile = postNode.getNode(file.getId()); // Fix permission node ForumServiceUtils.reparePermissions(nodeFile, "any"); Node nodeContent = null; if (!nodeFile.hasNode(JCR_CONTENT)) { nodeContent = nodeFile.addNode(JCR_CONTENT, EXO_FORUM_RESOURCE); nodeContent.setProperty(JCR_MIME_TYPE, file.getMimeType()); nodeContent.setProperty(JCR_DATA, file.getInputStream()); nodeContent.setProperty(JCR_LAST_MODIFIED, Calendar.getInstance().getTimeInMillis()); nodeContent.setProperty(EXO_FILE_NAME, file.getName()); } } catch (Exception e) { LOG.error("Failed to save attachment", e); } } } return listFileName; } public void savePost(String categoryId, String forumId, String topicId, Post post, boolean isNew, MessageBuilder messageBuilder) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); try { Node categoryNode = getCategoryHome(sProvider).getNode(categoryId); Node forumNode = categoryNode.getNode(forumId); Node topicNode = forumNode.getNode(topicId); Node postNode; if (isNew) { postNode = addPost(sProvider, categoryNode, forumNode, topicNode, post); } else { postNode = updatePost(sProvider, topicNode, post); } boolean sendAlertJob = messageBuilder.getLink().equals("link"); if (sendAlertJob == false) { sendAlertJob = (!post.getIsApproved() || post.getIsHidden() || post.getIsWaiting()) && (post.getUserPrivate().length != 2); } // forumNode.getSession().save(); if (isNew) { queryLastTopic(sProvider, forumNode.getPath()); } // post.setPath(postNode.getPath()); // if (topicNode.getName().replaceFirst(Utils.TOPIC, Utils.POST).equals(post.getId()) == false && isNew) { sendNotification(topicNode, null, post, messageBuilder, true); } if (sendAlertJob) { getTotalJobWatting(sProvider, new HashSet<String>( new PropertyReader(forumNode).list(EXO_MODERATORS, new ArrayList<String>()))); } // send notification message to user's private post. if (post.getUserPrivate().length > 1) { ForumPrivateMessage message = new ForumPrivateMessage(); message.setFrom(post.getOwner()); message.setSendTo(post.getUserPrivate()[0] + "," + post.getUserPrivate()[1]); message.setType("PrivatePost"); message.setName(post.getName()); message.setMessage(post.getMessage()); message.setId(topicId + "/" + post.getId()); sendNotificationMessage(message); } } catch (Exception e) { LOG.error("Failed to save post" + post.getName(), e); } } private Node addPost(SessionProvider sProvider, Node categoryNode, Node forumNode, Node topicNode, Post post) throws Exception { Calendar calendar = getGreenwichMeanTime(); Node postNode = topicNode.addNode(post.getId(), EXO_POST); postNode.setProperty(EXO_ID, post.getId()); postNode.setProperty(EXO_PATH, forumNode.getName()); postNode.setProperty(EXO_OWNER, post.getOwner()); post.setCreatedDate(calendar.getTime()); postNode.setProperty(EXO_CREATED_DATE, calendar); postNode.setProperty(EXO_USER_PRIVATE, post.getUserPrivate()); postNode.setProperty(EXO_LINK, post.getLink()); boolean isFistPost = topicNode.getName().replaceFirst(Utils.TOPIC, Utils.POST).equals(post.getId()); postNode.setProperty(EXO_IS_FIRST_POST, isFistPost); // postSaveProperties(postNode, post); // postAttachment(postNode, post); // long topicPostCount = topicNode.getProperty(EXO_POST_COUNT).getLong() + 1; long newNumberAttach = topicNode.getProperty(EXO_NUMBER_ATTACHMENTS).getLong() + post.getNumberAttach(); if (topicPostCount == 0) { topicNode.setProperty(EXO_POST_COUNT, topicPostCount); } // set InfoPost for Forum long forumPostCount = forumNode.getProperty(EXO_POST_COUNT).getLong() + 1; Topic topic = getTopicNodeSummary(topicNode); boolean topicActive = (topic.getIsClosed() == false && topic.getIsWaiting() == false && topic.getIsApproved() && topic.getIsActive() && topic.getIsActiveByForum()); boolean postActive = (post.getIsApproved() && post.getIsHidden() == false && post.getIsWaiting() == false && post.getUserPrivate().length != 2); boolean isPublic = (hasProperty(categoryNode, EXO_VIEWER) == false && hasProperty(forumNode, EXO_VIEWER) == false && hasProperty(topicNode, EXO_CAN_VIEW) == false); // set active by topic postNode.setProperty(EXO_IS_ACTIVE_BY_TOPIC, (topicActive || isFistPost)); // update forum if (isFistPost && forumNode.getProperty(EXO_IS_MODERATE_TOPIC).getBoolean() == false || isFistPost == false && topicActive) { forumNode.setProperty(EXO_POST_COUNT, forumPostCount); } // update topic if (postActive && isPublic) { topicNode.setProperty(EXO_POST_COUNT, topicPostCount); topicNode.setProperty(EXO_LAST_POST_DATE, calendar); topicNode.setProperty(EXO_LAST_POST_BY, post.getOwner()); topicNode.setProperty(EXO_NUMBER_ATTACHMENTS, newNumberAttach); } return postNode; } private Node updatePost(SessionProvider sProvider, Node topicNode, Post post) throws Exception { Node postNode = topicNode.getNode(post.getId()); long oldNumberAttachments = postNode.getProperty(EXO_NUMBER_ATTACH).getLong(); // postSaveProperties(postNode, post); // List<String> listFileName = postAttachment(postNode, post); // remove old attachments NodeIterator postAttachments = postNode.getNodes(); Node postAttachmentNode = null; while (postAttachments.hasNext()) { postAttachmentNode = postAttachments.nextNode(); if (listFileName.contains(postAttachmentNode.getName())) { continue; } postAttachmentNode.remove(); } long temp = topicNode.getProperty(EXO_NUMBER_ATTACHMENTS).getLong() - oldNumberAttachments; topicNode.setProperty(EXO_NUMBER_ATTACHMENTS, (temp + post.getNumberAttach())); // return postNode; } private boolean hasProperty(Node node, String property) throws Exception { String[] strs = new PropertyReader(node).strings(property, new String[] {}); return strs.length > 0; } private void sendNotification(Node node, Topic topic, Post post, MessageBuilder messageBuilder, boolean isApprovePost) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); try { messageBuilder = getInfoMessageMove(sProvider, messageBuilder.getContent(), messageBuilder.getHeaderSubject(), false); List<String> listUser = new ArrayList<String>(); List<String> emailList = new ArrayList<String>(); List<String> emailListCate = new ArrayList<String>(); Node userProfileHome = getUserProfileHome(sProvider); int count = 0; if (post == null) { Node forumNode = node; messageBuilder.setForumName(node.getProperty(EXO_NAME).getString()); node = node.getParent(); messageBuilder.setCatName(node.getProperty(EXO_NAME).getString()); messageBuilder.setTopicName(topic.getTopicName()); while (true) { emailListCate.addAll(emailList); emailList = new ArrayList<String>(); if (node.isNodeType(EXO_FORUM_WATCHING) && topic.getIsActive() && topic.getIsApproved() && topic.getIsActiveByForum() && !topic.getIsClosed() && !topic.getIsLock() && !topic.getIsWaiting()) { // set Category Private Node categoryNode = null; if (node.isNodeType(EXO_FORUM_CATEGORY)) { categoryNode = node; } else { categoryNode = node.getParent(); } if (categoryNode.hasProperty(EXO_USER_PRIVATE)) listUser.addAll( Utils.valuesToList(categoryNode.getProperty(EXO_USER_PRIVATE).getValues())); if (!listUser.isEmpty() && !Utils.isEmpty(listUser.get(0))) { if (node.hasProperty(EXO_EMAIL_WATCHING)) { List<String> emails = Utils .valuesToList(node.getProperty(EXO_EMAIL_WATCHING).getValues()); int i = 0; for (String user : Utils .valuesToList(node.getProperty(EXO_USER_WATCHING).getValues())) { if (ForumServiceUtils .hasPermission(listUser.toArray(new String[listUser.size()]), user)) { emailList.add(emails.get(i)); } i++; } } } else { if (node.hasProperty(EXO_EMAIL_WATCHING)) emailList.addAll( Utils.valuesToList(node.getProperty(EXO_EMAIL_WATCHING).getValues())); } } if (node.hasProperty(EXO_NOTIFY_WHEN_ADD_TOPIC)) { List<String> notyfys = Utils .valuesToList(node.getProperty(EXO_NOTIFY_WHEN_ADD_TOPIC).getValues()); if (!notyfys.isEmpty()) { emailList.addAll(notyfys); } } for (String string : emailListCate) { while (emailList.contains(string)) emailList.remove(string); } if (emailList.size() > 0) { String owner = getScreenName(sProvider, topic.getOwner()); messageBuilder.setObjName(node.getProperty(EXO_NAME).getString()); if (node.isNodeType(EXO_FORUM)) { messageBuilder.setWatchType(Utils.FORUM); } else { messageBuilder.setWatchType(Utils.CATEGORY); } messageBuilder.setId(topic.getId().replaceFirst(Utils.TOPIC, Utils.POST)); messageBuilder.setAddType(Utils.TOPIC); messageBuilder.setAddName(topic.getTopicName()); messageBuilder.setMessage(topic.getDescription()); messageBuilder.setCreatedDate(topic.getCreatedDate()); messageBuilder.setOwner(owner); messageBuilder.setLink(topic.getLink()); sendEmailNotification(emailList, messageBuilder.getContentEmail()); } if (node.isNodeType(EXO_FORUM) || count > 1) break; ++count; node = forumNode; } } else { if (!node.getName().replaceFirst(Utils.TOPIC, Utils.POST).equals(post.getId())) { /* * check is approved, is activate by topic and is not hidden before send mail */ Node forumNode = node.getParent(); Node categoryNode = forumNode.getParent(); messageBuilder.setCatName(categoryNode.getProperty(EXO_NAME).getString()); messageBuilder.setForumName(forumNode.getProperty(EXO_NAME).getString()); messageBuilder.setTopicName(node.getProperty(EXO_NAME).getString()); boolean isSend = false; if (post.getIsApproved() && post.getIsActiveByTopic() && !post.getIsHidden() && !post.getIsWaiting()) { isSend = true; List<String> listCanViewInTopic = new ArrayList<String>(); if (node.hasProperty(EXO_CAN_VIEW)) listCanViewInTopic .addAll(Utils.valuesToList(node.getProperty(EXO_CAN_VIEW).getValues())); if (post.getUserPrivate() != null && post.getUserPrivate().length > 1) { listUser.addAll(Arrays.asList(post.getUserPrivate())); } if ((listUser.isEmpty() || listUser.size() == 1)) { if (!listCanViewInTopic.isEmpty() && !Utils.isEmpty(listCanViewInTopic.get(0))) { listCanViewInTopic .addAll(Utils.valuesToList(forumNode.getProperty(EXO_POSTER).getValues())); listCanViewInTopic .addAll(Utils.valuesToList(forumNode.getProperty(EXO_VIEWER).getValues())); } // set Category Private if (categoryNode.hasProperty(EXO_USER_PRIVATE)) listUser.addAll( Utils.valuesToList(categoryNode.getProperty(EXO_USER_PRIVATE).getValues())); if (!listUser.isEmpty() && !Utils.isEmpty(listUser.get(0))) { if (!listCanViewInTopic.isEmpty() && !Utils.isEmpty(listCanViewInTopic.get(0))) { listUser = Utils.extractSameItems(listUser, listCanViewInTopic); if (listUser.isEmpty() || Utils.isEmpty(listUser.get(0))) isSend = false; } } else listUser = listCanViewInTopic; } } if (node.isNodeType(EXO_FORUM_WATCHING) && node.hasProperty(EXO_EMAIL_WATCHING) && isSend) { if (!listUser.isEmpty() && !listUser.get(0).equals(EXO_USER_PRI) && !Utils.isEmpty(listUser.get(0))) { List<String> emails = Utils .valuesToList(node.getProperty(EXO_EMAIL_WATCHING).getValues()); int i = 0; for (String user : Utils .valuesToList(node.getProperty(EXO_USER_WATCHING).getValues())) { if (ForumServiceUtils.hasPermission(listUser.toArray(new String[listUser.size()]), user)) { emailList.add(emails.get(i)); } i++; } } else { emailList = Utils.valuesToList(node.getProperty(EXO_EMAIL_WATCHING).getValues()); } } List<String> emailListForum = new ArrayList<String>(); // Owner Notify if (isApprovePost) { String ownerTopicEmail = ""; String owner = node.getProperty(EXO_OWNER).getString(); if (node.hasProperty(EXO_IS_NOTIFY_WHEN_ADD_POST) && !Utils.isEmpty(node.getProperty(EXO_IS_NOTIFY_WHEN_ADD_POST).getString())) { try { Node userOwner = userProfileHome.getNode(owner); ownerTopicEmail = userOwner.getProperty(EXO_EMAIL).getString(); } catch (Exception e) { ownerTopicEmail = node.getProperty(EXO_IS_NOTIFY_WHEN_ADD_POST).getString(); } } String[] users = post.getUserPrivate(); if (users != null && users.length == 2) { if (!Utils.isEmpty(ownerTopicEmail) && (users[0].equals(owner) || users[1].equals(owner))) { emailList.add(ownerTopicEmail); } owner = forumNode.getProperty(EXO_OWNER).getString(); if (forumNode.hasProperty(EXO_NOTIFY_WHEN_ADD_POST) && (users[0].equals(owner) || users[1].equals(owner))) { emailListForum.addAll(Utils .valuesToList(forumNode.getProperty(EXO_NOTIFY_WHEN_ADD_POST).getValues())); } } else { if (!Utils.isEmpty(ownerTopicEmail)) { emailList.add(ownerTopicEmail); } if (forumNode.hasProperty(EXO_NOTIFY_WHEN_ADD_POST)) { emailListForum.addAll(Utils .valuesToList(forumNode.getProperty(EXO_NOTIFY_WHEN_ADD_POST).getValues())); } } } /* * check is approved, is activate by topic and is not hidden before send mail */ if (forumNode.isNodeType(EXO_FORUM_WATCHING) && forumNode.hasProperty(EXO_EMAIL_WATCHING) && isSend) { if (!listUser.isEmpty() && !listUser.get(0).equals(EXO_USER_PRI) && !Utils.isEmpty(listUser.get(0))) { List<String> emails = Utils .valuesToList(forumNode.getProperty(EXO_EMAIL_WATCHING).getValues()); int i = 0; for (String user : Utils .valuesToList(forumNode.getProperty(EXO_USER_WATCHING).getValues())) { if (ForumServiceUtils.hasPermission(listUser.toArray(new String[listUser.size()]), user)) { emailListForum.add(emails.get(i)); } i++; } } else { emailListForum.addAll( Utils.valuesToList(forumNode.getProperty(EXO_EMAIL_WATCHING).getValues())); } } List<String> emailListCategory = new ArrayList<String>(); if (categoryNode.isNodeType(EXO_FORUM_WATCHING) && categoryNode.hasProperty(EXO_EMAIL_WATCHING) && isSend) { if (!listUser.isEmpty() && !listUser.get(0).equals(EXO_USER_PRI) && !Utils.isEmpty(listUser.get(0))) { List<String> emails = Utils .valuesToList(categoryNode.getProperty(EXO_EMAIL_WATCHING).getValues()); int i = 0; for (String user : Utils .valuesToList(categoryNode.getProperty(EXO_USER_WATCHING).getValues())) { if (ForumServiceUtils.hasPermission(listUser.toArray(new String[listUser.size()]), user)) { emailListCategory.add(emails.get(i)); } i++; } } else { emailListCategory.addAll( Utils.valuesToList(categoryNode.getProperty(EXO_EMAIL_WATCHING).getValues())); } } String fullName = getScreenName(sProvider, post.getOwner()); messageBuilder.setOwner(fullName); messageBuilder.setId(post.getId()); messageBuilder.setAddType(Utils.POST); messageBuilder.setAddName(post.getName()); messageBuilder.setMessage(post.getMessage()); messageBuilder.setCreatedDate(post.getCreatedDate()); messageBuilder.setLink(post.getLink()); // send email by category if (emailListCategory.size() > 0) { messageBuilder.setObjName(messageBuilder.getCatName()); messageBuilder.setWatchType(Utils.CATEGORY); sendEmailNotification(emailListCategory, messageBuilder.getContentEmail()); } for (String string : emailListCategory) { while (emailListForum.contains(string)) emailListForum.remove(string); } // send email by forum if (emailListForum.size() > 0) { messageBuilder.setObjName(messageBuilder.getForumName()); messageBuilder.setWatchType(Utils.FORUM); sendEmailNotification(emailListForum, messageBuilder.getContentEmail()); } for (String string : emailListCategory) { while (emailList.contains(string)) emailList.remove(string); } for (String string : emailListForum) { while (emailList.contains(string)) emailList.remove(string); } // send email by topic if (emailList.size() > 0) { messageBuilder.setObjName(messageBuilder.getTopicName()); messageBuilder.setWatchType(Utils.TOPIC); sendEmailNotification(emailList, messageBuilder.getContentEmail()); } } } } catch (Exception e) { LOG.error("Failed to send notification.", e); } } public void modifyPost(List<Post> posts, int type) { SessionProvider sProvider = CommonUtils.createSystemProvider(); try { Node forumHomeNode = getForumHomeNode(sProvider); for (Post post : posts) { try { String postPath = post.getPath(); String topicPath = postPath.substring(0, postPath.lastIndexOf("/")); String forumPath = postPath.substring(0, topicPath.lastIndexOf("/")); Node postNode = (Node) forumHomeNode.getSession().getItem(postPath); Node topicNode = (Node) forumHomeNode.getSession().getItem(topicPath); Node forumNode = (Node) forumHomeNode.getSession().getItem(forumPath); Calendar lastPostDate = topicNode.getProperty(EXO_LAST_POST_DATE).getDate(); Calendar postDate = postNode.getProperty(EXO_CREATED_DATE).getDate(); long topicPostCount = topicNode.getProperty(EXO_POST_COUNT).getLong(); long newNumberAttach = topicNode.getProperty(EXO_NUMBER_ATTACHMENTS).getLong(); long forumPostCount = forumNode.getProperty(EXO_POST_COUNT).getLong(); switch (type) { case Utils.APPROVE: { postNode.setProperty(EXO_IS_APPROVED, true); post.setIsApproved(true); sendNotification(topicNode, null, post, new MessageBuilder(), false); break; } case Utils.WAITING: { if (post.getIsWaiting()) { postNode.setProperty(EXO_IS_WAITING, true); Node postLastNode = getLastDatePost(forumHomeNode, topicNode, postNode); if (postLastNode != null) { topicNode.setProperty(EXO_LAST_POST_DATE, postLastNode.getProperty(EXO_CREATED_DATE).getDate()); topicNode.setProperty(EXO_LAST_POST_BY, postLastNode.getProperty(EXO_OWNER).getString()); } newNumberAttach = newNumberAttach - postNode.getProperty(EXO_NUMBER_ATTACH).getLong(); if (newNumberAttach < 0) newNumberAttach = 0; topicNode.setProperty(EXO_NUMBER_ATTACHMENTS, newNumberAttach); topicNode.setProperty(EXO_POST_COUNT, topicPostCount - 1); forumNode.setProperty(EXO_POST_COUNT, forumPostCount - 1); } else { postNode.setProperty(EXO_IS_WAITING, false); sendNotification(topicNode, null, post, new MessageBuilder(), false); } break; } case Utils.HIDDEN: { if (post.getIsHidden()) { postNode.setProperty(EXO_IS_HIDDEN, true); Node postLastNode = getLastDatePost(forumHomeNode, topicNode, postNode); if (postLastNode != null) { topicNode.setProperty(EXO_LAST_POST_DATE, postLastNode.getProperty(EXO_CREATED_DATE).getDate()); topicNode.setProperty(EXO_LAST_POST_BY, postLastNode.getProperty(EXO_OWNER).getString()); } newNumberAttach = newNumberAttach - postNode.getProperty(EXO_NUMBER_ATTACH).getLong(); if (newNumberAttach < 0) newNumberAttach = 0; topicNode.setProperty(EXO_NUMBER_ATTACHMENTS, newNumberAttach); topicNode.setProperty(EXO_POST_COUNT, topicPostCount - 1); forumNode.setProperty(EXO_POST_COUNT, forumPostCount - 1); } else { postNode.setProperty(EXO_IS_HIDDEN, false); sendNotification(topicNode, null, post, new MessageBuilder(), false); } break; } default: break; } if (!post.getIsHidden() && post.getIsApproved() && (Utils.WAITING != type)) { if (postDate.getTimeInMillis() > lastPostDate.getTimeInMillis()) { topicNode.setProperty(EXO_LAST_POST_DATE, postDate); topicNode.setProperty(EXO_LAST_POST_BY, post.getOwner()); } newNumberAttach = newNumberAttach + postNode.getProperty(EXO_NUMBER_ATTACH).getLong(); topicNode.setProperty(EXO_NUMBER_ATTACHMENTS, newNumberAttach); topicNode.setProperty(EXO_POST_COUNT, topicPostCount + 1); forumNode.setProperty(EXO_POST_COUNT, forumPostCount + 1); } if (forumNode.isNew()) { forumNode.getSession().save(); } else { forumNode.save(); } // getTotalJobWatting(sProvider, new HashSet<String>( new PropertyReader(forumNode).list(EXO_MODERATORS, new ArrayList<String>()))); } catch (PathNotFoundException e) { LOG.error("Failed to modify post" + post.getName(), e); } } } catch (Exception e) { LOG.error("Failed to modify posts", e); } } private Node getLastDatePost(Node forumHomeNode, Node node, Node postNode_) throws Exception { QueryManager qm = forumHomeNode.getSession().getWorkspace().getQueryManager(); StringBuffer pathQuery = new StringBuffer(); pathQuery.append(JCR_ROOT).append(node.getPath()).append( "/element(*,exo:post)[@exo:isHidden='false' and @exo:isApproved='true'] order by @exo:createdDate descending"); Query query = qm.createQuery(pathQuery.toString(), Query.XPATH); QueryResult result = query.execute(); NodeIterator iter = result.getNodes(); Node postNode = null; while (iter.hasNext()) { postNode = iter.nextNode(); if (postNode.getName().equals(postNode_.getName())) { continue; } else { break; } } return postNode; } public Post removePost(String categoryId, String forumId, String topicId, String postId) { SessionProvider sProvider = CommonUtils.createSystemProvider(); Post post; try { Node CategoryNode = getCategoryHome(sProvider).getNode(categoryId); post = getPost(categoryId, forumId, topicId, postId); Node forumNode = CategoryNode.getNode(forumId); Node topicNode = forumNode.getNode(topicId); Node postNode = topicNode.getNode(postId); long numberAttachs = postNode.getProperty(EXO_NUMBER_ATTACH).getLong(); String owner = postNode.getProperty(EXO_OWNER).getString(); Node userProfileNode = getUserProfileHome(sProvider); try { Node newProfileNode = userProfileNode.getNode(owner); newProfileNode.setProperty(EXO_TOTAL_POST, newProfileNode.getProperty(EXO_TOTAL_POST).getLong() - 1); newProfileNode.save(); } catch (PathNotFoundException e) { LOG.debug("Failed to save category moderators ", e); } postNode.remove(); // update information: setPostCount, lastpost for Topic if (!post.getIsHidden() && post.getIsApproved() && !post.getIsWaiting() && (post.getUserPrivate() == null || post.getUserPrivate().length == 1)) { long topicPostCount = topicNode.getProperty(EXO_POST_COUNT).getLong() - 1; topicNode.setProperty(EXO_POST_COUNT, topicPostCount); long newNumberAttachs = topicNode.getProperty(EXO_NUMBER_ATTACHMENTS).getLong(); if (newNumberAttachs > numberAttachs) newNumberAttachs = newNumberAttachs - numberAttachs; else newNumberAttachs = 0; topicNode.setProperty(EXO_NUMBER_ATTACHMENTS, newNumberAttachs); } NodeIterator nodeIterator = topicNode.getNodes(); /* * long last = nodeIterator.getSize() - 1; nodeIterator.skip(last); */ while (nodeIterator.hasNext()) { Node node = nodeIterator.nextNode(); if (node.isNodeType(EXO_POST)) postNode = node; } topicNode.setProperty(EXO_LAST_POST_BY, postNode.getProperty(EXO_OWNER).getValue().getString()); topicNode.setProperty(EXO_LAST_POST_DATE, postNode.getProperty(EXO_CREATED_DATE).getValue().getDate()); forumNode.save(); // TODO: Thinking for update forum and user profile by node observation? // setPostCount for Forum if (!post.getIsHidden() && post.getIsApproved() && (post.getUserPrivate() == null || post.getUserPrivate().length == 1)) { long forumPostCount = forumNode.getProperty(EXO_POST_COUNT).getLong() - 1; forumNode.setProperty(EXO_POST_COUNT, forumPostCount); forumNode.save(); } else if (post.getUserPrivate() == null || post.getUserPrivate().length == 1) { getTotalJobWatting(sProvider, new HashSet<String>( new PropertyReader(forumNode).list(EXO_MODERATORS, new ArrayList<String>()))); } return post; } catch (Exception e) { LOG.error("Failed to remove post in topic."); return null; } } public void movePost(String[] postPaths, String destTopicPath, boolean isCreatNewTopic, String mailContent, String link) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); Node forumHomeNode = getForumHomeNode(sProvider); // Node Topic move Post String srcTopicPath = postPaths[0]; srcTopicPath = srcTopicPath.substring(0, srcTopicPath.lastIndexOf("/")); Node srcTopicNode = (Node) forumHomeNode.getSession().getItem(srcTopicPath); Node srcForumNode = (Node) srcTopicNode.getParent(); Node destTopicNode = (Node) forumHomeNode.getSession().getItem(destTopicPath); Node destForumNode = (Node) destTopicNode.getParent(); long totalAtt = 0; long totalpost = (long) postPaths.length; Node postNode = null; boolean destModeratePost = false; if (destTopicNode.hasProperty(EXO_IS_MODERATE_POST)) { destModeratePost = destTopicNode.getProperty(EXO_IS_MODERATE_POST).getBoolean(); } boolean srcModeratePost = false; if (srcTopicNode.hasProperty(EXO_IS_MODERATE_POST)) { srcModeratePost = srcTopicNode.getProperty(EXO_IS_MODERATE_POST).getBoolean(); } PropertyReader destTopicReader = new PropertyReader(destTopicNode); boolean isActiveByTopic = destTopicReader.bool(EXO_IS_APPROVED) && destTopicReader.bool(EXO_IS_ACTIVE) && destTopicReader.bool(EXO_IS_ACTIVE_BY_FORUM) && !destTopicReader.bool(EXO_IS_CLOSED) && !destTopicReader.bool(EXO_IS_WAITING); boolean unAproved = false; String path; for (int i = 0; i < totalpost; ++i) { // totalAtt = totalAtt + post.getNumberAttach(); path = postPaths[i]; String newPostPath = destTopicPath + path.substring(path.lastIndexOf("/")); forumHomeNode.getSession().getWorkspace().move(path, newPostPath); postPaths[i] = newPostPath; // Node Post move postNode = (Node) forumHomeNode.getSession().getItem(newPostPath); postNode.setProperty(EXO_PATH, destForumNode.getName()); postNode.setProperty(EXO_CREATED_DATE, getGreenwichMeanTime()); if (isCreatNewTopic && i == 0) { postNode.setProperty(EXO_IS_FIRST_POST, true); } else { postNode.setProperty(EXO_IS_FIRST_POST, false); } if (!destModeratePost) { postNode.setProperty(EXO_IS_APPROVED, true); } else { if (!postNode.getProperty(EXO_IS_APPROVED).getBoolean()) { unAproved = true; } } postNode.setProperty(EXO_IS_ACTIVE_BY_TOPIC, isActiveByTopic); } // set destTopicNode destTopicNode.setProperty(EXO_POST_COUNT, destTopicNode.getProperty(EXO_POST_COUNT).getLong() + totalpost); destTopicNode.setProperty(EXO_NUMBER_ATTACHMENTS, destTopicNode.getProperty(EXO_NUMBER_ATTACHMENTS).getLong() + totalAtt); destForumNode.setProperty(EXO_POST_COUNT, destForumNode.getProperty(EXO_POST_COUNT).getLong() + totalpost); // update last post for destTopicNode destTopicNode.setProperty(EXO_LAST_POST_BY, postNode.getProperty(EXO_OWNER).getValue().getString()); destTopicNode.setProperty(EXO_LAST_POST_DATE, postNode.getProperty(EXO_CREATED_DATE).getValue().getDate()); // set srcTopicNode long temp = srcTopicNode.getProperty(EXO_POST_COUNT).getLong(); temp = temp - totalpost; srcTopicNode.setProperty(EXO_POST_COUNT, (temp > -1) ? temp : -1); temp = srcTopicNode.getProperty(EXO_NUMBER_ATTACHMENTS).getLong(); temp = temp - totalAtt; if (temp < 0) temp = 0; srcTopicNode.setProperty(EXO_NUMBER_ATTACHMENTS, temp); // update last post for srcTopicNode NodeIterator nodeIterator = srcTopicNode.getNodes(); long posLast = nodeIterator.getSize() - 1; nodeIterator.skip(posLast); while (nodeIterator.hasNext()) { Node node = nodeIterator.nextNode(); if (node.isNodeType(EXO_POST)) postNode = node; } srcTopicNode.setProperty(EXO_LAST_POST_BY, postNode.getProperty(EXO_OWNER).getValue().getString()); srcTopicNode.setProperty(EXO_LAST_POST_DATE, postNode.getProperty(EXO_CREATED_DATE).getValue().getDate()); // set srcForumNode temp = srcForumNode.getProperty(EXO_POST_COUNT).getLong(); temp = temp - totalpost; srcForumNode.setProperty(EXO_POST_COUNT, (temp > 0) ? temp : 0); if (forumHomeNode.isNew()) { forumHomeNode.getSession().save(); } else { forumHomeNode.save(); } String objectName = new StringBuilder("[") .append(destForumNode.getParent().getProperty(EXO_NAME).getString()).append("][") .append(destForumNode.getProperty(EXO_NAME).getString()).append("] ").toString(); MessageBuilder messageBuilder = getInfoMessageMove(sProvider, mailContent, objectName, true); String topicName = destTopicNode.getProperty(EXO_NAME).getString(); String ownerTopic = destTopicNode.getProperty(EXO_OWNER).getString(); messageBuilder.setOwner(getScreenName(sProvider, ownerTopic)); messageBuilder.setHeaderSubject(messageBuilder.getHeaderSubject() + topicName); messageBuilder.setAddType(topicName); link = link.replaceFirst("pathId", destTopicNode.getProperty(EXO_ID).getString()); messageBuilder.setTypes(Utils.TOPIC, Utils.POST, "", ""); for (int i = 0; i < totalpost; ++i) { postNode = (Node) forumHomeNode.getSession().getItem(postPaths[i]); messageBuilder.setObjName(postNode.getProperty(EXO_NAME).getString()); messageBuilder.setLink(link + "/" + postNode.getName()); Set<String> set = new HashSet<String>(); // set email author this topic set.add(getEmailUser(sProvider, postNode.getProperty(EXO_OWNER).getString())); // set email watch this topic, forum, category parent of this post set.addAll(calculateMoveEmail(destTopicNode)); // set email watch old category, forum, topic parent of this post set.addAll(calculateMoveEmail(srcTopicNode)); if (!Utils.isEmpty(set.toArray(new String[set.size()]))) { sendEmailNotification(new ArrayList<String>(set), messageBuilder.getContentEmailMoved()); } } Set<String> userIdsp = new HashSet<String>(); if (destModeratePost && srcModeratePost) { if (srcForumNode.hasProperty(EXO_MODERATORS)) { userIdsp.addAll(Utils.valuesToList(srcForumNode.getProperty(EXO_MODERATORS).getValues())); } if (unAproved && destForumNode.hasProperty(EXO_MODERATORS)) { userIdsp.addAll(Utils.valuesToList(destForumNode.getProperty(EXO_MODERATORS).getValues())); } } else if (srcModeratePost && !destModeratePost) { if (srcForumNode.hasProperty(EXO_MODERATORS)) { userIdsp.addAll(Utils.valuesToList(srcForumNode.getProperty(EXO_MODERATORS).getValues())); } } else if (!srcModeratePost && destModeratePost) { if (unAproved && destForumNode.hasProperty(EXO_MODERATORS)) { userIdsp.addAll(Utils.valuesToList(destForumNode.getProperty(EXO_MODERATORS).getValues())); } } if (!userIdsp.isEmpty()) { getTotalJobWatting(sProvider, userIdsp); } } private MessageBuilder getInfoMessageMove(SessionProvider sProvider, String defaultContent, String defaultSubject, boolean isMove) throws Exception { MessageBuilder messageBuilder = new MessageBuilder(); try { Node forumAdminNode = getAdminHome(sProvider).getNode(Utils.FORUMADMINISTRATION); PropertyReader reader = new PropertyReader(forumAdminNode); String property = (isMove) ? EXO_NOTIFY_EMAIL_MOVED : EXO_NOTIFY_EMAIL_CONTENT; messageBuilder.setContent(reader.string(property, defaultContent)); if (reader.bool(EXO_ENABLE_HEADER_SUBJECT)) { messageBuilder.setHeaderSubject(reader.string(EXO_HEADER_SUBJECT, defaultSubject)); } else { messageBuilder.setHeaderSubject(defaultSubject); } } catch (Exception e) { messageBuilder.setContent(defaultContent); messageBuilder.setHeaderSubject(defaultSubject); } return messageBuilder; } public void mergeTopic(String srcTopicPath, String destTopicPath, String mailContent, String link) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); try { Node srcTopicNode = getCategoryHome(sProvider).getNode(srcTopicPath); NodeIterator iter = srcTopicNode.getNodes(); List<Post> posts = new ArrayList<Post>(); Post post; boolean isTopicWaiting = new PropertyReader(srcTopicNode).bool(EXO_IS_WAITING); while (iter.hasNext()) { post = new Post(); Node node = iter.nextNode(); if (node.isNodeType(EXO_POST)) { if (new PropertyReader(node).bool(EXO_IS_FIRST_POST)) { node.setProperty(EXO_IS_WAITING, isTopicWaiting); node.save(); } post.setPath(node.getPath()); post.setCreatedDate(node.getProperty(EXO_CREATED_DATE).getDate().getTime()); posts.add(post); } } if (posts.size() > 0) { Collections.sort(posts, new Utils.DatetimeComparatorPostDESC()); String[] postPaths = new String[posts.size()]; int i = 0; for (Post p : posts) { postPaths[i] = p.getPath(); ++i; } movePost(postPaths, destTopicPath, false, mailContent, link); String ids[] = srcTopicPath.split("/"); removeTopic(ids[0], ids[1], srcTopicNode.getName()); } } catch (Exception e) { throw e; } } public void splitTopic(Topic newTopic, Post fistPost, List<String> postPathMove, String mailContent, String link) throws Exception { // save new topic saveTopic(newTopic.getCategoryId(), newTopic.getForumId(), newTopic, true, true, new MessageBuilder()); // save first post savePost(fistPost.getCategoryId(), fistPost.getForumId(), fistPost.getTopicId(), fistPost, false, new MessageBuilder()); // move all posts to new topic movePost(postPathMove.toArray(new String[postPathMove.size()]), newTopic.getPath(), true, mailContent, link); } public void addTag(List<Tag> tags, String userName, String topicPath) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); try { boolean isAdd; Node topicNode = (Node) getCategoryHome(sProvider).getSession().getItem(topicPath); List<String> listId = new ArrayList<String>(); List<String> list = new ArrayList<String>(); if (topicNode.hasProperty(EXO_TAG_ID)) { listId = Utils.valuesToList(topicNode.getProperty(EXO_TAG_ID).getValues()); } list.addAll(listId); String userIdAndTagId; for (Tag tag : tags) { isAdd = true; userIdAndTagId = userName + ":" + tag.getId(); for (String string1 : listId) { if (userIdAndTagId.equals(string1)) { isAdd = false; break; } } if (isAdd) { list.add(userIdAndTagId); saveTag(tag); } } topicNode.setProperty(EXO_TAG_ID, Utils.getStringsInList(list)); if (topicNode.isNew()) { topicNode.getSession().save(); } else { topicNode.save(); } } catch (Exception e) { LOG.error("Failed to add tags", e); } } public void unTag(String tagId, String userName, String topicPath) { SessionProvider sProvider = CommonUtils.createSystemProvider(); try { Node categoryHome = getCategoryHome(sProvider); Node topicNode = (Node) categoryHome.getSession().getItem(topicPath); List<String> oldTagsId = Utils.valuesToList(topicNode.getProperty(EXO_TAG_ID).getValues()); // remove in topic. String userIdTagId = userName + ":" + tagId; QueryManager qm = categoryHome.getSession().getWorkspace().getQueryManager(); StringBuilder builder = new StringBuilder(); builder.append(JCR_ROOT).append(categoryHome.getPath()).append("//element(*,exo:topic)[@exo:tagId='") .append(userIdTagId).append("']"); Query query = qm.createQuery(builder.toString(), Query.XPATH); QueryResult result = query.execute(); NodeIterator iter = result.getNodes(); if (oldTagsId.contains(userIdTagId)) { oldTagsId.remove(userIdTagId); topicNode.setProperty(EXO_TAG_ID, oldTagsId.toArray(new String[oldTagsId.size()])); if (topicNode.isNew()) { topicNode.getSession().save(); } else { topicNode.save(); } } Tag tag = getTag(tagId); List<String> userTags = new ArrayList<String>(); userTags.addAll(Arrays.asList(tag.getUserTag())); if (iter.getSize() == 1 && userTags.size() > 1) { if (userTags.contains(userName)) { userTags.remove(userName); tag.setUserTag(userTags.toArray(new String[userTags.size()])); Node tagNode = getTagHome(sProvider).getNode(tagId); long count = tagNode.getProperty(EXO_USE_COUNT).getLong(); if (count > 1) tagNode.setProperty(EXO_USE_COUNT, count - 1); tagNode.setProperty(EXO_USER_TAG, userTags.toArray(new String[userTags.size()])); tagNode.save(); } } else if (iter.getSize() == 1 && userTags.size() == 1) { Node tagHomNode = getTagHome(sProvider); tagHomNode.getNode(tagId).remove(); tagHomNode.save(); } else if (iter.getSize() > 1) { Node tagNode = getTagHome(sProvider).getNode(tagId); long count = tagNode.getProperty(EXO_USE_COUNT).getLong(); if (count > 1) tagNode.setProperty(EXO_USE_COUNT, count - 1); tagNode.save(); } } catch (Exception e) { LOG.error("Failed to untag.", e); } } public Tag getTag(String tagId) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); try { Node tagNode = getTagHome(sProvider).getNode(tagId); return getTagNode(tagNode); } catch (Exception e) { return null; } } public List<String> getTagNameInTopic(String userAndTopicId) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); List<String> tagNames = new ArrayList<String>(); try { Node tagHome = getTagHome(sProvider); QueryManager qm = tagHome.getSession().getWorkspace().getQueryManager(); int t = userAndTopicId.indexOf(","); String userId = userAndTopicId.substring(0, t); NodeIterator iter = getTopicNodeIteratorByTag(sProvider, qm, userAndTopicId); StringBuilder builder = new StringBuilder(); StringBuilder builder1 = new StringBuilder(); if (iter.getSize() > 0) { Node node = (Node) iter.nextNode(); if (node.hasProperty(EXO_TAG_ID)) { boolean b = true; t = 0; List<String> list = new ArrayList<String>(); for (String string : Utils.valuesToList(node.getProperty(EXO_TAG_ID).getValues())) { String[] temp = string.split(":"); if (temp.length == 2) { if (temp[0].equals(userId)) { if (t == 0) builder.append("(@exo:id != '").append(temp[1]).append("'"); else builder.append(" and @exo:id != '").append(temp[1]).append("'"); list.add(temp[1]); t = 1; } else if (!list.contains(temp[1])) { if (b) builder1.append(" (@exo:id='").append(temp[1]).append("'"); else builder1.append(" or @exo:id='").append(temp[1]).append("'"); b = false; } } } if (!b) builder1.append(")"); if (t == 1) builder.append(")"); } } if (builder1.length() == 0) { return tagNames; } StringBuffer queryString = new StringBuffer(); queryString.append(JCR_ROOT).append(tagHome.getPath()).append("//element(*,exo:forumTag)"); boolean isQr = false; if (builder.length() > 0) { queryString.append("[").append(builder); isQr = true; } if (builder1.length() > 0) { if (isQr) { queryString.append(" and ").append(builder1); } else { queryString.append("[").append(builder1); isQr = true; } } if (isQr) queryString.append("]"); queryString.append("order by @exo:useCount descending, @exo:name ascending "); Query query = qm.createQuery(queryString.toString(), Query.XPATH); iter = query.execute().getNodes(); return getTagName(iter, tagNames); } catch (Exception e) { return tagNames; } } private List<String> getTagName(NodeIterator iter, List<String> tagNames) { StringBuilder str; PropertyReader reader; while (iter.hasNext()) { reader = new PropertyReader((Node) iter.nextNode()); str = new StringBuilder(reader.string(EXO_NAME)); str.append(Utils.SPACE).append("<font color=\"Salmon\">(").append(reader.string(EXO_USE_COUNT)) .append(")</font>"); tagNames.add(str.toString()); if (tagNames.size() == 5) break; } return tagNames; } private NodeIterator getTopicNodeIteratorByTag(SessionProvider sProvider, QueryManager qm, String userAndTopicId) throws Exception { Node categoryHome = getCategoryHome(sProvider); StringBuffer queryString = new StringBuffer(); String topicId = userAndTopicId.substring(userAndTopicId.indexOf(",") + 1); queryString.append(JCR_ROOT).append(categoryHome.getPath()).append("//element(*,exo:topic)[exo:id='") .append(topicId).append("']"); Query query = qm.createQuery(queryString.toString(), Query.XPATH); return query.execute().getNodes(); } public List<String> getAllTagName(String keyValue, String userAndTopicId) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); List<String> tagNames = new ArrayList<String>(); try { Node tagHome = getTagHome(sProvider); QueryManager qm = tagHome.getSession().getWorkspace().getQueryManager(); int t = userAndTopicId.indexOf(","); String userId = userAndTopicId.substring(0, t); NodeIterator iter = getTopicNodeIteratorByTag(sProvider, qm, userAndTopicId); StringBuilder builder = new StringBuilder(); if (iter.getSize() > 0) { Node node = (Node) iter.nextNode(); if (node.hasProperty(EXO_TAG_ID)) { t = 0; for (String string : Utils.valuesToList(node.getProperty(EXO_TAG_ID).getValues())) { String[] temp = string.split(":"); if (temp.length == 2 && temp[0].equals(userId)) { if (t == 0) builder.append("@exo:id != '").append(temp[1]).append("'"); else builder.append(" and @exo:id != '").append(temp[1]).append("'"); t = 1; } } } } StringBuffer queryString = new StringBuffer(); queryString.append(JCR_ROOT).append(tagHome.getPath()) .append("//element(*,exo:forumTag)[(jcr:contains(@exo:name, '").append(keyValue).append("*'))"); if (builder.length() > 0) { queryString.append(" and (").append(builder).append(")"); } queryString.append("]order by @exo:useCount descending, @exo:name ascending "); Query query = qm.createQuery(queryString.toString(), Query.XPATH); iter = query.execute().getNodes(); return getTagName(iter, tagNames); } catch (Exception e) { return tagNames; } } public List<Tag> getAllTags() throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); List<Tag> tags = new ArrayList<Tag>(); try { Node tagHome = getTagHome(sProvider); QueryManager qm = tagHome.getSession().getWorkspace().getQueryManager(); StringBuffer queryString = new StringBuffer(JCR_ROOT + tagHome.getPath() + "/element(*,exo:forumTag)"); Query query = qm.createQuery(queryString.toString(), Query.XPATH); QueryResult result = query.execute(); NodeIterator iter = result.getNodes(); while (iter.hasNext()) { tags.add(getTagNode((Node) iter.nextNode())); } return tags; } catch (Exception e) { return tags; } } private Tag getTagNode(Node tagNode) throws RepositoryException { Tag newTag = new Tag(); newTag.setId(tagNode.getName()); PropertyReader reader = new PropertyReader(tagNode); newTag.setUserTag(reader.strings(EXO_USER_TAG, new String[] {})); newTag.setName(reader.string(EXO_NAME, "")); newTag.setUseCount(reader.l(EXO_USE_COUNT)); return newTag; } public List<Tag> getMyTagInTopic(String[] tagIds) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); List<Tag> tags = new ArrayList<Tag>(); try { Node tagHome = getTagHome(sProvider); for (String id : tagIds) { try { tags.add(getTagNode(tagHome.getNode(id))); } catch (Exception e) { if (LOG.isDebugEnabled()) { LOG.debug(String.format("Failed to get tag node with id %s", id), e); } } } return tags; } catch (Exception e) { return tags; } } public JCRPageList getTopicByMyTag(String userIdAndtagId, String strOrderBy) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); try { Node categoryHome = getCategoryHome(sProvider); QueryManager qm = categoryHome.getSession().getWorkspace().getQueryManager(); StringBuilder builder = new StringBuilder(); builder.append(JCR_ROOT).append(categoryHome.getPath()).append("//element(*,exo:topic)"); if (userIdAndtagId.indexOf(":") > 0) { builder.append("[@exo:tagId='").append(userIdAndtagId).append("']"); } else { builder.append("[jcr:contains(@exo:tagId,'").append(userIdAndtagId).append("')]"); } builder.append(" order by @exo:isSticky descending"); if (Utils.isEmpty(strOrderBy)) { builder.append(", @exo:lastPostDate descending"); } else { builder.append(", @exo:").append(strOrderBy); if (strOrderBy.indexOf("lastPostDate") < 0) { builder.append(", @exo:lastPostDate descending"); } } String pathQuery = builder.toString(); Query query = qm.createQuery(pathQuery, Query.XPATH); QueryResult result = query.execute(); NodeIterator iter = result.getNodes(); JCRPageList pagelist = new ForumPageList(iter, 10, pathQuery, true); return pagelist; } catch (Exception e) { return null; } } public void saveTag(Tag newTag) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); try { Node tagHome = getTagHome(sProvider); Node newTagNode; boolean isNew = false; try { newTagNode = tagHome.getNode(newTag.getId()); } catch (PathNotFoundException e) { isNew = true; String id = Utils.TAG + newTag.getName(); newTagNode = tagHome.addNode(id, EXO_FORUM_TAG); newTagNode.setProperty(EXO_ID, id); } if (isNew) { newTagNode.setProperty(EXO_USER_TAG, newTag.getUserTag()); newTagNode.setProperty(EXO_NAME, newTag.getName()); newTagNode.setProperty(EXO_USE_COUNT, 1); } else { List<String> userTags = Utils.valuesToList(newTagNode.getProperty(EXO_USER_TAG).getValues()); if (!userTags.contains(newTag.getUserTag()[0])) { userTags.add(newTag.getUserTag()[0]); newTagNode.setProperty(EXO_USER_TAG, userTags.toArray(new String[userTags.size()])); } long count = newTagNode.getProperty(EXO_USE_COUNT).getLong(); newTagNode.setProperty(EXO_USE_COUNT, count + 1); } if (tagHome.isNew()) { tagHome.getSession().save(); } else { tagHome.save(); } } catch (Exception e) { LOG.error("Failed to save tag.", e); } } public JCRPageList getPageListUserProfile() throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); try { Node userProfileNode = getUserProfileHome(sProvider); NodeIterator iterator = userProfileNode.getNodes(); JCRPageList pageList = new ForumPageList(iterator, 10, userProfileNode.getPath(), false); return pageList; } catch (Exception e) { return null; } } public JCRPageList searchUserProfile(String userSearch) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); try { Node userProfileHome = getUserProfileHome(sProvider); QueryManager qm = userProfileHome.getSession().getWorkspace().getQueryManager(); StringBuffer stringBuffer = new StringBuffer(); stringBuffer.append(JCR_ROOT).append(userProfileHome.getPath()).append("/element(*,") .append(EXO_FORUM_USER_PROFILE).append(")").append("[(jcr:contains(., '").append(userSearch) .append("'))]"); Query query = qm.createQuery(stringBuffer.toString(), Query.XPATH); QueryResult result = query.execute(); NodeIterator iter = result.getNodes(); JCRPageList pagelist = new ForumPageList(iter, 10, stringBuffer.toString(), true); return pagelist; } catch (Exception e) { return null; } } public UserProfile getDefaultUserProfile(String userName, String ip) throws Exception { UserProfile userProfile = new UserProfile(); if (userName == null || userName.length() <= 0) return userProfile; SessionProvider sProvider = CommonUtils.createSystemProvider(); try { Node profileNode = getUserProfileNode(sProvider, userName); PropertyReader reader = new PropertyReader(profileNode); userProfile.setUserId(userName); if (isAdminRole(userName)) { userProfile.setUserRole((long) 0); } else { userProfile.setUserRole(reader.l(EXO_USER_ROLE, 2)); } userProfile.setModerateForums(reader.strings(EXO_MODERATE_FORUMS, new String[] {})); userProfile.setModerateCategory(reader.strings(EXO_MODERATE_CATEGORY, new String[] {})); userProfile.setScreenName(getScreenName(userName, profileNode)); userProfile.setNewMessage(reader.l(EXO_NEW_MESSAGE)); userProfile.setTimeZone(reader.d(EXO_TIME_ZONE)); userProfile.setShortDateFormat(reader.string(EXO_SHORT_DATEFORMAT, userProfile.getShortDateFormat())); userProfile.setLongDateFormat(reader.string(EXO_LONG_DATEFORMAT, userProfile.getLongDateFormat())); userProfile.setTimeFormat(reader.string(EXO_TIME_FORMAT, userProfile.getTimeFormat())); userProfile.setMaxPostInPage(reader.l(EXO_MAX_POST, 10)); userProfile.setMaxTopicInPage(reader.l(EXO_MAX_TOPIC, 10)); userProfile.setIsAutoWatchMyTopics(reader.bool(EXO_IS_AUTO_WATCH_MY_TOPICS)); userProfile.setIsAutoWatchTopicIPost(reader.bool(EXO_IS_AUTO_WATCH_TOPIC_I_POST)); userProfile.setLastReadPostOfForum(reader.strings(EXO_LAST_READ_POST_OF_FORUM, new String[] {})); userProfile.setLastReadPostOfTopic(reader.strings(EXO_LAST_READ_POST_OF_TOPIC, new String[] {})); userProfile.setIsBanned(reader.bool(EXO_IS_BANNED)); userProfile.setCollapCategories(reader.strings(EXO_COLLAP_CATEGORIES, new String[] {})); userProfile.setEmail(reader.string(EXO_EMAIL, "")); List<String> values = reader.list(EXO_READ_TOPIC, new ArrayList<String>()); String s = ":"; for (String str : values) { if (str.indexOf(s) > 0) { String[] array = str.split(s); userProfile.setLastTimeAccessTopic(array[0], Long.parseLong(array[1])); } } values = reader.list(EXO_READ_FORUM, new ArrayList<String>()); for (String str : values) { if (str.indexOf(s) > 0) { String[] array = str.split(s); userProfile.setLastTimeAccessForum(array[0], Long.parseLong(array[1])); } } if (userProfile.getIsBanned()) { if (profileNode.hasProperty(EXO_BAN_UNTIL)) { userProfile.setBanUntil(reader.l(EXO_BAN_UNTIL)); if (userProfile.getBanUntil() <= getGreenwichMeanTime().getTimeInMillis()) { profileNode.setProperty(EXO_IS_BANNED, false); profileNode.save(); userProfile.setIsBanned(false); } } } else if (ip != null) { userProfile.setIsBanned(isBanIp(ip)); } } catch (Exception e) { if (LOG.isDebugEnabled()) { LOG.debug("Failed to get default userprofile of user: " + userName, e); } } return userProfile; } public UserProfile updateUserProfileSetting(UserProfile userProfile) throws Exception { if (userProfile.getIsBanned()) { SessionProvider sProvider = CommonUtils.createSystemProvider(); Node profileNode = getUserProfileNode(sProvider, userProfile.getUserId()); if (profileNode.hasProperty(EXO_BAN_UNTIL)) { userProfile.setBanUntil(profileNode.getProperty(EXO_BAN_UNTIL).getLong()); if (userProfile.getBanUntil() <= getGreenwichMeanTime().getTimeInMillis()) { profileNode.setProperty(EXO_IS_BANNED, false); profileNode.save(); userProfile.setIsBanned(false); } } } return userProfile; } public String getScreenName(String userName) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); try { return getScreenName(sProvider, userName); } catch (Exception e) { return userName; } } private String getScreenName(SessionProvider sProvider, String userName) throws Exception { try { Node userProfile = getUserProfileNode(getUserProfileHome(sProvider), userName); return getScreenName(userName, userProfile); } catch (Exception e) { return getScreenName(userName, null); } } private String getScreenName(String userName, Node userProfile) throws Exception { String userTemp = userName; if (userProfile != null) { PropertyReader reader = new PropertyReader(userProfile); userName = reader.string(EXO_SCREEN_NAME, reader.string(EXO_FULL_NAME, userName)); } return (userTemp.contains(Utils.DELETED)) ? "<s>" + ((userName.contains(Utils.DELETED)) ? userName.substring(0, userName.indexOf(Utils.DELETED)) : userName) + "</s>" : userName; } public boolean isBanIp(String ip) throws Exception { return (getBanList().contains(ip)) ? true : false; } public UserProfile getUserSettingProfile(String userName) throws Exception { UserProfile userProfile = new UserProfile(); if (userName == null || userName.length() <= 0) return userProfile; SessionProvider sProvider = CommonUtils.createSystemProvider(); Session session = sessionManager.getSession(sProvider); try { userProfile = getCachedDataStorage().getQuickProfile(userName); Node profileNode = session.getRootNode() .getNode(dataLocator.getUserProfilesLocation() + "/" + userProfile.getPath()); PropertyReader reader = new PropertyReader(profileNode); //some information of profile has been loaded by getQuickProfile, don't loading anymore. //userProfile.setUserId(userName); //userProfile.setUserTitle(reader.string(EXO_USER_TITLE, "")); userProfile.setScreenName(getScreenName(userName, profileNode)); userProfile.setSignature(reader.string(EXO_SIGNATURE, "")); userProfile.setIsDisplaySignature(reader.bool(EXO_IS_DISPLAY_SIGNATURE, true)); //userProfile.setIsDisplayAvatar(reader.bool(EXO_IS_DISPLAY_AVATAR, true)); userProfile.setIsAutoWatchMyTopics(reader.bool(EXO_IS_AUTO_WATCH_MY_TOPICS)); userProfile.setIsAutoWatchTopicIPost(reader.bool(EXO_IS_AUTO_WATCH_TOPIC_I_POST)); userProfile.setUserRole(reader.l(EXO_USER_ROLE)); userProfile.setTimeZone(reader.d(EXO_TIME_ZONE)); userProfile.setShortDateFormat(reader.string(EXO_SHORT_DATEFORMAT, "")); userProfile.setLongDateFormat(reader.string(EXO_LONG_DATEFORMAT, "")); userProfile.setTimeFormat(reader.string(EXO_TIME_FORMAT, "")); userProfile.setMaxPostInPage(reader.l(EXO_MAX_POST)); userProfile.setMaxTopicInPage(reader.l(EXO_MAX_TOPIC)); } catch (Exception e) { userProfile.setUserId(userName); userProfile.setUserTitle(Utils.USER); userProfile.setUserRole((long) 2); // default Administration if (isAdminRole(userName)) { userProfile.setUserRole((long) 0); userProfile.setUserTitle(Utils.ADMIN); saveUserProfile(userProfile, false, false); } } return userProfile; } public void saveUserSettingProfile(UserProfile userProfile) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); Node profileNode = getUserProfileNode(sProvider, userProfile.getUserId()); try { profileNode.setProperty(EXO_USER_TITLE, userProfile.getUserTitle()); profileNode.setProperty(EXO_SCREEN_NAME, userProfile.getScreenName()); profileNode.setProperty(EXO_SIGNATURE, userProfile.getSignature()); profileNode.setProperty(EXO_IS_DISPLAY_SIGNATURE, userProfile.getIsDisplaySignature()); profileNode.setProperty(EXO_IS_DISPLAY_AVATAR, userProfile.getIsDisplayAvatar()); profileNode.setProperty(EXO_USER_ROLE, userProfile.getUserRole()); profileNode.setProperty(EXO_TIME_ZONE, userProfile.getTimeZone()); profileNode.setProperty(EXO_SHORT_DATEFORMAT, userProfile.getShortDateFormat()); profileNode.setProperty(EXO_LONG_DATEFORMAT, userProfile.getLongDateFormat()); profileNode.setProperty(EXO_TIME_FORMAT, userProfile.getTimeFormat()); profileNode.setProperty(EXO_MAX_POST, userProfile.getMaxPostInPage()); profileNode.setProperty(EXO_MAX_TOPIC, userProfile.getMaxTopicInPage()); profileNode.setProperty(EXO_IS_AUTO_WATCH_MY_TOPICS, userProfile.getIsAutoWatchMyTopics()); profileNode.setProperty(EXO_IS_AUTO_WATCH_TOPIC_I_POST, userProfile.getIsAutoWatchTopicIPost()); profileNode.save(); } catch (Exception e) { LOG.error("Failed to save setting profile.", e); } } public UserProfile getLastPostIdRead(UserProfile userProfile, String isOfForum) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); Node profileNode = getUserProfileNode(sProvider, userProfile.getUserId()); PropertyReader reader = new PropertyReader(profileNode); if (isOfForum.equals("true")) { userProfile.setLastReadPostOfForum(reader.strings(EXO_LAST_READ_POST_OF_FORUM, new String[] {})); } else if (isOfForum.equals("false")) { userProfile.setLastReadPostOfTopic(reader.strings(EXO_LAST_READ_POST_OF_TOPIC, new String[] {})); } else { userProfile.setLastReadPostOfForum(reader.strings(EXO_LAST_READ_POST_OF_FORUM, new String[] {})); userProfile.setLastReadPostOfTopic(reader.strings(EXO_LAST_READ_POST_OF_TOPIC, new String[] {})); } return userProfile; } public void saveLastPostIdRead(String userId, String[] lastReadPostOfForum, String[] lastReadPostOfTopic) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); try { Node profileNode = getUserProfileNode(sProvider, userId); profileNode.setProperty(EXO_LAST_READ_POST_OF_FORUM, lastReadPostOfForum); profileNode.setProperty(EXO_LAST_READ_POST_OF_TOPIC, lastReadPostOfTopic); profileNode.getSession().save(); } catch (Exception e) { LOG.error("Failed to save last post id read.", e); } } public List<String> getUserModerator(String userName, boolean isModeCate) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); Node userProfileNode = getUserProfileHome(sProvider); List<String> list = new ArrayList<String>(); try { Node profileNode = userProfileNode.getNode(userName); if (isModeCate) try { list.addAll(Utils.valuesToList(profileNode.getProperty(EXO_MODERATE_CATEGORY).getValues())); } catch (Exception e) { if (LOG.isDebugEnabled()) { LOG.debug("Failed to get moderators of categories", e); } } else list.addAll(Utils.valuesToList(profileNode.getProperty(EXO_MODERATE_FORUMS).getValues())); } catch (Exception e) { if (LOG.isDebugEnabled()) { LOG.debug("Failed to get moderators of forums", e); } } return list; } public void saveUserModerator(String userName, List<String> ids, boolean isModeCate) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); Node userProfileNode = getUserProfileHome(sProvider); try { Node profileNode = userProfileNode.getNode(userName); if (isModeCate) profileNode.setProperty(EXO_MODERATE_CATEGORY, Utils.getStringsInList(ids)); else profileNode.setProperty(EXO_MODERATE_FORUMS, Utils.getStringsInList(ids)); profileNode.save(); } catch (Exception e) { LOG.error(String.format("Failed to set %s as moderator", userName)); } } private Node getUserProfileNode(Node profileHome, String userName) throws Exception { try { return profileHome.getNode(userName); } catch (PathNotFoundException e) { return profileHome.getNode(Utils.USER_PROFILE_DELETED).getNode(userName); } catch (Exception e) { throw e; } } public UserProfile getUserInfo(String userName) throws Exception { UserProfile userProfile = new UserProfile(); if (userName == null || userName.length() <= 0) return userProfile; SessionProvider sProvider = CommonUtils.createSystemProvider(); Node userProfileNode = getUserProfileHome(sProvider); Node newProfileNode; try { newProfileNode = getUserProfileNode(userProfileNode, userName); PropertyReader reader = new PropertyReader(newProfileNode); userProfile.setUserId(userName); userProfile.setScreenName(getScreenName(userName, newProfileNode)); userProfile.setFullName(reader.string(EXO_FULL_NAME)); userProfile.setFirstName(reader.string(EXO_FIRST_NAME)); userProfile.setLastName(reader.string(EXO_LAST_NAME)); userProfile.setEmail(reader.string(EXO_EMAIL)); if (isAdminRole(userName)) { userProfile.setUserRole((long) 0); // admin role = 0 } else { userProfile.setUserRole(reader.l(EXO_USER_ROLE)); } userProfile.setUserTitle(reader.string(EXO_USER_TITLE, "")); userProfile.setSignature(reader.string(EXO_SIGNATURE)); userProfile.setTotalPost(reader.l(EXO_TOTAL_POST)); userProfile.setTotalTopic(reader.l(EXO_TOTAL_TOPIC)); userProfile.setBookmark(reader.strings(EXO_BOOKMARK)); userProfile.setLastLoginDate(reader.date(EXO_LAST_LOGIN_DATE)); userProfile.setJoinedDate(reader.date(EXO_JOINED_DATE)); userProfile.setLastPostDate(reader.date(EXO_LAST_POST_DATE)); userProfile.setIsDisplaySignature(reader.bool(EXO_IS_DISPLAY_SIGNATURE)); userProfile.setIsDisplayAvatar(reader.bool(EXO_IS_DISPLAY_AVATAR)); } catch (PathNotFoundException e) { userProfile.setUserId(userName); userProfile.setUserTitle(Utils.USER); userProfile.setUserRole((long) 2); // default Administration if (isAdminRole(userName)) { userProfile.setUserRole((long) 0); userProfile.setUserTitle(Utils.ADMIN); saveUserProfile(userProfile, false, false); } } return userProfile; } public List<UserProfile> getQuickProfiles(List<String> userList) throws Exception { UserProfile userProfile; List<UserProfile> profiles = new ArrayList<UserProfile>(); SessionProvider sProvider = CommonUtils.createSystemProvider(); PropertyReader reader; Node userProfileNode; try { Node userProfileHome = getUserProfileHome(sProvider); for (String userName : userList) { userProfile = new UserProfile(); userProfileNode = getUserProfileNode(userProfileHome, userName); reader = new PropertyReader(userProfileNode); userProfile.setPath(dataLocator.getUserProfilesLocation()); userProfile.setUserId(userName); userProfile.setUserRole((userName.contains(Utils.DELETED)) ? 4 : reader.l(EXO_USER_ROLE, 2)); userProfile.setUserTitle(reader.string(EXO_USER_TITLE, "")); userProfile.setScreenName(getScreenName(userName, userProfileNode)); userProfile.setJoinedDate(reader.date(EXO_JOINED_DATE, new Date())); userProfile.setIsDisplayAvatar(reader.bool(EXO_IS_DISPLAY_AVATAR, false)); userProfile.setTotalPost(reader.l(EXO_TOTAL_POST)); if (userProfile.getTotalPost() > 0) { userProfile.setLastPostDate(reader.date(EXO_LAST_POST_DATE)); } userProfile.setLastLoginDate(reader.date(EXO_LAST_LOGIN_DATE)); userProfile.setIsDisplaySignature(reader.bool(EXO_IS_DISPLAY_SIGNATURE, false)); if (userProfile.getIsDisplaySignature()) userProfile.setSignature(reader.string(EXO_SIGNATURE, "")); profiles.add(userProfile); } } catch (Exception e) { LOG.trace("\nUser Name must exist: " + e.getMessage() + "\n" + e.getCause()); } return profiles; } public UserProfile getQuickProfile(String userName) throws Exception { UserProfile userProfile; SessionProvider sProvider = CommonUtils.createSystemProvider(); Node userProfileHome = getUserProfileHome(sProvider); userProfile = new UserProfile(); Node userProfileNode = getUserProfileNode(userProfileHome, userName); PropertyReader reader = new PropertyReader(userProfileNode); userProfile.setUserId(userName); userProfile.setPath(dataLocator.getUserProfilesLocation()); userProfile.setUserRole((userName.contains(Utils.DELETED)) ? 4 : reader.l(EXO_USER_ROLE, 2)); userProfile.setUserTitle(reader.string(EXO_USER_TITLE, "")); userProfile.setScreenName(getScreenName(userName, userProfileNode)); userProfile.setJoinedDate(reader.date(EXO_JOINED_DATE, new Date())); userProfile.setIsDisplayAvatar(reader.bool(EXO_IS_DISPLAY_AVATAR, false)); userProfile.setTotalPost(reader.l(EXO_TOTAL_POST)); if (userProfile.getTotalPost() > 0) { userProfile.setLastPostDate(reader.date(EXO_LAST_POST_DATE)); } userProfile.setLastLoginDate(reader.date(EXO_LAST_LOGIN_DATE)); userProfile.setIsDisplaySignature(reader.bool(EXO_IS_DISPLAY_SIGNATURE, false)); if (userProfile.getIsDisplaySignature()) userProfile.setSignature(reader.string(EXO_SIGNATURE, "")); return userProfile; } public UserProfile getUserInformations(UserProfile userProfile) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); Node userProfileHome = getUserProfileHome(sProvider); Node profileNode = getUserProfileNode(userProfileHome, userProfile.getUserId()); PropertyReader reader = new PropertyReader(profileNode); userProfile.setFirstName(reader.string(EXO_FIRST_NAME, "")); userProfile.setLastName(reader.string(EXO_LAST_NAME, "")); userProfile.setFullName(reader.string(EXO_FULL_NAME, "")); userProfile.setEmail(reader.string(EXO_EMAIL, "")); return userProfile; } public void saveUserProfile(UserProfile newUserProfile, boolean isOption, boolean isBan) throws Exception { Node newProfileNode; String userName = newUserProfile.getUserId(); if (userName == null || userName.length() <= 0) return; SessionProvider sProvider = CommonUtils.createSystemProvider(); Node userProfileHome = getUserProfileHome(sProvider); long role = 2; try { newProfileNode = userProfileHome.getNode(userName); if (newProfileNode.hasProperty(EXO_USER_ROLE)) { role = new PropertyReader(newProfileNode).l(EXO_USER_ROLE); } } catch (PathNotFoundException e) { newProfileNode = userProfileHome.addNode(userName, EXO_FORUM_USER_PROFILE); newProfileNode.setProperty(EXO_USER_ID, userName); newProfileNode.setProperty(EXO_TOTAL_POST, 0); newProfileNode.setProperty(EXO_TOTAL_TOPIC, 0); newProfileNode.setProperty(EXO_READ_TOPIC, new String[] {}); newProfileNode.setProperty(EXO_READ_FORUM, new String[] {}); if (newUserProfile.getUserRole() >= 2) { newUserProfile.setUserRole((long) 2); } if (isAdminRole(userName)) { newUserProfile.setUserTitle(Utils.ADMIN); } } newProfileNode.setProperty(EXO_USER_ROLE, newUserProfile.getUserRole()); newProfileNode.setProperty(EXO_USER_TITLE, newUserProfile.getUserTitle()); newProfileNode.setProperty(EXO_SCREEN_NAME, newUserProfile.getScreenName()); newProfileNode.setProperty(EXO_SIGNATURE, newUserProfile.getSignature()); newProfileNode.setProperty(EXO_IS_AUTO_WATCH_MY_TOPICS, newUserProfile.getIsAutoWatchMyTopics()); newProfileNode.setProperty(EXO_IS_AUTO_WATCH_TOPIC_I_POST, newUserProfile.getIsAutoWatchTopicIPost()); newProfileNode.setProperty(EXO_MODERATE_CATEGORY, newUserProfile.getModerateCategory()); Calendar calendar = getGreenwichMeanTime(); if (newUserProfile.getLastLoginDate() != null) calendar.setTime(newUserProfile.getLastLoginDate()); newProfileNode.setProperty(EXO_LAST_LOGIN_DATE, calendar); newProfileNode.setProperty(EXO_IS_DISPLAY_SIGNATURE, newUserProfile.getIsDisplaySignature()); newProfileNode.setProperty(EXO_IS_DISPLAY_AVATAR, newUserProfile.getIsDisplayAvatar()); // UserOption if (isOption) { newProfileNode.setProperty(EXO_TIME_ZONE, newUserProfile.getTimeZone()); newProfileNode.setProperty(EXO_SHORT_DATEFORMAT, newUserProfile.getShortDateFormat()); newProfileNode.setProperty(EXO_LONG_DATEFORMAT, newUserProfile.getLongDateFormat()); newProfileNode.setProperty(EXO_TIME_FORMAT, newUserProfile.getTimeFormat()); newProfileNode.setProperty(EXO_MAX_POST, newUserProfile.getMaxPostInPage()); newProfileNode.setProperty(EXO_MAX_TOPIC, newUserProfile.getMaxTopicInPage()); } // UserBan if (isBan) { if (newProfileNode.hasProperty(EXO_IS_BANNED)) { if (!newProfileNode.getProperty(EXO_IS_BANNED).getBoolean() && newUserProfile.getIsBanned()) { newProfileNode.setProperty(EXO_CREATED_DATE_BAN, getGreenwichMeanTime()); } } else { newProfileNode.setProperty(EXO_CREATED_DATE_BAN, getGreenwichMeanTime()); } newProfileNode.setProperty(EXO_IS_BANNED, newUserProfile.getIsBanned()); newProfileNode.setProperty(EXO_BAN_UNTIL, newUserProfile.getBanUntil()); newProfileNode.setProperty(EXO_BAN_REASON, newUserProfile.getBanReason()); newProfileNode.setProperty(EXO_BAN_COUNTER, "" + newUserProfile.getBanCounter()); newProfileNode.setProperty(EXO_BAN_REASON_SUMMARY, newUserProfile.getBanReasonSummary()); } if (userProfileHome.isNew()) { userProfileHome.getSession().save(); } else { userProfileHome.save(); } if (role >= 2 && newUserProfile.getUserRole() < 2 && !isAdminRole(userName)) { getTotalJobWaitingForModerator(userProfileHome.getSession(), userName); } } public UserProfile getUserProfileManagement(String userName) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); try { Node userProfileNode = getUserProfileNode(getUserProfileHome(sProvider), userName); return getUserProfile(userProfileNode); } catch (Exception e) { return null; } } private UserProfile getUserProfile(Node userProfileNode) throws Exception { UserProfile userProfile = new UserProfile(); userProfile.setUserId(userProfileNode.getName()); PropertyReader reader = new PropertyReader(userProfileNode); userProfile.setUserTitle(reader.string(EXO_USER_TITLE, "")); userProfile.setScreenName(getScreenName(userProfileNode.getName(), userProfileNode)); userProfile.setFullName(reader.string(EXO_FULL_NAME, "")); userProfile.setFirstName(reader.string(EXO_FIRST_NAME, "")); userProfile.setLastName(reader.string(EXO_LAST_NAME, "")); userProfile.setEmail(reader.string(EXO_EMAIL, "")); userProfile.setUserRole(reader.l(EXO_USER_ROLE)); userProfile.setSignature(reader.string(EXO_SIGNATURE, "")); userProfile.setTotalPost(reader.l(EXO_TOTAL_POST)); userProfile.setTotalTopic(reader.l(EXO_TOTAL_TOPIC)); userProfile.setModerateForums(reader.strings(EXO_MODERATE_FORUMS, new String[] {})); try { userProfile.setModerateCategory(reader.strings(EXO_MODERATE_CATEGORY, new String[] {})); } catch (Exception e) { userProfile.setModerateCategory(new String[] {}); } if (userProfileNode.hasProperty(EXO_LAST_LOGIN_DATE)) userProfile.setLastLoginDate(userProfileNode.getProperty(EXO_LAST_LOGIN_DATE).getDate().getTime()); if (userProfileNode.hasProperty(EXO_JOINED_DATE)) userProfile.setJoinedDate(userProfileNode.getProperty(EXO_JOINED_DATE).getDate().getTime()); if (userProfileNode.hasProperty(EXO_LAST_POST_DATE)) userProfile.setLastPostDate(userProfileNode.getProperty(EXO_LAST_POST_DATE).getDate().getTime()); userProfile.setIsDisplaySignature(reader.bool(EXO_IS_DISPLAY_SIGNATURE)); userProfile.setIsDisplayAvatar(reader.bool(EXO_IS_DISPLAY_AVATAR)); userProfile.setNewMessage(reader.l(EXO_NEW_MESSAGE)); userProfile.setTimeZone(reader.d(EXO_TIME_ZONE)); userProfile.setShortDateFormat(reader.string(EXO_SHORT_DATEFORMAT, "")); userProfile.setLongDateFormat(reader.string(EXO_LONG_DATEFORMAT, "")); userProfile.setTimeFormat(reader.string(EXO_TIME_FORMAT, "")); userProfile.setMaxPostInPage(reader.l(EXO_MAX_POST)); userProfile.setMaxTopicInPage(reader.l(EXO_MAX_TOPIC)); userProfile.setIsBanned(reader.bool(EXO_IS_BANNED)); if (userProfile.getIsBanned()) { if (userProfileNode.hasProperty(EXO_BAN_UNTIL)) { userProfile.setBanUntil(reader.l(EXO_BAN_UNTIL)); if (userProfile.getBanUntil() <= getGreenwichMeanTime().getTimeInMillis()) { userProfileNode.setProperty(EXO_IS_BANNED, false); userProfileNode.save(); userProfile.setIsBanned(false); } } } if (userProfileNode.hasProperty(EXO_BAN_REASON)) userProfile.setBanReason(reader.string(EXO_BAN_REASON, "")); if (userProfileNode.hasProperty(EXO_BAN_COUNTER)) userProfile.setBanCounter(Integer.parseInt(reader.string(EXO_BAN_COUNTER, ""))); if (userProfileNode.hasProperty(EXO_BAN_REASON_SUMMARY)) userProfile.setBanReasonSummary(reader.strings(EXO_BAN_REASON_SUMMARY, new String[] {})); if (userProfileNode.hasProperty(EXO_CREATED_DATE_BAN)) userProfile.setCreatedDateBan(userProfileNode.getProperty(EXO_CREATED_DATE_BAN).getDate().getTime()); return userProfile; } public void saveUserBookmark(String userName, String bookMark, boolean isNew) throws Exception { Node newProfileNode; SessionProvider sProvider = CommonUtils.createSystemProvider(); try { Node userProfileNode = getUserProfileHome(sProvider); try { newProfileNode = userProfileNode.getNode(userName); if (newProfileNode.hasProperty(EXO_BOOKMARK)) { List<String> listOld = Utils.valuesToList(newProfileNode.getProperty(EXO_BOOKMARK).getValues()); List<String> listNew = new ArrayList<String>(); String pathNew = bookMark.substring(bookMark.lastIndexOf("//") + 1); String pathOld = ""; boolean isAdd = true; for (String string : listOld) { pathOld = string.substring(string.lastIndexOf("//") + 1); if (pathNew.equals(pathOld)) { if (isNew) { listNew.add(bookMark); } isAdd = false; continue; } listNew.add(string); } if (isAdd) { listNew.add(bookMark); } String[] bookMarks = listNew.toArray(new String[listNew.size()]); newProfileNode.setProperty(EXO_BOOKMARK, bookMarks); if (newProfileNode.isNew()) { newProfileNode.getSession().save(); } else { newProfileNode.save(); } } else { newProfileNode.setProperty(EXO_BOOKMARK, new String[] { bookMark }); if (newProfileNode.isNew()) { newProfileNode.getSession().save(); } else { newProfileNode.save(); } } } catch (PathNotFoundException e) { newProfileNode = userProfileNode.addNode(userName, EXO_FORUM_USER_PROFILE); newProfileNode.setProperty(EXO_USER_ID, userName); newProfileNode.setProperty(EXO_USER_TITLE, Utils.USER); if (isAdminRole(userName)) { newProfileNode.setProperty(EXO_USER_TITLE, Utils.ADMIN); } newProfileNode.setProperty(EXO_USER_ROLE, 2); newProfileNode.setProperty(EXO_BOOKMARK, new String[] { bookMark }); if (newProfileNode.isNew()) { newProfileNode.getSession().save(); } else { newProfileNode.save(); } } } catch (Exception e) { LOG.error("Failed to save UserBookmark.", e); } } public void saveCollapsedCategories(String userName, String categoryId, boolean isAdd) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); Node newProfileNode; Node userProfileHome = getUserProfileHome(sProvider); try { newProfileNode = userProfileHome.getNode(userName); if (newProfileNode.hasProperty(EXO_COLLAP_CATEGORIES)) { List<String> listCategoryId = Utils .valuesToList(newProfileNode.getProperty(EXO_COLLAP_CATEGORIES).getValues()); if (listCategoryId.contains(categoryId)) { if (!isAdd) { listCategoryId.remove(categoryId); isAdd = true; } } else { if (isAdd) { listCategoryId.add(categoryId); } } if (isAdd) { String[] categoryIds = listCategoryId.toArray(new String[listCategoryId.size()]); newProfileNode.setProperty(EXO_COLLAP_CATEGORIES, categoryIds); if (newProfileNode.isNew()) { newProfileNode.getSession().save(); } else { newProfileNode.save(); } } } else { newProfileNode.setProperty(EXO_COLLAP_CATEGORIES, new String[] { categoryId }); if (newProfileNode.isNew()) { newProfileNode.getSession().save(); } else { newProfileNode.save(); } } } catch (PathNotFoundException e) { newProfileNode = userProfileHome.addNode(userName, EXO_FORUM_USER_PROFILE); newProfileNode.setProperty(EXO_USER_ID, userName); newProfileNode.setProperty(EXO_USER_TITLE, Utils.USER); if (isAdminRole(userName)) { newProfileNode.setProperty(EXO_USER_TITLE, Utils.ADMIN); } newProfileNode.setProperty(EXO_USER_ROLE, 2); newProfileNode.setProperty(EXO_COLLAP_CATEGORIES, new String[] { categoryId }); if (newProfileNode.isNew()) { newProfileNode.getSession().save(); } else { newProfileNode.save(); } } catch (Exception e) { if (LOG.isDebugEnabled()) { LOG.debug("Failed to save collapsed categories.", e); } } } public void saveReadMessage(String messageId, String userName, String type) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); Node userProfileNode = getUserProfileHome(sProvider); try { Node profileNode = userProfileNode.getNode(userName); long totalNewMessage = 0; boolean isNew = false; try { Node messageNode = profileNode.getNode(messageId); if (messageNode.hasProperty(EXO_IS_UNREAD)) { isNew = messageNode.getProperty(EXO_IS_UNREAD).getBoolean(); } if (isNew) {// First read message. messageNode.setProperty(EXO_IS_UNREAD, false); } } catch (PathNotFoundException e) { LOG.error("Failed to save read massage", e); } if (type.equals(Utils.RECEIVE_MESSAGE) && isNew) { if (profileNode.hasProperty(EXO_NEW_MESSAGE)) { totalNewMessage = profileNode.getProperty(EXO_NEW_MESSAGE).getLong(); if (totalNewMessage > 0) { profileNode.setProperty(EXO_NEW_MESSAGE, (totalNewMessage - 1)); } } } if (isNew) { if (userProfileNode.isNew()) { userProfileNode.getSession().save(); } else { userProfileNode.save(); } } } catch (Exception e) { LOG.error("Failed to save read message."); } } public JCRPageList getPrivateMessage(String userName, String type) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); Node userProfileNode = getUserProfileHome(sProvider); try { Node profileNode = userProfileNode.getNode(userName); QueryManager qm = profileNode.getSession().getWorkspace().getQueryManager(); String pathQuery = JCR_ROOT + profileNode.getPath() + "/element(*,exo:privateMessage)[@exo:type='" + type + "'] order by @exo:receivedDate descending"; Query query = qm.createQuery(pathQuery, Query.XPATH); QueryResult result = query.execute(); NodeIterator iter = result.getNodes(); JCRPageList pagelist = new ForumPageList(iter, 10, pathQuery, true); return pagelist; } catch (Exception e) { return null; } } public long getNewPrivateMessage(String userName) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); Node userProfileNode = getUserProfileHome(sProvider); try { Node profileNode = userProfileNode.getNode(userName); if (!profileNode.getProperty(EXO_IS_BANNED).getBoolean()) { return profileNode.getProperty(EXO_NEW_MESSAGE).getLong(); } } catch (PathNotFoundException e) { return -1; } return -1; } public void savePrivateMessage(ForumPrivateMessage privateMessage) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); Node userProfileNode = getUserProfileHome(sProvider); Node profileNode = null; Node profileNodeFirst = null; Node messageNode = null; String sendTo = privateMessage.getSendTo(); sendTo = sendTo.replaceAll(";", ","); String[] strUserNames = sendTo.split(","); List<String> userNames; try { userNames = ForumServiceUtils.getUserPermission(strUserNames); } catch (Exception e) { userNames = Arrays.asList(strUserNames); } String id; String userNameFirst = privateMessage.getFrom(); try { profileNodeFirst = userProfileNode.getNode(userNameFirst); } catch (PathNotFoundException e) { profileNodeFirst = addNodeUserProfile(sProvider, userNameFirst); } long totalMessage = 0; if (profileNodeFirst != null) { id = userNameFirst + IdGenerator.generate(); messageNode = profileNodeFirst.addNode(id, EXO_PRIVATE_MESSAGE); messageNode.setProperty(EXO_FROM, privateMessage.getFrom()); messageNode.setProperty(EXO_SEND_TO, privateMessage.getSendTo()); messageNode.setProperty(EXO_NAME, privateMessage.getName()); messageNode.setProperty(EXO_MESSAGE, privateMessage.getMessage()); messageNode.setProperty(EXO_RECEIVED_DATE, getGreenwichMeanTime()); messageNode.setProperty(EXO_IS_UNREAD, true); messageNode.setProperty(EXO_TYPE, Utils.RECEIVE_MESSAGE); } for (String userName : userNames) { if (userName.equals(userNameFirst)) continue; try { profileNode = userProfileNode.getNode(userName); totalMessage = profileNode.getProperty(EXO_NEW_MESSAGE).getLong() + 1; id = profileNode.getPath() + "/" + userName + IdGenerator.generate(); userProfileNode.getSession().getWorkspace().copy(messageNode.getPath(), id); profileNode.setProperty(EXO_NEW_MESSAGE, totalMessage); } catch (Exception e) { profileNode = addNodeUserProfile(sProvider, userName); id = profileNode.getPath() + "/" + userName + IdGenerator.generate(); userProfileNode.getSession().getWorkspace().copy(messageNode.getPath(), id); profileNode.setProperty(EXO_NEW_MESSAGE, 1); } } // send notification message for user privateMessage.setType("PrivateMessage"); sendNotificationMessage(privateMessage); if (messageNode != null) { messageNode.setProperty(EXO_TYPE, Utils.SEND_MESSAGE); } if (userProfileNode.isNew()) { userProfileNode.getSession().save(); } else { userProfileNode.save(); } } private Node addNodeUserProfile(SessionProvider sProvider, String userName) throws Exception { Node userProfileHome = getUserProfileHome(sProvider); Node profileNode = userProfileHome.addNode(userName, EXO_FORUM_USER_PROFILE); profileNode.setProperty(EXO_USER_ID, userName); profileNode.setProperty(EXO_USER_TITLE, Utils.USER); if (isAdminRole(userName)) { profileNode.setProperty(EXO_USER_ROLE, 0); profileNode.setProperty(EXO_USER_TITLE, Utils.ADMIN); } profileNode.setProperty(EXO_USER_ROLE, 2); if (userProfileHome.isNew()) { userProfileHome.getSession().save(); } else { userProfileHome.save(); } return profileNode; } public void removePrivateMessage(String messageId, String userName, String type) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); Node userProfileNode = getUserProfileHome(sProvider); try { Node profileNode = userProfileNode.getNode(userName); Node messageNode = profileNode.getNode(messageId); if (type.equals(Utils.RECEIVE_MESSAGE)) { if (messageNode.hasProperty(EXO_IS_UNREAD)) { if (messageNode.getProperty(EXO_IS_UNREAD).getBoolean()) { long totalMessage = profileNode.getProperty(EXO_NEW_MESSAGE).getLong(); if (totalMessage > 0) { profileNode.setProperty(EXO_NEW_MESSAGE, (totalMessage - 1)); } } } } messageNode.remove(); profileNode.save(); } catch (PathNotFoundException e) { LOG.error("Failed to remove private message", e); } } public ForumSubscription getForumSubscription(String userId) { SessionProvider sProvider = CommonUtils.createSystemProvider(); ForumSubscription forumSubscription = new ForumSubscription(); try { Node subscriptionNode = getUserProfileHome(sProvider) .getNode(userId + "/" + Utils.FORUM_SUBSCRIOTION + userId); PropertyReader reader = new PropertyReader(subscriptionNode); forumSubscription.setCategoryIds(reader.strings(EXO_CATEGORY_IDS, new String[] {})); forumSubscription.setForumIds(reader.strings(EXO_FORUM_IDS, new String[] {})); forumSubscription.setTopicIds(reader.strings(EXO_TOPIC_IDS, new String[] {})); } catch (Exception e) { if (LOG.isDebugEnabled()) { LOG.debug(String.format("Failed to get forum subscription for user %s", userId), e); } } return forumSubscription; } public void saveForumSubscription(ForumSubscription forumSubscription, String userId) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); try { Node profileNode = getUserProfileHome(sProvider).getNode(userId); Node subscriptionNode; String id = Utils.FORUM_SUBSCRIOTION + userId; try { subscriptionNode = profileNode.getNode(id); } catch (PathNotFoundException e) { subscriptionNode = profileNode.addNode(id, EXO_FORUM_SUBSCRIPTION); } subscriptionNode.setProperty(EXO_CATEGORY_IDS, forumSubscription.getCategoryIds()); subscriptionNode.setProperty(EXO_FORUM_IDS, forumSubscription.getForumIds()); subscriptionNode.setProperty(EXO_TOPIC_IDS, forumSubscription.getTopicIds()); if (profileNode.isNew()) { profileNode.getSession().save(); } else { profileNode.save(); } } catch (Exception e) { LOG.error("Failed to save forum subscription.", e); } } private String[] getValueProperty(Node node, String property, String objectId) throws Exception { List<String> list = new ArrayList<String>(); if (node.hasProperty(property)) { list.addAll(Utils.valuesToList(node.getProperty(property).getValues())); if (!list.contains(objectId)) list.add(objectId); } else { list.add(objectId); } return list.toArray(new String[list.size()]); } public ForumStatistic getForumStatistic() throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); ForumStatistic forumStatistic = new ForumStatistic(); try { Node forumStatisticNode = getForumStatisticsNode(sProvider); PropertyReader reader = new PropertyReader(forumStatisticNode); forumStatistic.setPostCount(reader.l(EXO_POST_COUNT, 0)); forumStatistic.setTopicCount(reader.l(EXO_TOPIC_COUNT, 0)); forumStatistic.setMembersCount(reader.l(EXO_MEMBERS_COUNT, 0)); forumStatistic.setActiveUsers(reader.l(EXO_ACTIVE_USERS, 0)); forumStatistic.setNewMembers(reader.string(EXO_NEW_MEMBERS, "")); forumStatistic.setMostUsersOnline(reader.string(EXO_MOST_USERS_ONLINE, "")); } catch (Exception e) { if (LOG.isDebugEnabled()) { LOG.debug("Failed to load forum statistics", e); } } finally { sProvider.close(); } return forumStatistic; } public void saveForumStatistic(ForumStatistic forumStatistic) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { Node forumStatisticNode = getForumStatisticsNode(sProvider); forumStatisticNode.setProperty(EXO_POST_COUNT, forumStatistic.getPostCount()); forumStatisticNode.setProperty(EXO_TOPIC_COUNT, forumStatistic.getTopicCount()); forumStatisticNode.setProperty(EXO_MEMBERS_COUNT, forumStatistic.getMembersCount()); forumStatisticNode.setProperty(EXO_ACTIVE_USERS, forumStatistic.getActiveUsers()); forumStatisticNode.setProperty(EXO_MOST_USERS_ONLINE, forumStatistic.getMostUsersOnline()); if (!Utils.isEmpty(forumStatistic.getNewMembers())) forumStatisticNode.setProperty(EXO_NEW_MEMBERS, forumStatistic.getNewMembers()); if (forumStatisticNode.isNew()) { forumStatisticNode.getSession().save(); } else { forumStatisticNode.save(); } } catch (Exception e) { LOG.error("Failed to save forum statistics", e); } finally { sProvider.close(); } } public Object getObjectNameByPath(String path) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); Object object; try { if (path.indexOf(KSDataLocation.Locations.FORUM_CATEGORIES_HOME) < 0 && (path.indexOf(Utils.CATEGORY) >= 0)) { path = getCategoryHome(sProvider).getPath() + "/" + path; } else if (path.indexOf(Utils.TAG) == 0) { path = getTagHome(sProvider).getPath() + "/" + path; } Node myNode = (Node) getForumHomeNode(sProvider).getSession().getItem(path); if (path.indexOf(Utils.POST) > 0) { Post post = new Post(); post.setId(myNode.getName()); post.setPath(path); post.setName(myNode.getProperty(EXO_NAME).getString()); object = post; } else if (path.indexOf(Utils.TOPIC) > 0) { Topic topic = new Topic(); topic.setId(myNode.getName()); topic.setPath(path); topic.setTopicName(myNode.getProperty(EXO_NAME).getString()); object = topic; } else if (path.indexOf(Utils.FORUM) > 0 && (path.lastIndexOf(Utils.FORUM) > path.indexOf(Utils.CATEGORY))) { Forum forum = new Forum(); forum.setId(myNode.getName()); forum.setPath(path); forum.setForumName(myNode.getProperty(EXO_NAME).getString()); object = forum; } else if (path.indexOf(Utils.CATEGORY) > 0) { Category category = new Category(); category.setId(myNode.getName()); category.setPath(path); category.setCategoryName(myNode.getProperty(EXO_NAME).getString()); object = category; } else if (path.indexOf(Utils.TAG) > 0) { Tag tag = new Tag(); tag.setId(myNode.getName()); tag.setName(myNode.getProperty(EXO_NAME).getString()); object = tag; } else return null; return object; } catch (RepositoryException e) { return null; } } public Object getObjectNameById(String id, String type) throws Exception { Object object = null; SessionProvider sProvider = CommonUtils.createSystemProvider(); try { Node node = getNodeById(sProvider, id, type); if (type.equals(Utils.CATEGORY)) { Category category = getCategory(node); object = category; } else if (type.equals(Utils.FORUM)) { Forum forum = getForum(node); object = forum; } else if (type.equals(Utils.TOPIC)) { Topic topic = getTopicNode(node); object = topic; } else { Post post = getPost(node); object = post; } } catch (Exception e) { if (LOG.isDebugEnabled()) { LOG.debug("Can not get " + type + " by Id: " + id, e); } } return object; } private Node getNodeById(SessionProvider sProvider, String id, String type) { try { Node categoryHome = getCategoryHome(sProvider); if (type.equals(Utils.CATEGORY)) return categoryHome.getNode(id); QueryManager qm = categoryHome.getSession().getWorkspace().getQueryManager(); StringBuffer stringBuffer = new StringBuffer(JCR_ROOT).append(categoryHome.getPath()) .append("//element(*,exo:").append(type).append(")[(@").append(EXO_ID).append("='").append(id) .append("') or (fn:name()='").append(id).append("')]"); Query query = qm.createQuery(stringBuffer.toString(), Query.XPATH); QueryResult result = query.execute(); NodeIterator iter = result.getNodes(); if (iter.getSize() > 0) return iter.nextNode(); } catch (Exception e) { if (LOG.isDebugEnabled()) { LOG.debug("Can not get Node by Id: " + id, e); } } return null; } public List<ForumLinkData> getAllLink(String strQueryCate, String strQueryForum) throws Exception { List<ForumLinkData> forumLinks = new ArrayList<ForumLinkData>(); SessionProvider sProvider = CommonUtils.createSystemProvider(); Node categoryHome = getCategoryHome(sProvider); QueryManager qm = categoryHome.getSession().getWorkspace().getQueryManager(); StringBuffer queryString = new StringBuffer(); queryString.append(JCR_ROOT).append(categoryHome.getPath()).append("/element(*,exo:forumCategory)") .append(strQueryCate).append(" order by @exo:categoryOrder ascending, @exo:createdDate ascending"); Query query = qm.createQuery(queryString.toString(), Query.XPATH); QueryResult result = query.execute(); NodeIterator iter = result.getNodes(); ForumLinkData linkData; while (iter.hasNext()) { linkData = new ForumLinkData(); Node cateNode = iter.nextNode(); linkData.setId(cateNode.getName()); linkData.setName(cateNode.getProperty(EXO_NAME).getString()); linkData.setType(Utils.CATEGORY); linkData.setPath(cateNode.getName()); forumLinks.add(linkData); { queryString = new StringBuffer(); queryString.append(JCR_ROOT).append(cateNode.getPath()).append("/element(*,exo:forum)") .append(strQueryForum) .append(" order by @exo:forumOrder ascending,@exo:createdDate ascending"); query = qm.createQuery(queryString.toString(), Query.XPATH); result = query.execute(); NodeIterator iterForum = result.getNodes(); while (iterForum.hasNext()) { linkData = new ForumLinkData(); Node forumNode = iterForum.nextNode(); linkData.setId(forumNode.getName()); linkData.setName(forumNode.getProperty(EXO_NAME).getString()); linkData.setType(Utils.FORUM); linkData.setPath(cateNode.getName() + "/" + forumNode.getName()); if (forumNode.hasProperty(EXO_IS_LOCK)) linkData.setIsLock(forumNode.getProperty(EXO_IS_LOCK).getBoolean()); if (forumNode.hasProperty(EXO_IS_CLOSED)) linkData.setIsClosed(forumNode.getProperty(EXO_IS_CLOSED).getBoolean()); forumLinks.add(linkData); } } } return forumLinks; } public List<ForumSearchResult> getQuickSearch(String textQuery, String type_, String pathQuery, String userId, List<String> listCateIds, List<String> listForumIds, List<String> forumIdsOfModerator) throws Exception { List<ForumSearchResult> listSearchEvent = new ArrayList<ForumSearchResult>(); SessionProvider sProvider = CommonUtils.createSystemProvider(); try { Node categoryHome = getCategoryHome(sProvider); QueryManager qm = categoryHome.getSession().getWorkspace().getQueryManager(); // Check path query if (pathQuery == null || pathQuery.length() <= 0) { pathQuery = categoryHome.getPath(); } textQuery = StringUtils.replace(textQuery, "'", "'"); String[] values = type_.split(",");// user(admin or not admin), type(forum, topic, post) boolean isAdmin = false; if (values[0].equals("true")) isAdmin = true; String types[] = new String[] { Utils.CATEGORY, Utils.FORUM, Utils.TOPIC, Utils.POST }; if (!values[1].equals("all")) { types = values[1].split("/"); } boolean isAnd = false; String searchBy = null; List<String> listOfUser = new ArrayList<String>(); // If user isn't admin , get all membership of user if (!isAdmin) { listOfUser = UserHelper.getAllGroupAndMembershipOfUser(null); // Get all category & forum that user can view Map<String, List<String>> mapList = getCategoryViewer(categoryHome, listOfUser, listCateIds, listForumIds, EXO_USER_PRIVATE); listCateIds = mapList.get(Utils.CATEGORY); listForumIds = mapList.get(Utils.FORUM); } for (String type : types) { StringBuffer queryString = new StringBuffer(); // select * from exo:type -- category, forum ,topic , post queryString.append(JCR_ROOT).append(pathQuery).append("//element(*,exo:").append(type).append(")"); queryString.append("["); // if search in category and list category that user can view not null if (type.equals(Utils.CATEGORY)) { if (listCateIds != null && listCateIds.size() > 0) { queryString.append("("); // select all category have name in list user can view for (int i = 0; i < listCateIds.size(); i++) { queryString.append("fn:name() = '").append(listCateIds.get(i)).append("'"); if (i < listCateIds.size() - 1) queryString.append(" or "); } queryString.append(") and "); } // Select all forum that user can view } else if (listForumIds != null && listForumIds.size() > 0) { if (type.equals(Utils.FORUM)) searchBy = "fn:name()"; else searchBy = "@exo:path"; queryString.append("("); for (int i = 0; i < listForumIds.size(); i++) { queryString.append(searchBy).append("='").append(listForumIds.get(i)).append("'"); if (i < listForumIds.size() - 1) queryString.append(" or "); } queryString.append(") and "); } // Append text query if (textQuery != null && textQuery.length() > 0 && !textQuery.equals("null")) { queryString.append("(jcr:contains(., '").append(textQuery).append("'))"); isAnd = true; } // if user isn't admin if (!isAdmin) { StringBuilder builder = new StringBuilder(); // check user if user is moderator if (forumIdsOfModerator != null && !forumIdsOfModerator.isEmpty()) { for (String string : forumIdsOfModerator) { builder.append(" or (@exo:path='").append(string).append("')"); } } // search forum not close in this user is moderator if (type.equals(Utils.FORUM)) { if (isAnd) queryString.append(" and "); queryString.append("(@exo:isClosed='false'"); for (String forumId : forumIdsOfModerator) { queryString.append(" or fn:name()='").append(forumId).append("'"); } queryString.append(")"); } else { // search topic if (type.equals(Utils.TOPIC)) { if (isAnd) queryString.append(" and "); queryString.append( "((@exo:isClosed='false' and @exo:isWaiting='false' and @exo:isApproved='true' and @exo:isActive='true' and @exo:isActiveByForum='true')"); if (builder.length() > 0) { queryString.append(builder); } queryString.append(")"); String str = Utils.buildXpathByUserInfo(EXO_CAN_VIEW, listOfUser); if (!Utils.isEmpty(str)) { if (isAnd) { queryString.append(" and "); } queryString.append("(@").append(Utils.EXO_OWNER).append("='").append(userId) .append("' or ").append(Utils.buildXpathHasProperty(EXO_CAN_VIEW)) .append(" or ").append(str).append(")"); } // seach post } else if (type.equals(Utils.POST)) { if (isAnd) queryString.append(" and "); queryString.append( "((@exo:isApproved='true' and @exo:isHidden='false' and @exo:isActiveByTopic='true')"); if (builder.length() > 0) { queryString.append(builder); } queryString.append(") and (@exo:userPrivate='exoUserPri'") .append(" or @exo:userPrivate='").append(userId) .append("') and @exo:isFirstPost='false'"); } } } else { if (type.equals(Utils.POST)) { if (isAnd) queryString.append(" and "); queryString.append("(@exo:userPrivate='exoUserPri'").append(" or @exo:userPrivate='") .append(userId).append("') and @exo:isFirstPost='false'"); } } queryString.append("]"); // System.out.println("\n\n=======>"+queryString.toString()); Query query = qm.createQuery(queryString.toString(), Query.XPATH); QueryResult result = query.execute(); NodeIterator iter = result.getNodes(); // System.out.println("\n\n=======>iter: "+iter.getSize()); while (iter.hasNext()) { Node nodeObj = iter.nextNode(); listSearchEvent.add(setPropertyForForumSearch(nodeObj, type)); } if (type.equals(Utils.POST)) { listSearchEvent.addAll(getSearchByAttachment(categoryHome, pathQuery, textQuery, listForumIds, listOfUser, isAdmin, "")); } } // System.out.println("\n\n=======>listSearchEvent: "+listSearchEvent.size()); if (!isAdmin && listSearchEvent.size() > 0) { List<String> categoryCanView = new ArrayList<String>(); List<String> forumCanView = new ArrayList<String>(); Map<String, List<String>> mapList = getCategoryViewer(categoryHome, listOfUser, listCateIds, new ArrayList<String>(), EXO_VIEWER); categoryCanView = mapList.get(Utils.CATEGORY); forumCanView.addAll(getCachedDataStorage().getForumUserCanView(listOfUser, listForumIds)); if (categoryCanView.size() > 0 || forumCanView.size() > 0) listSearchEvent = removeItemInList(listSearchEvent, forumCanView, categoryCanView); } } catch (Exception e) { throw e; } return listSearchEvent; } public List<ForumSearchResult> getUnifiedSearch(String textQuery, String userId, Integer offset, Integer limit, String sort, String order) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); List<ForumSearchResult> list = new ArrayList<ForumSearchResult>(); try { Node categoryHome = getCategoryHome(sProvider); QueryManager qm = categoryHome.getSession().getWorkspace().getQueryManager(); //String rootPath = categoryHome.getPath(); //process query for asterisk String asteriskQuery = CommonUtils.processLikeCondition(textQuery).toUpperCase(); textQuery = CommonUtils.processUnifiedSearchSearchCondition(textQuery); //textQuery = CommonUtils.encodeSpecialCharToHTMLnumber(textQuery, "~", true); boolean isAdmin = isAdminRole(userId); List<String> listOfUser = UserHelper.getAllGroupAndMembershipOfUser(null); List<String> listForumIds = getCachedDataStorage().getForumUserCanView(listOfUser, new ArrayList<String>()); //for (String type : types) { StringBuilder queryString = buildSQLQueryUnifiedSearch(listForumIds, asteriskQuery, textQuery, isAdmin, sort, order, userId, listOfUser); //System.out.println("\n" + queryString.toString() + "\n"); QueryImpl query = (QueryImpl) qm.createQuery(queryString.toString(), Query.SQL); query.setLimit(30); query.setOffset(offset); //query.setCaseInsensitiveOrder(true); QueryResult result = query.execute(); NodeIterator iter = result.getNodes(); //RowIterator rowIterator = result.getRows(); while (iter.hasNext() && limit > 0) { Node nodeObj = iter.nextNode(); //Row row = rowIterator.nextRow(); if (hasPermssionViewerPost(nodeObj, listOfUser) == false) { continue; } list.add(setPropertyUnifiedSearch(nodeObj, textQuery)); limit--; } } catch (Exception e) { throw e; } // return UnifiedSearchOrder.processOrder(list, sort, order); } private StringBuilder buildSQLQueryUnifiedSearch(List<String> listForumIds, String asteriskQuery, String textQuery, boolean isAdmin, String sort, String order, String userId, List<String> listOfUser) { StringBuilder queryString = new StringBuilder(); queryString.append("select exo:name, exo:message, rep:excerpt() from exo:post where "); if (listForumIds != null && listForumIds.size() > 0) { queryString.append("("); for (int i = 0; i < listForumIds.size(); i++) { queryString.append(EXO_PATH).append("='").append(listForumIds.get(i)).append("'"); if (i < listForumIds.size() - 1) queryString.append(" or "); } queryString.append(") and "); } queryString.append("(") //.append("(CONTAINS (exo:message, '").append(textQuery).append("')") .append("UPPER(exo:message) LIKE '").append(asteriskQuery).append("'") .append(" or (exo:isFirstPost='true' and ") //.append("(CONTAINS (exo:name, '").append(textQuery).append("')") .append("UPPER(exo:name) LIKE '").append(asteriskQuery).append("'))"); // if user isn't admin if (!isAdmin) { queryString.append(" and "); queryString.append("(exo:isApproved='true' and exo:isHidden='false' and exo:isActiveByTopic='true')"); queryString.append(" and (exo:userPrivate='exoUserPri'").append(" or exo:userPrivate='").append(userId) .append("')"); } else { queryString.append(" and "); queryString.append("(exo:userPrivate='exoUserPri'").append(" or exo:userPrivate='").append(userId) .append("')"); } if ("date".equalsIgnoreCase(sort)) { queryString.append(" order by ").append(EXO_CREATED_DATE); } else if ("title".equalsIgnoreCase(sort) || Utils.isEmpty(sort)) { queryString.append(" order by ").append(EXO_NAME); } if ("relevancy".equalsIgnoreCase(sort)) { queryString.append(" order by ").append(JCR_SCORE); } queryString.append(" ").append(order); return queryString; } private boolean hasPermssionViewerPost(Node postNode, List<String> listOfUser) throws Exception { Node topicNode = postNode.getParent(); PropertyReader reader = new PropertyReader(topicNode); List<String> listOfCanviewrs = reader.list(EXO_CAN_VIEW, new ArrayList<String>()); if (listOfUser != null && listOfUser.size() > 0 && reader.string(EXO_OWNER, "").equals(listOfUser.get(0))) { return true; } return listOfCanviewrs.isEmpty() || Utils.hasPermission(listOfCanviewrs, listOfUser); } private ForumSearchResult setPropertyUnifiedSearch(Node nodeObj, String originQuery) throws Exception { ForumSearchResult forumSearch = setPropertyForForumSearch(nodeObj, Utils.POST); //forumSearch.setExcerpt(originQuery); //forumSearch.setRelevancy(1); try { // forumSearch.setRelevancy(1); originQuery = CommonUtils.removeSpecialCharacterForUnifiedSearch(originQuery); // String excerpt = highlightText(nodeObj.getProperty(EXO_MESSAGE).getString(), originQuery); // if excerpt does not contain highlight text and text query, using field // name to display excerpt if (!HIGHLIHT_PATTERN.matcher(excerpt).find() && excerpt.toLowerCase().indexOf(originQuery) < 0) { excerpt = highlightText(nodeObj.getProperty(EXO_NAME).getString(), originQuery); } forumSearch.setExcerpt(excerpt); } catch (Exception e) { e.printStackTrace(); } return forumSearch; } private String highlightText(String message, String termToHighlight) { for (String term : termToHighlight.split(" ")) { message = message.replace(term, "<strong>" + term + "</strong>"); } return message; } private List<ForumSearchResult> removeItemInList(List<ForumSearchResult> listSearchEvent, List<String> forumCanView, List<String> categoryCanView) { List<ForumSearchResult> tempListSearchEvent = new ArrayList<ForumSearchResult>(); String path = null; String[] strs; for (ForumSearchResult forumSearch : listSearchEvent) { path = forumSearch.getPath(); if (!path.contains(Utils.TOPIC)) {// search category or forum tempListSearchEvent.add(forumSearch); continue; } strs = path.split("/"); if (categoryCanView.contains(strs[5]) || forumCanView.contains(strs[6])) { tempListSearchEvent.add(forumSearch); } } return tempListSearchEvent; } public List<String> getForumUserCanView(List<String> listOfUser, List<String> listForumIds) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); List<String> listForum = new ArrayList<String>(); Node categoryHome = getCategoryHome(sProvider); QueryManager qm = categoryHome.getSession().getWorkspace().getQueryManager(); StringBuilder queryString = new StringBuilder(); if (listOfUser == null || listOfUser.isEmpty()) { listOfUser = new ArrayList<String>(); listOfUser.add(UserProfile.USER_GUEST); } // select all forum // queryString.append(JCR_ROOT).append(categoryHome.getPath()).append("//element(*,").append(EXO_FORUM).append(")[") // .append("(").append(Utils.buildXpathHasProperty(EXO_VIEWER)) // .append(" or ").append(Utils.buildXpathByUserInfo(EXO_VIEWER, listOfUser)).append(")") // .append(" or (").append(Utils.buildXpathByUserInfo(EXO_MODERATORS, listOfUser)).append(")") // .append("]"); // Query query = qm.createQuery(queryString.toString(), Query.XPATH); queryString.append("SELECT * FROM ").append(EXO_FORUM).append(" WHERE (") .append(Utils.buildSQLHasProperty(EXO_VIEWER)).append(" OR ") .append(Utils.buildSQLByUserInfo(EXO_VIEWER, listOfUser)).append(")").append(" OR (") .append(Utils.buildSQLByUserInfo(EXO_MODERATORS, listOfUser)).append(")"); Query query = qm.createQuery(queryString.toString(), Query.SQL); QueryResult result = query.execute(); NodeIterator iter = result.getNodes(); Node forumNode = null; String forumId = null; while (iter.hasNext()) { forumNode = iter.nextNode(); forumId = forumNode.getName(); if (listForumIds != null && !listForumIds.isEmpty()) { if (listForumIds.contains(forumId)) { listForum.add(forumId); } } else { listForum.add(forumId); } } // If user isn't admin , get all membership of user if (!isAdminRole(listOfUser.get(0))) { // Get all category & forum that user can view Map<String, List<String>> mapList = getCategoryViewer(categoryHome, listOfUser, new ArrayList<String>(), listForum, EXO_USER_PRIVATE); listForum = mapList.get(Utils.FORUM); } return listForum; } public List<ForumSearchResult> getAdvancedSearch(ForumEventQuery eventQuery, List<String> listCateIds, List<String> listForumIds) { SessionProvider sProvider = CommonUtils.createSystemProvider(); List<ForumSearchResult> listSearchEvent = new ArrayList<ForumSearchResult>(); try { Node categoryHome = getCategoryHome(sProvider); QueryManager qm = categoryHome.getSession().getWorkspace().getQueryManager(); String path = eventQuery.getPath(); if (path == null || path.length() <= 0) { path = categoryHome.getPath(); } eventQuery.setPath(path); String type = eventQuery.getType(); String queryString = null; List<String> listOfUser = eventQuery.getListOfUser(); if (eventQuery.getUserPermission() > 0) { Map<String, List<String>> mapList = getCategoryViewer(categoryHome, listOfUser, listCateIds, listForumIds, EXO_USER_PRIVATE); listCateIds = mapList.get(Utils.CATEGORY); listForumIds = mapList.get(Utils.FORUM); } if (type.equals(Utils.CATEGORY)) { queryString = eventQuery.getPathQuery(listCateIds); } else { queryString = eventQuery.getPathQuery(listForumIds); } Query query = qm.createQuery(queryString, Query.XPATH); QueryResult result = query.execute(); NodeIterator iter = result.getNodes(); while (iter.hasNext()) { Node nodeObj = iter.nextNode(); listSearchEvent.add(setPropertyForForumSearch(nodeObj, type)); } // Note: Query Attachment in post. if ((type.equals(Utils.POST) || type.equals(Utils.TOPIC)) && !Utils.isEmpty(eventQuery.getKeyValue())) { boolean isAdmin = false; if (eventQuery.getUserPermission() == 0) isAdmin = true; listSearchEvent.addAll(getSearchByAttachment(categoryHome, eventQuery.getPath(), eventQuery.getKeyValue(), listForumIds, eventQuery.getListOfUser(), isAdmin, type)); } if (eventQuery.getUserPermission() > 0) { List<String> categoryCanView = new ArrayList<String>(); List<String> forumCanView = new ArrayList<String>(); Map<String, List<String>> mapList = getCategoryViewer(categoryHome, listOfUser, listCateIds, listForumIds, "@exo:viewer"); categoryCanView = mapList.get(Utils.CATEGORY); forumCanView.addAll(mapList.get(Utils.FORUM)); forumCanView.addAll(getCachedDataStorage().getForumUserCanView(listOfUser, listForumIds)); if (categoryCanView.size() > 0 || forumCanView.size() > 0) listSearchEvent = removeItemInList(listSearchEvent, forumCanView, categoryCanView); } } catch (Exception e) { if (LOG.isDebugEnabled()) { LOG.debug("Failed to do advanced search", e); } } return listSearchEvent; } private List<ForumSearchResult> getSearchByAttachment(Node categoryHome, String path, String key, List<String> listForumIds, List<String> listOfUser, boolean isAdmin, String type) throws Exception { List<ForumSearchResult> listSearchEvent = new ArrayList<ForumSearchResult>(); try { QueryManager qm = categoryHome.getSession().getWorkspace().getQueryManager(); StringBuilder strQuery = new StringBuilder(); strQuery.append(JCR_ROOT).append(path).append("//element(*,nt:resource) ["); strQuery.append("(jcr:contains(., '").append(key).append("*'))]"); Query query = qm.createQuery(strQuery.toString(), Query.XPATH); QueryResult result = query.execute(); NodeIterator iter = result.getNodes(); boolean isAdd = true; String type_ = type; while (iter.hasNext()) { Node nodeObj = iter.nextNode().getParent().getParent(); if (nodeObj.isNodeType(EXO_POST)) { if (type == null || type.length() == 0) { if (nodeObj.getProperty(EXO_IS_FIRST_POST).getBoolean()) { type_ = Utils.TOPIC; } else { type_ = Utils.POST; } } else { if (nodeObj.getProperty(EXO_IS_FIRST_POST).getBoolean()) { if (!type.equals(Utils.TOPIC)) continue; } else { if (type.equals(Utils.TOPIC)) continue; } } // check scoping, private by category. if (!isAdmin && !listForumIds.isEmpty()) { String path_ = nodeObj.getPath(); path_ = path_.substring(path_.lastIndexOf(Utils.FORUM), path_.lastIndexOf("/" + Utils.TOPIC)); if (listForumIds.contains(path_)) isAdd = true; else isAdd = false; } if (isAdd) { // check post private List<String> list = Utils.valuesToList(nodeObj.getProperty(EXO_USER_PRIVATE).getValues()); if (!list.get(0).equals(EXO_USER_PRI) && !Utils.isListContentItemList(listOfUser, list)) isAdd = false; // not is admin if (isAdd && !isAdmin) { // not is moderator list = Utils.valuesToList( nodeObj.getParent().getParent().getProperty(EXO_MODERATORS).getValues()); if (!Utils.hasPermission(listOfUser, list)) { // can view by topic list = Utils .valuesToList(nodeObj.getParent().getProperty(EXO_CAN_VIEW).getValues()); if (list != null && list.size() > 0 && !Utils.isEmpty(list.get(0))) { if (!Utils.hasPermission(listOfUser, list)) isAdd = false; } if (isAdd) { // check by post Post post = getPost(nodeObj); if (!post.getIsActiveByTopic() || !post.getIsApproved() || post.getIsHidden() || post.getIsWaiting()) isAdd = false; } } } } if (isAdd) { if (type_.equals(Utils.TOPIC)) nodeObj = nodeObj.getParent(); listSearchEvent.add(setPropertyForForumSearch(nodeObj, type_)); } } } } catch (Exception e) { LOG.error("Search by attachment has failed", e); } return listSearchEvent; } private ForumSearchResult setPropertyForForumSearch(Node nodeObj, String type) throws Exception { ForumSearchResult forumSearch = new ForumSearchResult(); forumSearch.setId(nodeObj.getName()); forumSearch.setPath(nodeObj.getPath()); PropertyReader reader = new PropertyReader(nodeObj); forumSearch.setName(reader.string(EXO_NAME, "")); forumSearch.setType(type); forumSearch.setCreatedDate(reader.date(EXO_CREATED_DATE)); if (type.equals(Utils.FORUM)) { if (reader.bool(EXO_IS_CLOSED)) forumSearch.setIcon("ForumCloseIcon"); else if (reader.bool(EXO_IS_LOCK)) forumSearch.setIcon("ForumLockedIcon"); else forumSearch.setIcon("ForumNormalIcon"); } else if (type.equals(Utils.TOPIC)) { forumSearch.setContent(reader.string(EXO_DESCRIPTION)); if (reader.bool(EXO_IS_CLOSED)) forumSearch.setIcon("HotThreadNoNewClosePost"); else if (reader.bool(EXO_IS_LOCK)) forumSearch.setIcon("HotThreadNoNewLockPost"); else forumSearch.setIcon("HotThreadNoNewPost"); } else if (type.equals(Utils.CATEGORY)) { forumSearch.setIcon("CategoryIcon"); } else { forumSearch.setIcon(reader.string(EXO_ICON, "")); forumSearch.setContent(reader.string(EXO_MESSAGE)); } return forumSearch; } /** * * @param categoryHome * @param listOfUser * all group and membership user belong to * @param listCateIds * all category visible * @param listForumIds * all forum visible * @return * @throws Exception */ private Map<String, List<String>> getCategoryViewer(Node categoryHome, List<String> listOfUser, List<String> listCateIds, List<String> listForumIds, String property) throws Exception { Map<String, List<String>> mapList = new HashMap<String, List<String>>(); if (listOfUser == null || listOfUser.isEmpty()) { listOfUser = new ArrayList<String>(); listOfUser.add(UserProfile.USER_GUEST); } QueryManager qm = categoryHome.getSession().getWorkspace().getQueryManager(); StringBuilder queryString = new StringBuilder(); queryString.append(JCR_ROOT).append(categoryHome.getPath()).append("/element(*,").append(EXO_FORUM_CATEGORY) .append(")[") .append("(").append(Utils.buildXpathHasProperty(property)).append(" or ") .append(Utils.buildXpathByUserInfo(property, listOfUser)).append(")").append(" or (") .append(Utils.buildXpathByUserInfo(EXO_MODERATORS, listOfUser)).append(")").append("]"); Query query = qm.createQuery(queryString.toString(), Query.XPATH); QueryResult result = query.execute(); NodeIterator iter = result.getNodes(); NodeIterator iter1 = null; // Check if the result is not all if (iter.getSize() > 0 && iter.getSize() != categoryHome.getNodes().getSize()) { String forumId, cateId; List<String> listForumId = new ArrayList<String>(); List<String> listCateId = new ArrayList<String>(); // Check all category in result.If it can visible then add it to list. while (iter.hasNext()) { Node catNode = iter.nextNode(); cateId = catNode.getName(); if (listCateIds != null && !listCateIds.isEmpty()) { if (listCateIds.contains(cateId)) { listCateId.add(cateId); } } else { listCateId.add(cateId); } // Check all forum in result if it visible then get it iter1 = catNode.getNodes(); while (iter1.hasNext()) { Node forumNode = iter1.nextNode(); if (forumNode.isNodeType(EXO_FORUM)) { forumId = forumNode.getName(); if (listForumIds != null && !listForumIds.isEmpty()) { if (listForumIds.contains(forumId)) { listForumId.add(forumId); } } else { listForumId.add(forumId); } } } } mapList.put(Utils.FORUM, listForumId); mapList.put(Utils.CATEGORY, listCateId); } else if (iter.getSize() == 0) { if (!property.equals(EXO_VIEWER)) { listForumIds = new ArrayList<String>(); listForumIds.add("forumId"); mapList.put(Utils.FORUM, listForumIds); listCateIds = new ArrayList<String>(); listCateIds.add("cateId"); mapList.put(Utils.CATEGORY, listCateIds); } else { mapList.put(Utils.FORUM, new ArrayList<String>()); mapList.put(Utils.CATEGORY, new ArrayList<String>()); } } else { mapList.put(Utils.FORUM, listForumIds); mapList.put(Utils.CATEGORY, listCateIds); } return mapList; } public void addWatch(int watchType, String path, List<String> values, String currentUser) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); try { Node categoryHome = getCategoryHome(sProvider); if (watchType == -1) { QueryManager qm = categoryHome.getSession().getWorkspace().getQueryManager(); StringBuffer queryString = new StringBuffer(); queryString.append(JCR_ROOT).append(categoryHome.getPath()).append("//*[@exo:id='").append(path) .append("']"); Query query = qm.createQuery(queryString.toString(), Query.XPATH); QueryResult result = query.execute(); NodeIterator iterator = result.getNodes(); path = iterator.nextNode().getPath(); } if (path.indexOf(categoryHome.getName()) < 0) path = categoryHome.getPath() + "/" + path; Node watchingNode = (Node) categoryHome.getSession().getItem(path); // add watching for node List<String> listUsers = new ArrayList<String>(); if (watchingNode.isNodeType(EXO_FORUM_WATCHING)) { if (watchType == 1) {// send email when had changed on category List<String> listEmail = new ArrayList<String>(); if (watchingNode.hasProperty(EXO_EMAIL_WATCHING)) listEmail.addAll( Utils.valuesToList(watchingNode.getProperty(EXO_EMAIL_WATCHING).getValues())); if (watchingNode.hasProperty(EXO_USER_WATCHING)) listUsers.addAll( Utils.valuesToList(watchingNode.getProperty(EXO_USER_WATCHING).getValues())); for (String str : values) { if (listEmail.contains(str)) continue; listEmail.add(0, str); listUsers.add(0, currentUser); } watchingNode.setProperty(EXO_EMAIL_WATCHING, Utils.getStringsInList(listEmail)); watchingNode.setProperty(EXO_USER_WATCHING, Utils.getStringsInList(listUsers)); } else { watchingNode.setProperty(EXO_RSS_WATCHING, getValueProperty(watchingNode, EXO_RSS_WATCHING, currentUser)); } } else { watchingNode.addMixin(EXO_FORUM_WATCHING); if (watchType == 1) { // send email when had changed on category for (int i = 0; i < values.size(); i++) { listUsers.add(currentUser); } watchingNode.setProperty(EXO_EMAIL_WATCHING, Utils.getStringsInList(values)); watchingNode.setProperty(EXO_USER_WATCHING, Utils.getStringsInList(listUsers)); } else { // add RSS watching watchingNode.setProperty(EXO_RSS_WATCHING, new String[] { currentUser }); } } if (watchingNode.isNew()) { watchingNode.getSession().save(); } else { watchingNode.save(); } // if(watchType == -1)addForumSubscription(sProvider, currentUser, watchingNode.getName()); } catch (Exception e) { LOG.error("Can not add Watch for user: " + currentUser, e); } } public void removeWatch(int watchType, String path, String values) throws Exception { if (Utils.isEmpty(values)) return; Node watchingNode = null; SessionProvider sProvider = CommonUtils.createSystemProvider(); Node categoryHome = getCategoryHome(sProvider); String string = categoryHome.getPath(); if (path.indexOf(categoryHome.getName()) < 0) path = string + "/" + path; try { watchingNode = (Node) categoryHome.getSession().getItem(path); List<String> newValues = new ArrayList<String>(); List<String> listNewUsers = new ArrayList<String>(); List<String> userRSS = new ArrayList<String>(); // add watching for node if (watchingNode.isNodeType(EXO_FORUM_WATCHING)) { if (watchType == 1) { String[] emails = new String[] {}; String[] listOldUsers = new String[] {}; String[] listRss = new String[] {}; PropertyReader reader = new PropertyReader(watchingNode); emails = reader.strings(EXO_EMAIL_WATCHING, new String[] {}); listOldUsers = reader.strings(EXO_USER_WATCHING, new String[] {}); listRss = reader.strings(EXO_RSS_WATCHING, new String[] {}); int n = (listRss.length > listOldUsers.length) ? listRss.length : listOldUsers.length; for (int i = 0; i < n; i++) { if (listOldUsers.length > i && !values.contains("/" + emails[i])) { newValues.add(emails[i]); listNewUsers.add(listOldUsers[i]); } if (listRss.length > i && !values.contains(listRss[i] + "/")) userRSS.add(listRss[i]); } watchingNode.setProperty(EXO_EMAIL_WATCHING, Utils.getStringsInList(newValues)); watchingNode.setProperty(EXO_USER_WATCHING, Utils.getStringsInList(listNewUsers)); watchingNode.setProperty(EXO_RSS_WATCHING, Utils.getStringsInList(userRSS)); if (watchingNode.isNew()) { watchingNode.getSession().save(); } else { watchingNode.save(); } } } } catch (Exception e) { LOG.error("Failed to remove watch.", e); } } public void updateEmailWatch(List<String> listNodeId, String newEmailAdd, String userId) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); try { Node parentNode = getForumHomeNode(sProvider); QueryManager qm = parentNode.getSession().getWorkspace().getQueryManager(); StringBuffer queryString = new StringBuffer(JCR_ROOT).append(parentNode.getPath()) .append("//element(*,exo:forumWatching)[("); for (int i = 0; i < listNodeId.size(); i++) { if (i > 0) queryString.append(" or "); queryString.append("@exo:id='").append(listNodeId.get(i)).append("'"); } queryString.append(")]"); Query query = qm.createQuery(queryString.toString(), Query.XPATH); QueryResult result = query.execute(); NodeIterator iterator = result.getNodes(); Node watchingNode = null; List<String> listEmail = null; List<String> listUsers = null; while (iterator.hasNext()) { watchingNode = iterator.nextNode(); PropertyReader reader = new PropertyReader(watchingNode); listEmail = reader.list(EXO_EMAIL_WATCHING, new ArrayList<String>()); listUsers = reader.list(EXO_USER_WATCHING, new ArrayList<String>()); if (listUsers.contains(userId)) { for (int i = 0; i < listUsers.size(); i++) { if (listUsers.get(i).equals(userId)) { listEmail.set(i, newEmailAdd); } } } else { listUsers.add(userId); listEmail.add(newEmailAdd); } watchingNode.setProperty(EXO_EMAIL_WATCHING, listEmail.toArray(new String[listEmail.size()])); watchingNode.setProperty(EXO_USER_WATCHING, listUsers.toArray(new String[listUsers.size()])); watchingNode.save(); } } catch (Exception e) { LOG.error("Failed to update email watch.", e); } } public List<Watch> getWatchByUser(String userId) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); List<Watch> listWatches = new ArrayList<Watch>(); try { Node categoryHome = getCategoryHome(sProvider); StringBuffer rootPath = new StringBuffer(categoryHome.getPath()); QueryManager qm = categoryHome.getSession().getWorkspace().getQueryManager(); StringBuffer queryString = new StringBuffer(); queryString.append(JCR_ROOT).append(rootPath.toString()).append("//element(*,") .append(EXO_FORUM_WATCHING).append(")[(@").append(EXO_USER_WATCHING).append("='").append(userId) .append("') or (@").append(EXO_RSS_WATCHING).append("='").append(userId).append("')]"); Query query = qm.createQuery(queryString.toString(), Query.XPATH); QueryResult result = query.execute(); NodeIterator iterator = result.getNodes(); Watch watch; Node node; List<String> users; List<String> RSSUsers; String emails[]; String path; StringBuffer pathName = new StringBuffer(); String typeNode; PropertyReader reader; while (iterator.hasNext()) { node = iterator.nextNode(); reader = new PropertyReader(node); users = reader.list(EXO_USER_WATCHING, new ArrayList<String>()); emails = reader.strings(EXO_EMAIL_WATCHING, new String[] {}); RSSUsers = reader.list(EXO_RSS_WATCHING, new ArrayList<String>()); rootPath.setLength(0); rootPath.append(categoryHome.getPath()); path = node.getPath(); pathName.setLength(0); if (node.isNodeType(Utils.TYPE_CATEGORY)) { typeNode = Utils.TYPE_CATEGORY; } else if (node.isNodeType(Utils.TYPE_FORUM)) { typeNode = Utils.TYPE_FORUM; } else { typeNode = Utils.TYPE_TOPIC; } for (String str : (path.replace(rootPath.toString() + "/", "")).split("/")) { rootPath.append("/"); rootPath.append(str); if (!Utils.isEmpty(pathName.toString())) { pathName.append(" > "); } pathName.append(((Node) categoryHome.getSession().getItem(rootPath.toString())) .getProperty(EXO_NAME).getString()); } watch = new Watch(); watch.setId(node.getName()); watch.setNodePath(path); watch.setUserId(userId); watch.setPath(pathName.toString()); watch.setTypeNode(typeNode); if (users.contains(userId)) { watch.setEmail(emails[users.indexOf(userId)]); watch.setIsAddWatchByEmail(true); } else { watch.setIsAddWatchByEmail(false); } watch.setIsAddWatchByRSS(RSSUsers.contains(userId)); listWatches.add(watch); } return listWatches; } catch (Exception e) { return listWatches; } } private void sendEmailNotification(List<String> addresses, Message message) throws Exception { pendingMessagesQueue.add(new SendMessageInfo(addresses, message)); } public Iterator<SendMessageInfo> getPendingMessages() throws Exception { Iterator<SendMessageInfo> pending = new ArrayList<SendMessageInfo>(pendingMessagesQueue).iterator(); pendingMessagesQueue.clear(); return pending; } public void updateForum(String path) throws Exception { if (path == null || path.length() <= 0 || path.equals("/" + dataLocator.getForumHomeLocation())) { path = dataLocator.getForumHomeLocation(); updateForum(path, true); } else { updateForum(path, false); } } private void updateForum(String path, boolean isReset) throws Exception { Map<String, Long> topicMap = new HashMap<String, Long>(); Map<String, Long> postMap = new HashMap<String, Long>(); if (path.indexOf("/") > 0) path = "/" + path; SessionProvider sProvider = CommonUtils.createSystemProvider(); try { Node forumStatisticNode = getStatisticHome(sProvider).getNode(Locations.FORUM_STATISTIC); QueryManager qm = forumStatisticNode.getSession().getWorkspace().getQueryManager(); Query query = qm.createQuery(JCR_ROOT + path + "//element(*,exo:topic)", Query.XPATH); QueryResult result = query.execute(); NodeIterator topicIter = result.getNodes(); query = qm.createQuery(JCR_ROOT + path + "//element(*,exo:post)", Query.XPATH); result = query.execute(); NodeIterator postIter = result.getNodes(); // Update Forum statistic if (isReset) { forumStatisticNode.setProperty(EXO_POST_COUNT, postIter.getSize()); forumStatisticNode.setProperty(EXO_TOPIC_COUNT, topicIter.getSize()); } else if (path.indexOf(Utils.FORUM) == path.lastIndexOf(Utils.FORUM)) { PropertyReader statisticReader = new PropertyReader(forumStatisticNode); forumStatisticNode.setProperty(EXO_POST_COUNT, statisticReader.l(EXO_POST_COUNT, 0) + postIter.getSize()); forumStatisticNode.setProperty(EXO_TOPIC_COUNT, statisticReader.l(EXO_TOPIC_COUNT, 0) + topicIter.getSize()); } forumStatisticNode.save(); // put post and topic to maps by user Node node; while (topicIter.hasNext()) { node = topicIter.nextNode(); String owner = node.getProperty(EXO_OWNER).getString(); if (topicMap.containsKey(owner)) { long l = topicMap.get(owner) + 1; topicMap.put(owner, l); } else { long l = 1; topicMap.put(owner, l); } } while (postIter.hasNext()) { node = postIter.nextNode(); String owner = node.getProperty(EXO_OWNER).getString(); if (postMap.containsKey(owner)) { long l = postMap.get(owner) + 1; postMap.put(owner, l); } else { long l = 1; postMap.put(owner, l); } } Node profileHome = getUserProfileHome(sProvider); Node profile; // update topic to user profile Iterator<Entry<String, Long>> it = topicMap.entrySet().iterator(); String userId; Calendar cal = getGreenwichMeanTime(); while (it.hasNext()) { userId = it.next().getKey(); if (userId.indexOf(Utils.DELETED) < 0) { if (profileHome.hasNode(userId)) { profile = profileHome.getNode(userId); } else { profile = profileHome.addNode(userId, EXO_FORUM_USER_PROFILE); profile.setProperty(EXO_USER_ID, userId); profile.setProperty(EXO_LAST_LOGIN_DATE, cal); profile.setProperty(EXO_JOINED_DATE, cal); profile.setProperty(EXO_LAST_POST_DATE, cal); } long l = (isReset) ? topicMap.get(userId) : profile.getProperty(EXO_TOTAL_TOPIC).getLong() + topicMap.get(userId); profile.setProperty(EXO_TOTAL_TOPIC, l); if (postMap.containsKey(userId)) { long t = (isReset) ? postMap.get(userId) : profile.getProperty(EXO_TOTAL_POST).getLong() + postMap.get(userId); profile.setProperty(EXO_TOTAL_POST, t); profile.setProperty(EXO_LAST_POST_DATE, cal); postMap.remove(userId); } } } // update post to user profile it = postMap.entrySet().iterator(); while (it.hasNext()) { userId = it.next().getKey(); if (userId.indexOf(Utils.DELETED) < 0) { if (profileHome.hasNode(userId)) { profile = profileHome.getNode(userId); } else { profile = profileHome.addNode(userId, EXO_FORUM_USER_PROFILE); profile.setProperty(EXO_USER_ID, userId); profile.setProperty(EXO_LAST_LOGIN_DATE, cal); profile.setProperty(EXO_JOINED_DATE, cal); } long t = (isReset) ? postMap.get(userId) : profile.getProperty(EXO_TOTAL_POST).getLong() + postMap.get(userId); profile.setProperty(EXO_TOTAL_POST, t); profile.setProperty(EXO_LAST_POST_DATE, cal); } } if (profileHome.isNew()) { profileHome.getSession().save(); } else { profileHome.save(); } int t = (profileHome.hasNode(Utils.USER_PROFILE_DELETED)) ? 1 : 0; forumStatisticNode.setProperty(EXO_MEMBERS_COUNT, profileHome.getNodes().getSize() - t); forumStatisticNode.save(); } catch (Exception e) { LOG.error("Failed to update forum", e); } } public SendMessageInfo getMessageInfo(String name) throws Exception { SendMessageInfo messageInfo = (SendMessageInfo) infoMap.get(name); infoMap.remove(name); return messageInfo; } private String getPath(String index, String path) throws Exception { int t = path.lastIndexOf(index); if (t > 0) { path = path.substring(t + 1); } return path; } public List<ForumSearchResult> getJobWattingForModerator(String[] paths) { SessionProvider sProvider = CommonUtils.createSystemProvider(); List<ForumSearchResult> list = new ArrayList<ForumSearchResult>(); try { Node categoryHome = getCategoryHome(sProvider); String string = categoryHome.getPath(); QueryManager qm = categoryHome.getSession().getWorkspace().getQueryManager(); StringBuilder builder = new StringBuilder(); int l = paths.length; if (l > 0) { builder.append(" and ("); for (int i = 0; i < l; i++) { if (i > 0) builder.append(" or "); String str = getPath(("/" + Utils.FORUM), paths[i]); builder.append("@exo:path='").append(str).append("'"); } builder.append(")"); } Query query; NodeIterator iter; QueryResult result; StringBuilder stringBuilder = new StringBuilder(JCR_ROOT).append(string).append("//element(*,") .append(EXO_TOPIC).append(")").append("[(@").append(EXO_IS_APPROVED).append("='false' or @") .append(EXO_IS_WAITING).append("='true')").append(builder) .append("] order by @exo:modifiedDate descending"); query = qm.createQuery(stringBuilder.toString(), Query.XPATH); result = query.execute(); iter = result.getNodes(); ForumSearchResult forumSearch; while (iter.hasNext()) { forumSearch = new ForumSearchResult(); Node node = iter.nextNode(); forumSearch.setId(node.getName()); forumSearch.setPath(node.getPath()); forumSearch.setType(Utils.TOPIC); forumSearch.setName(node.getProperty(EXO_NAME).getString()); forumSearch.setContent(node.getProperty(EXO_DESCRIPTION).getString()); forumSearch.setCreatedDate(node.getProperty(EXO_CREATED_DATE).getDate().getTime()); list.add(forumSearch); } stringBuilder = new StringBuilder(JCR_ROOT).append(string).append("//element(*,").append(EXO_POST) .append(")").append("[(@").append(EXO_IS_APPROVED).append("='false' or @").append(EXO_IS_HIDDEN) .append("='true' or @").append(EXO_IS_WAITING).append("='true')").append(builder) .append("] order by @exo:modifiedDate descending"); query = qm.createQuery(stringBuilder.toString(), Query.XPATH); result = query.execute(); iter = result.getNodes(); while (iter.hasNext()) { forumSearch = new ForumSearchResult(); Node node = iter.nextNode(); forumSearch.setId(node.getName()); forumSearch.setPath(node.getPath()); forumSearch.setType(Utils.POST); forumSearch.setName(node.getProperty(EXO_NAME).getString()); forumSearch.setContent(node.getProperty(EXO_MESSAGE).getString()); forumSearch.setCreatedDate(node.getProperty(EXO_CREATED_DATE).getDate().getTime()); list.add(forumSearch); } } catch (Exception e) { LOG.error("Failed to get waiting jobs for moderator", e); } return list; } public int getJobWattingForModeratorByUser(String userId) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); int job = 0; Node newProfileNode = getUserProfileHome(sProvider).getNode(userId); long t;// = 3 if (isAdminRole(userId)) { t = 0; } else { t = newProfileNode.getProperty(EXO_USER_ROLE).getLong(); } if (t < 2) { try { job = (int) newProfileNode.getProperty(EXO_JOB_WATTING_FOR_MODERATOR).getLong(); } catch (Exception e) { job = 0; } } return job; } private int getTotalJobWaitingForModerator(Session session, String userId) throws Exception { int totalJob = 0; try { Node newProfileNode = session.getRootNode().getNode(dataLocator.getUserProfilesLocation()) .getNode(userId); long t;// = 3; if (isAdminRole(userId)) { t = 0; } else { t = newProfileNode.getProperty(EXO_USER_ROLE).getLong(); } if (t < 2) { Node categoryHome = session.getRootNode().getNode(dataLocator.getForumCategoriesLocation()); String string = categoryHome.getPath(); QueryManager qm = categoryHome.getSession().getWorkspace().getQueryManager(); StringBuffer buffer = new StringBuffer(); if (t > 0) { String[] paths = Utils .valuesToArray(newProfileNode.getProperty(EXO_MODERATE_FORUMS).getValues()); int l = paths.length; if (l > 0) { buffer.append(" and ("); for (int i = 0; i < l; i++) { if (i > 0) buffer.append(" or "); String str = getPath(("/" + Utils.FORUM), paths[i]); buffer.append("@exo:path='").append(str).append("'"); } buffer.append(")"); } } StringBuffer stringBuffer = new StringBuffer(JCR_ROOT).append(string).append("//element(*,") .append(EXO_TOPIC).append(")").append("[(@").append(EXO_IS_APPROVED).append("='false' or @") .append(EXO_IS_WAITING).append("='true')").append(buffer).append("]"); Query query = qm.createQuery(stringBuffer.toString(), Query.XPATH); QueryResult result = query.execute(); NodeIterator iter = result.getNodes(); totalJob = (int) iter.getSize(); stringBuffer = new StringBuffer(JCR_ROOT).append(string).append("//element(*,").append(EXO_POST) .append(")").append("[(@").append(EXO_IS_APPROVED).append("='false' or @") .append(EXO_IS_HIDDEN).append("='true' or @").append(EXO_IS_WAITING).append("='true')") .append(buffer).append("]"); query = qm.createQuery(stringBuffer.toString(), Query.XPATH); result = query.execute(); iter = result.getNodes(); totalJob = totalJob + (int) iter.getSize(); newProfileNode.setProperty(EXO_JOB_WATTING_FOR_MODERATOR, totalJob); newProfileNode.save(); } } catch (Exception e) { LOG.error("Failed to get total job watting for moderator", e); } return totalJob; } private void getTotalJobWatting(SessionProvider sProvider, Set<String> userIds) { try { ContinuationService continuation = CommonUtils.getComponent(ContinuationService.class); if (continuation != null) { Set<String> set = new HashSet<String>( ForumServiceUtils.getUserPermission(userIds.toArray(new String[userIds.size()]))); set.addAll(getAllAdministrator(sProvider)); JsonGeneratorImpl generatorImpl = new JsonGeneratorImpl(); Category cat = new Category(); for (String userId : set) { if (Utils.isEmpty(userId) || userId.indexOf(CommonUtils.SLASH) > 0 || userId.indexOf(CommonUtils.COLON) > 0) continue; int job = getTotalJobWaitingForModerator(getForumHomeNode(sProvider).getSession(), userId); if (job >= 0) { cat.setCategoryName(String.valueOf(job)); JsonValue json = generatorImpl.createJsonObject(cat); continuation.sendMessage(userId, "/eXo/Application/Forum/messages", json, cat.toString()); } } } } catch (Exception e) { LOG.error("Failed to get total job waiting for moderator", e); } } public void sendNotificationMessage(ForumPrivateMessage message) { try { if (message != null) { ContinuationService continuation = CommonUtils.getComponent(ContinuationService.class); String[] sendTo = message.getSendTo().replaceAll(";", ",").split(","); String from = message.getFrom(); message.setFrom(getScreenName(from)); JsonGeneratorImpl generatorImpl = new JsonGeneratorImpl(); JsonValue json = generatorImpl.createJsonObject(message); for (int i = 0; i < sendTo.length; i++) { String to = sendTo[i].trim(); if (to.equals(from)) { continue; } continuation.sendMessage(to, "/eXo/Application/Forum/NotificationMessage", json, message.toString()); } } } catch (Exception e) { LOG.error("Failed to send notification message:" + e.getMessage()); } } public NodeIterator search(String queryString) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); try { QueryManager qm = getForumHomeNode(sProvider).getSession().getWorkspace().getQueryManager(); Query query = qm.createQuery(queryString, Query.XPATH); QueryResult result = query.execute(); return result.getNodes(); } catch (Exception e) { LOG.error("Failed to search", e); } return null; } public void evaluateActiveUsers(String strQuery) { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { String path = getUserProfileHome(sProvider).getPath(); StringBuilder stringBuilder = new StringBuilder(); if (strQuery == null || strQuery.length() == 0) { Calendar calendar = GregorianCalendar.getInstance(); calendar.setTimeInMillis(calendar.getTimeInMillis() - 864000000); stringBuilder.append(JCR_ROOT).append(path).append("//element(*,").append(EXO_FORUM_USER_PROFILE) .append(")[").append("@exo:lastPostDate >= xs:dateTime('").append(ISO8601.format(calendar)) .append("')]"); } else { stringBuilder.append(JCR_ROOT).append(path).append(strQuery); } QueryManager qm = getForumHomeNode(sProvider).getSession().getWorkspace().getQueryManager(); Query query = qm.createQuery(stringBuilder.toString(), Query.XPATH); QueryResult result = query.execute(); NodeIterator iter = result.getNodes(); Node statisticHome = getStatisticHome(sProvider); if (statisticHome.hasNode(Locations.FORUM_STATISTIC)) { statisticHome.getNode(Locations.FORUM_STATISTIC).setProperty(EXO_ACTIVE_USERS, iter.getSize()); statisticHome.save(); } else { ForumStatistic forumStatistic = new ForumStatistic(); forumStatistic.setActiveUsers(iter.getSize()); saveForumStatistic(forumStatistic); } } catch (Exception e) { LOG.error("Failed to evaluate active users", e); } finally { sProvider.close(); } } protected List<File> createCategoryFiles(List<String> objectIds, SessionProvider sessionProvider) throws Exception { List<File> listFiles = new ArrayList<File>(); ByteArrayOutputStream outputStream = null; Node categoryHome = getCategoryHome(sessionProvider); Node cateNode = null; for (String categoryId : objectIds) { try { cateNode = categoryHome.getNode(categoryId); outputStream = new ByteArrayOutputStream(); Calendar date = new GregorianCalendar(); categoryHome.getSession().exportSystemView(cateNode.getPath(), outputStream, false, false); listFiles.add(CommonUtils.getXMLFile(outputStream, "eXo Knowledge Suite - Forum", "Category", date.getTime(), cateNode.getName())); } finally { outputStream.close(); } } return listFiles; } protected List<File> createForumFiles(String categoryId, List<String> objectIds, SessionProvider sessionProvider) throws Exception { List<File> listFiles = new ArrayList<File>(); List<Forum> forums = getCachedDataStorage().getForums(new ForumFilter(categoryId, true)); for (Forum forum : forums) { if (objectIds.size() > 0 && !objectIds.contains(forum.getId())) continue; ByteArrayOutputStream outputStream = null; try { outputStream = new ByteArrayOutputStream(); Calendar calendar = GregorianCalendar.getInstance(); getCategoryHome(sessionProvider).getSession().exportSystemView(forum.getPath(), outputStream, false, false); listFiles.add(CommonUtils.getXMLFile(outputStream, "eXo Knowledge Suite - Forum", "Forum", calendar.getTime(), forum.getId())); } finally { outputStream.close(); } } return listFiles; } protected List<File> createFilesFromNode(Node node, String type) throws Exception { List<File> listFiles = new ArrayList<File>(); if (node != null) { ByteArrayOutputStream outputStream = null; try { outputStream = new ByteArrayOutputStream(); Calendar calendar = GregorianCalendar.getInstance(); node.getSession().exportSystemView(node.getPath(), outputStream, false, false); listFiles.add(CommonUtils.getXMLFile(outputStream, "eXo Knowledge Suite - Forum", type, calendar.getTime(), node.getName())); } finally { outputStream.close(); } } return listFiles; } protected List<File> createAllForumFiles(SessionProvider sessionProvider) throws Exception { List<File> listFiles = new ArrayList<File>(); /* * // Create Statistic file listFiles.addAll(createFilesFromNodeIter(categoryHome, null, getStatisticHome(sessionProvider), "")); */ // Create Administration file listFiles.addAll(createFilesFromNode(getAdminHome(sessionProvider), Locations.ADMINISTRATION_HOME)); // Create UserProfile files listFiles.addAll(createFilesFromNode(getUserProfileHome(sessionProvider), Locations.USER_PROFILE_HOME)); // create tag files listFiles.addAll(createFilesFromNode(getTagHome(sessionProvider), Locations.TAG_HOME)); // Create BBCode file listFiles.addAll(createFilesFromNode(getBBCodesHome(sessionProvider), Locations.BBCODE_HOME)); // Create BanIP file listFiles.addAll(createFilesFromNode(getBanIPHome(sessionProvider), Locations.BANIP_HOME)); // Create category home file listFiles.addAll(createFilesFromNode(getCategoryHome(sessionProvider), Locations.FORUM_CATEGORIES_HOME)); return listFiles; } public Object exportXML(String categoryId, String forumId, List<String> objectIds, String nodePath, ByteArrayOutputStream bos, boolean isExportAll) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); try { List<File> listFiles = new ArrayList<File>(); if (!isExportAll) { if (categoryId != null) { if (Utils.isEmpty(forumId)) { listFiles.addAll(createForumFiles(categoryId, objectIds, sProvider)); } else { Node categoryHome = getCategoryHome(sProvider); categoryHome.getSession().exportSystemView(nodePath, bos, false, false); return null; } } else { listFiles.addAll(createCategoryFiles(objectIds, sProvider)); } } else { listFiles.addAll(createAllForumFiles(sProvider)); } ZipOutputStream zipOutputStream = null; try { zipOutputStream = new ZipOutputStream(new FileOutputStream("exportCategory.zip")); int byteReads; byte[] buffer = new byte[4096]; // Create a buffer for copying FileInputStream inputStream = null; ZipEntry zipEntry = null; for (File f : listFiles) { inputStream = new FileInputStream(f); try { zipEntry = new ZipEntry(f.getPath()); zipOutputStream.putNextEntry(zipEntry); while ((byteReads = inputStream.read(buffer)) != -1) zipOutputStream.write(buffer, 0, byteReads); } finally { inputStream.close(); } } } finally { zipOutputStream.close(); } File file = new File("exportCategory.zip"); for (File f : listFiles) f.deleteOnExit(); return file; } catch (Exception e) { return null; } } public void importXML(String nodePath, ByteArrayInputStream bis, int typeImport) throws Exception { String nodeName = ""; byte[] bdata = new byte[bis.available()]; bis.read(bdata); DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder(); ByteArrayInputStream is = new ByteArrayInputStream(bdata); Document doc = docBuilder.parse(is); doc.getDocumentElement().normalize(); String typeNodeExport = ((org.w3c.dom.Node) doc.getFirstChild().getChildNodes().item(0).getChildNodes() .item(0)).getTextContent(); SessionProvider sProvider = CommonUtils.createSystemProvider(); List<String> patchNodeImport = new ArrayList<String>(); try { Node forumHome = getForumHomeNode(sProvider); is = new ByteArrayInputStream(bdata); if (!typeNodeExport.equals(EXO_FORUM_CATEGORY) && !typeNodeExport.equals(EXO_FORUM)) { // All nodes when import need reset childnode if (typeNodeExport.equals(EXO_CATEGORY_HOME)) { nodePath = getCategoryHome(sProvider).getPath(); Node categoryHome = getCategoryHome(sProvider); nodeName = "CategoryHome"; addDataFromXML(categoryHome, nodePath, sProvider, is, nodeName); } else if (typeNodeExport.equals(EXO_USER_PROFILE_HOME)) { Node userProfile = getUserProfileHome(sProvider); nodeName = "UserProfileHome"; nodePath = getUserProfileHome(sProvider).getPath(); addDataFromXML(userProfile, nodePath, sProvider, is, nodeName); } else if (typeNodeExport.equals(EXO_TAG_HOME)) { Node tagHome = getTagHome(sProvider); nodePath = getTagHome(sProvider).getPath(); nodeName = "TagHome"; addDataFromXML(tagHome, nodePath, sProvider, is, nodeName); } else if (typeNodeExport.equals(EXO_FORUM_BB_CODE_HOME)) { nodePath = dataLocator.getBBCodesLocation(); Node bbcodeNode = getBBCodesHome(sProvider); nodeName = "forumBBCode"; addDataFromXML(bbcodeNode, nodePath, sProvider, is, nodeName); } // Node import but don't need reset childnodes else if (typeNodeExport.equals(EXO_ADMINISTRATION_HOME)) { nodePath = getForumSystemHome(sProvider).getPath(); Node node = getAdminHome(sProvider); node.remove(); getForumSystemHome(sProvider).save(); typeImport = ImportUUIDBehavior.IMPORT_UUID_COLLISION_REPLACE_EXISTING; Session session = forumHome.getSession(); session.importXML(nodePath, is, typeImport); session.save(); } else if (typeNodeExport.equals(EXO_BAN_IP_HOME)) { nodePath = getForumSystemHome(sProvider).getPath(); Node node = getBanIPHome(sProvider); node.remove(); getForumSystemHome(sProvider).save(); typeImport = ImportUUIDBehavior.IMPORT_UUID_COLLISION_REPLACE_EXISTING; Session session = forumHome.getSession(); session.importXML(nodePath, is, typeImport); session.save(); } else { throw new RuntimeException("unknown type of node to export :" + typeNodeExport); } } else { if (typeNodeExport.equals(EXO_FORUM_CATEGORY)) { // Check if import forum but the data import have structure of a category --> Error if (nodePath.split("/").length == 6) { throw new ConstraintViolationException(); } nodePath = getCategoryHome(sProvider).getPath(); } Session session = forumHome.getSession(); NodeIterator iter = ((Node) session.getItem(nodePath)).getNodes(); while (iter.hasNext()) { patchNodeImport.add(iter.nextNode().getName()); } session.importXML(nodePath, is, typeImport); session.save(); NodeIterator newIter = ((Node) session.getItem(nodePath)).getNodes(); while (newIter.hasNext()) { Node node = newIter.nextNode(); if (patchNodeImport.contains(node.getName())) patchNodeImport.remove(node.getName()); else patchNodeImport.add(node.getName()); } } // update forum statistic and profile of owner post. if (typeNodeExport.equals(EXO_FORUM_CATEGORY) || typeNodeExport.equals(EXO_FORUM)) { for (String string : patchNodeImport) { updateForum(nodePath + "/" + string, false); } } else if (typeNodeExport.equals(EXO_CATEGORY_HOME)) { updateForum(null); } } finally { is.close(); } } private void addDataFromXML(Node sourceNode, String nodePath, SessionProvider sessionProvider, InputStream is, String nodeName) throws Exception { Node forumHomeNode = getForumHomeNode(sessionProvider); Session session = forumHomeNode.getSession(); Node tempNode = forumHomeNode.getParent().addNode("DataTemp"); // Add child node of DataTemp session.importXML(tempNode.getPath(), is, ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW); session.save(); // Node store data from XML file. Node importNode = tempNode.getNode(nodeName); try { copyFullNodes(sourceNode, importNode, session); } finally { tempNode.remove(); forumHomeNode.getParent().save(); } } private void copyFullNodes(Node sourceNode, Node importNode, Session session) throws Exception { // Check if importNode have different child than sourceNode then add it. NodeIterator sourceIter = sourceNode.getNodes(); NodeIterator importIter = importNode.getNodes(); Node srcTemp = null; Node importTemp = null; boolean flag = false; while (importIter.hasNext()) { flag = true; importTemp = importIter.nextNode(); while (sourceIter.hasNext()) { srcTemp = sourceIter.nextNode(); if (importTemp.getName().equals(srcTemp.getName())) { copyFullNodes(srcTemp, importTemp, session); flag = false; break; } } if (flag) { String path = sourceNode.getPath() + "/" + importTemp.getName(); try { session.getWorkspace().copy(importTemp.getPath(), path); } catch (Exception e) { if (LOG.isDebugEnabled()) { LOG.debug(path + " or " + importTemp.getPath() + " does not exist: " + e.getMessage() + "\n" + e.getCause()); } } } } } public void updateTopicAccess(String userId, String topicId) { if (updatingRead.containsKey(userId)) { updatingRead.get(userId).add(topicId); } else { List<String> value = new ArrayList<String>(); value.add(topicId); updatingRead.put(userId, value); } } public void writeReads() { // Map<String, List<String>> map = updatingRead; updatingRead = new ConcurrentHashMap<String, List<String>>(); // SessionProvider sysSession = CommonUtils.createSystemProvider(); for (Map.Entry<String, List<String>> entry : map.entrySet()) { try { if (!getUserProfileHome(sysSession).hasNode(entry.getKey())) { return; } // Node profile = getUserProfileHome(sysSession).getNode(entry.getKey()); List<String> values = new PropertyReader(profile).list(EXO_READ_TOPIC, Collections.EMPTY_LIST); // for (String topicId : entry.getValue()) { // int i = 0; boolean isUpdated = false; for (String vl : values) { if (vl.indexOf(topicId) == 0) { values.set(i, topicId + ":" + getGreenwichMeanTime().getTimeInMillis()); isUpdated = true; break; } i++; } // if (!isUpdated) { values.add(topicId + ":" + getGreenwichMeanTime().getTimeInMillis()); } profile.setProperty(EXO_READ_TOPIC, values.toArray(new String[values.size()])); profile.save(); } } catch (Exception e) { logDebug(String.format("Failed to update user %s acess for topic %s", entry.getKey(), "bar"), e); } } } public void updateForumAccess(String userId, String forumId) { SessionProvider sysSession = CommonUtils.createSystemProvider(); try { Node profile = getUserProfileHome(sysSession).getNode(userId); List<String> values = new ArrayList<String>(); if (profile.hasProperty(EXO_READ_FORUM)) { values = Utils.valuesToList(profile.getProperty(EXO_READ_FORUM).getValues()); } int i = 0; boolean isUpdated = false; for (String vl : values) { if (vl.indexOf(forumId) == 0) { values.set(i, forumId + ":" + getGreenwichMeanTime().getTimeInMillis()); isUpdated = true; break; } i++; } if (!isUpdated) { values.add(forumId + ":" + getGreenwichMeanTime().getTimeInMillis()); } if (values.size() == 2 && Utils.isEmpty(values.get(0))) values.remove(0); profile.setProperty(EXO_READ_FORUM, values.toArray(new String[values.size()])); profile.save(); } catch (Exception e) { LOG.warn(String.format("Failed to update user %s acess for forum %s", userId, forumId)); } } public List<String> getBookmarks(String userName) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); Node profile = getUserProfileHome(sProvider).getNode(userName); if (profile.hasProperty(EXO_BOOKMARK)) { return Utils.valuesToList(profile.getProperty(EXO_BOOKMARK).getValues()); } return new ArrayList<String>(); } public List<String> getBanList() throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); try { Node banNode = getForumBanNode(sProvider); if (banNode.hasProperty(EXO_IPS)) return Utils.valuesToList(banNode.getProperty(EXO_IPS).getValues()); } catch (Exception e) { if (LOG.isDebugEnabled()) { LOG.debug("Failed to get ban list", e); } } return new ArrayList<String>(); } public boolean addBanIP(String ip) throws Exception { List<String> ips = getBanList(); if (ips.contains(ip)) return false; ips.add(ip); SessionProvider sProvider = CommonUtils.createSystemProvider(); try { Node banNode = getForumBanNode(sProvider); banNode.setProperty(EXO_IPS, ips.toArray(new String[ips.size()])); if (banNode.isNew()) { banNode.getSession().save(); } else { banNode.save(); } return true; } catch (Exception e) { LOG.error("Failed to add ban ip: " + ip, e); } return false; } public void removeBan(String ip) throws Exception { List<String> ips = getBanList(); if (ips.contains(ip)) { ips.remove(ip); SessionProvider sProvider = CommonUtils.createSystemProvider(); try { Node banNode = getForumBanNode(sProvider); banNode.setProperty(EXO_IPS, Utils.getStringsInList(ips)); banNode.save(); } catch (Exception e) { LOG.error("Failed to remove ban, ip: " + ip, e); } } } public List<String> getForumBanList(String forumId) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); List<String> list = new ArrayList<String>(); try { if (forumId.indexOf(".") > 0) forumId = StringUtils.replace(forumId, ".", "/"); Node forumNode = getCategoryHome(sProvider).getNode(forumId); if (forumNode.hasProperty(EXO_BAN_I_PS)) list.addAll(Utils.valuesToList(forumNode.getProperty(EXO_BAN_I_PS).getValues())); } catch (Exception e) { if (LOG.isDebugEnabled()) { LOG.debug("Failed to get forum ban list.", e); } } return list; } public boolean addBanIPForum(String ip, String forumId) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); List<String> ips = new ArrayList<String>(); try { Node forumNode = getCategoryHome(sProvider).getNode(forumId); if (forumNode.hasProperty(EXO_BAN_I_PS)) ips.addAll(Utils.valuesToList(forumNode.getProperty(EXO_BAN_I_PS).getValues())); if (ips.contains(ip)) return false; ips.add(ip); forumNode.setProperty(EXO_BAN_I_PS, Utils.getStringsInList(ips)); if (forumNode.isNew()) { forumNode.getSession().save(); } else { forumNode.save(); } return true; } catch (Exception e) { LOG.error("Failed to add ban ip forum.", e); } return false; } public void removeBanIPForum(String ip, String forumId) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); List<String> ips = new ArrayList<String>(); try { Node forumNode = getCategoryHome(sProvider).getNode(forumId); if (forumNode.hasProperty(EXO_BAN_I_PS)) ips.addAll(Utils.valuesToList(forumNode.getProperty(EXO_BAN_I_PS).getValues())); if (ips.contains(ip)) { ips.remove(ip); forumNode.setProperty(EXO_BAN_I_PS, Utils.getStringsInList(ips)); if (forumNode.isNew()) { forumNode.getSession().save(); } else { forumNode.save(); } } } catch (Exception e) { LOG.error("Failed to remove ban IP from forum", e); } } private List<String> getAllAdministrator(SessionProvider sProvider) throws Exception { QueryManager qm = getForumHomeNode(sProvider).getSession().getWorkspace().getQueryManager(); StringBuilder pathQuery = new StringBuilder(); pathQuery.append(JCR_ROOT).append(getUserProfileHome(sProvider).getPath()).append("//element(*,") .append(EXO_FORUM_USER_PROFILE).append(")[@exo:userRole=0]"); Query query = qm.createQuery(pathQuery.toString(), Query.XPATH); QueryResult result = query.execute(); NodeIterator iter = result.getNodes(); List<String> list = new ArrayList<String>(); while (iter.hasNext()) { Node userNode = iter.nextNode(); list.add(userNode.getName()); } return list; } public void updateStatisticCounts(long topicCount, long postCount) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { Node forumStatisticNode = getForumStatisticsNode(sProvider); PropertyReader reader = new PropertyReader(forumStatisticNode); if (topicCount != 0) { long count = reader.l(EXO_TOPIC_COUNT); if (count < 0) count = 0; forumStatisticNode.setProperty(EXO_TOPIC_COUNT, count + topicCount); } if (postCount != 0) { long count = reader.l(EXO_POST_COUNT); if (count < 0) count = 0; forumStatisticNode.setProperty(EXO_POST_COUNT, count + postCount); } forumStatisticNode.save(); } catch (Exception e) { if (LOG.isDebugEnabled()) { LOG.debug("Failed to update statistic counts", e); } } finally { sProvider.close(); } } private PruneSetting getPruneSetting(Node prunNode) throws Exception { PruneSetting pruneSetting = new PruneSetting(); pruneSetting.setId(prunNode.getName()); pruneSetting.setForumPath(prunNode.getParent().getPath()); pruneSetting.setActive(prunNode.getProperty(EXO_IS_ACTIVE).getBoolean()); pruneSetting.setCategoryName(prunNode.getParent().getParent().getProperty(EXO_NAME).getString()); pruneSetting.setForumName(prunNode.getParent().getProperty(EXO_NAME).getString()); pruneSetting.setInActiveDay(prunNode.getProperty(EXO_IN_ACTIVE_DAY).getLong()); pruneSetting.setPeriodTime(prunNode.getProperty(EXO_PERIOD_TIME).getLong()); if (prunNode.hasProperty(EXO_LAST_RUN_DATE)) pruneSetting.setLastRunDate(prunNode.getProperty(EXO_LAST_RUN_DATE).getDate().getTime()); return pruneSetting; } public PruneSetting getPruneSetting(String forumPath) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); PruneSetting pruneSetting = new PruneSetting(); try { Node forumNode = (Node) getCategoryHome(sProvider).getSession().getItem(forumPath); pruneSetting = getPruneSetting(forumNode.getNode(Utils.PRUNESETTING)); } catch (Exception e) { if (LOG.isDebugEnabled()) { LOG.debug("Failed to get Prune Settings: " + e.getMessage() + "\n" + e.getCause()); } } return pruneSetting; } public List<PruneSetting> getAllPruneSetting() throws Exception { List<PruneSetting> prunList = new ArrayList<PruneSetting>(); SessionProvider sProvider = CommonUtils.createSystemProvider(); NodeIterator iter = getNodeIteratorAutoPruneSetting(sProvider, false); while (iter.hasNext()) { Node prunNode = iter.nextNode(); prunList.add(getPruneSetting(prunNode)); } return prunList; } public void savePruneSetting(PruneSetting pruneSetting) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); try { String path = pruneSetting.getForumPath(); Node forumNode = (Node) getForumHomeNode(sProvider).getSession().getItem(path); Node pruneNode; try { pruneNode = forumNode.getNode(Utils.PRUNESETTING); } catch (Exception e) { pruneNode = forumNode.addNode(Utils.PRUNESETTING, EXO_PRUNE_SETTING); pruneNode.setProperty(EXO_ID, pruneSetting.getId()); } pruneNode.setProperty(EXO_IN_ACTIVE_DAY, pruneSetting.getInActiveDay()); pruneNode.setProperty(EXO_PERIOD_TIME, pruneSetting.getPeriodTime()); pruneNode.setProperty(EXO_IS_ACTIVE, pruneSetting.isActive()); if (pruneSetting.getLastRunDate() != null) { Calendar calendar = Calendar.getInstance(); calendar.setTime(pruneSetting.getLastRunDate()); pruneNode.setProperty(EXO_LAST_RUN_DATE, calendar); } if (pruneNode.isNew()) forumNode.getSession().save(); else forumNode.save(); try { addOrRemoveSchedule(pruneSetting); } catch (Exception e) { if (LOG.isDebugEnabled()) { LOG.debug("Failed to add or remove prune jobs", e); } } } catch (Exception e) { LOG.error("Failed to save prune setting.", e); } } private void addOrRemoveSchedule(PruneSetting pSetting) throws Exception { Calendar cal = new GregorianCalendar(); PeriodInfo periodInfo = new PeriodInfo(cal.getTime(), null, -1, (pSetting.getPeriodTime() * 86400000)); // pSetting.getPeriodTime() return value JobInfo info = new JobInfo(pSetting.getId(), KNOWLEDGE_SUITE_FORUM_JOBS, AutoPruneJob.class); ExoContainer container = ExoContainerContext.getCurrentContainer(); JobSchedulerService schedulerService = (JobSchedulerService) container .getComponentInstanceOfType(JobSchedulerService.class); schedulerService.removeJob(info); if (pSetting.isActive()) { info = new JobInfo(pSetting.getId(), KNOWLEDGE_SUITE_FORUM_JOBS, AutoPruneJob.class); info.setDescription(pSetting.getForumPath()); RepositoryService repositoryService = (RepositoryService) ExoContainerContext.getCurrentContainer() .getComponentInstanceOfType(RepositoryService.class); String repoName = repositoryService.getCurrentRepository().getConfiguration().getName(); JobDataMap jdatamap = new JobDataMap(); jdatamap.put(Utils.CACHE_REPO_NAME, repoName); schedulerService.addPeriodJob(info, periodInfo, jdatamap); if (LOG.isInfoEnabled()) { LOG.info("\n\nActivated " + info.getJobName()); } } } public void runPrune(String forumPath) throws Exception { runPrune(getPruneSetting(forumPath)); } public void runPrune(PruneSetting pSetting) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); try { Node forumNode = (Node) getForumHomeNode(sProvider).getSession().getItem(pSetting.getForumPath()); NodeIterator iter = getIteratorPrune(sProvider, pSetting); while (iter.hasNext()) { Node topic = iter.nextNode(); topic.setProperty(EXO_IS_ACTIVE, false); topic.save(); try { Node forumN = topic.getParent(); if (new PropertyReader(forumN).string(EXO_LAST_TOPIC_PATH, "").indexOf(topic.getName()) >= 0) { queryLastTopic(sProvider, forumN.getPath()); } } catch (Exception e) { LOG.warn("Failed to save new value last post date in forum", e); } } // update last run for prune setting Node setting = forumNode.getNode(pSetting.getId()); setting.setProperty(EXO_LAST_RUN_DATE, getGreenwichMeanTime()); forumNode.save(); } catch (Exception e) { LOG.error("Failed to run prune", e); } } private NodeIterator getIteratorPrune(SessionProvider sProvider, PruneSetting pSetting) throws Exception { Node forumHome = getForumHomeNode(sProvider); Node forumNode = (Node) forumHome.getSession().getItem(pSetting.getForumPath()); Calendar newDate = getGreenwichMeanTime(); newDate.setTimeInMillis(newDate.getTimeInMillis() - pSetting.getInActiveDay() * 86400000); QueryManager qm = forumHome.getSession().getWorkspace().getQueryManager(); StringBuffer stringBuffer = new StringBuffer(); stringBuffer.append(JCR_ROOT).append(forumNode.getPath()).append("//element(*,").append(EXO_TOPIC) .append(")[ @").append(EXO_IS_ACTIVE).append("='true' and @").append(EXO_LAST_POST_DATE) .append(" <= xs:dateTime('").append(ISO8601.format(newDate)).append("')]"); Query query = qm.createQuery(stringBuffer.toString(), Query.XPATH); QueryResult result = query.execute(); return result.getNodes(); } public long checkPrune(PruneSetting pSetting) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); try { return getIteratorPrune(sProvider, pSetting).getSize(); } catch (Exception e) { if (LOG.isDebugEnabled()) { LOG.debug("Failed to check prune", e); } } return 0; } public InputStream createForumRss(String objectId, String link) throws Exception { List<SyndEntry> entries = new ArrayList<SyndEntry>(); SessionProvider sProvider = CommonUtils.createSystemProvider(); try { Node node_ = null; if (objectId.indexOf(Utils.CATEGORY) == 0) { node_ = getNodeById(sProvider, objectId, Utils.CATEGORY); entries.addAll(categoryUpdated(node_)); } else if (objectId.indexOf(Utils.FORUM) == 0) { node_ = getNodeById(sProvider, objectId, Utils.FORUM); entries.addAll(forumUpdated(node_)); } else { node_ = getNodeById(sProvider, objectId, Utils.TOPIC); String link_ = node_.getProperty(EXO_LINK).getString(); link = Utils.isEmpty(link_) ? link : link_; entries.addAll(topicUpdated(node_)); } SyndFeed feed = createNewFeed(node_, link); feed.setEntries(entries); SyndFeedOutput output = new SyndFeedOutput(); String s = output.outputString(feed); s = StringUtils.replace(s, "&", "&"); s = s.replaceAll("<", "<").replaceAll(">", ">"); s = StringUtils.replace(s, "ST[CDATA[", "<![CDATA["); s = StringUtils.replace(s, "END]]", "]]>"); return new ByteArrayInputStream(s.getBytes()); } catch (Exception e) { if (LOG.isDebugEnabled()) { LOG.debug("Failed to create forum rss", e); } } return null; } private List<SyndEntry> categoryUpdated(Node cateNode) throws Exception { List<SyndEntry> entries = new ArrayList<SyndEntry>(); NodeIterator iterator = cateNode.getNodes(); while (iterator.hasNext()) { Node node = iterator.nextNode(); if (node.isNodeType(EXO_FORUM) && !node.getProperty(EXO_IS_CLOSED).getBoolean()) { entries.addAll(forumUpdated(node)); } } return entries; } private List<SyndEntry> forumUpdated(Node forumNode) throws Exception { List<SyndEntry> entries = new ArrayList<SyndEntry>(); try { QueryManager qm = forumNode.getSession().getWorkspace().getQueryManager(); StringBuilder queryString = new StringBuilder(JCR_ROOT).append(forumNode.getPath()).append( "//element(*,exo:topic)[@exo:isWaiting='false' and @exo:isActive='true' and @exo:isClosed='false' and (not(@exo:canView) or @exo:canView='' or @exo:canView=' ')]") .append(" order by @exo:isSticky descending, @exo:lastPostDate descending"); Query query = qm.createQuery(queryString.toString(), Query.XPATH); QueryResult result = query.execute(); NodeIterator iter = result.getNodes(); while (iter.hasNext()) { entries.addAll(topicUpdated(iter.nextNode())); } } catch (Exception e) { if (LOG.isDebugEnabled()) { LOG.debug("Failed to update syndEntry by forum.", e); } } return entries; } private List<SyndEntry> topicUpdated(Node topicNode) { List<SyndEntry> entries = new ArrayList<SyndEntry>(); try { Node forumNode = topicNode.getParent(); Node categoryNode = forumNode.getParent(); boolean categoryHasRestrictedAudience = (hasProperty(categoryNode, EXO_VIEWER)); boolean forumHasRestrictedAudience = (hasProperty(forumNode, EXO_VIEWER)); String topicName = topicNode.getName(); if (categoryHasRestrictedAudience || forumHasRestrictedAudience) { if (LOG.isDebugEnabled()) { LOG.debug("Post" + topicName + " was not added to feed because category or forum has restricted audience"); } return null; } // update posts in topic QueryManager qm = topicNode.getSession().getWorkspace().getQueryManager(); StringBuffer stringBuffer = new StringBuffer(JCR_ROOT).append(topicNode.getPath()) .append("//element(*,").append(EXO_POST).append(")") .append(Utils.getPathQuery("true", "false", "false", EXO_USER_PRI)) .append(" order by @exo:createdDate ascending"); Query query = qm.createQuery(stringBuffer.toString(), Query.XPATH); QueryResult result = query.execute(); NodeIterator iter = result.getNodes(); Node postNode = null; while (iter.hasNext()) { postNode = iter.nextNode(); try { entries.add(postUpdated(postNode)); } catch (Exception e) { if (LOG.isDebugEnabled()) { LOG.debug("Failed to generate feed for post " + postNode.getPath(), e); } } } } catch (Exception e) { if (LOG.isDebugEnabled()) { LOG.debug("Failed to update sundEntry by topic.", e); } } return entries; } private SyndEntry postUpdated(Node postNode) throws Exception { Node topicNode = postNode.getParent(); String postName = postNode.getName(); PropertyReader post = new PropertyReader(postNode); boolean notApproved = !post.bool(EXO_IS_APPROVED); boolean isPrivatePost = !post.list(EXO_USER_PRIVATE, new ArrayList<String>()).contains(EXO_USER_PRI); boolean topicHasLimitedViewers = hasProperty(topicNode, EXO_CAN_VIEW); if ((notApproved) || isPrivatePost || topicHasLimitedViewers) { logDebug("Post" + postName + " was not added to feed because it is private or topic has restricted audience or it is waiting for approval"); return null; } Node forumNode = topicNode.getParent(); Node categoryNode = forumNode.getParent(); boolean categoryHasRestrictedAudience = (hasProperty(categoryNode, EXO_VIEWER)); boolean forumHasRestrictedAudience = (hasProperty(forumNode, EXO_VIEWER)); if (categoryHasRestrictedAudience || forumHasRestrictedAudience) { logDebug( "Post" + postName + " was not added to feed because category or forum has restricted audience"); return null; } List<String> listContent = new ArrayList<String>(); String message = post.string(EXO_MESSAGE); listContent.add(message); SyndContent description = new SyndContentImpl(); description.setType("text/html"); description.setValue(getTitleRSS(message)); final String title = post.string(EXO_NAME); final Date created = post.date(EXO_CREATED_DATE); final String owner = post.string(EXO_OWNER); final String linkItem = post.string(EXO_LINK); SyndEntry entry = createNewEntry(postName, title, linkItem, listContent, description, created, owner); return entry; } private SyndFeed createNewFeed(Node node, String link) throws Exception { PropertyReader reader = new PropertyReader(node); String desc = reader.string(EXO_DESCRIPTION, " "); SyndFeed feed = new SyndFeedImpl(); feed.setFeedType("rss_2.0"); feed.setTitle(getTitleRSS(reader.string(EXO_NAME))); feed.setPublishedDate(reader.date(EXO_CREATED_DATE, new Date())); feed.setLink(link); feed.setDescription(getTitleRSS(desc)); feed.setEncoding("UTF-8"); return feed; } private SyndEntry createNewEntry(String uri, String title, String link, List<String> listContent, SyndContent description, Date pubDate, String author) { SyndEntry entry = new SyndEntryImpl(); entry.setUri(uri); entry.setTitle(getTitleRSS(title)); entry.setLink(link); entry.setContributors(listContent); entry.setDescription(description); entry.setPublishedDate(pubDate); entry.setAuthor(author); return entry; } private String getTitleRSS(String title) { title = CommonUtils.decodeSpecialCharToHTMLnumber(TransformHTML.getPlainText(title)); return new StringBuilder("ST[CDATA[") .append(StringEscapeUtils.unescapeHtml(TransformHTML.getTitleInHTMLCode(title, null))) .append("END]]").toString(); } public InputStream createUserRss(String userId, String link) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); List<SyndEntry> entries = new ArrayList<SyndEntry>(); try { Node subscriptionNode = getUserProfileHome(sProvider) .getNode(userId + "/" + Utils.FORUM_SUBSCRIOTION + userId); PropertyReader reader = new PropertyReader(subscriptionNode); List<String> cateIds = reader.list(EXO_CATEGORY_IDS, new ArrayList<String>()); Node node; for (String id : cateIds) { node = getNodeById(sProvider, id, Utils.CATEGORY); if (node != null) { entries.addAll(categoryUpdated(node)); } } List<String> forumIds = reader.list(EXO_FORUM_IDS, new ArrayList<String>()); for (String id : forumIds) { node = getNodeById(sProvider, id, Utils.FORUM); if (node != null && !cateIds.contains(node.getParent().getName())) { entries.addAll(forumUpdated(node)); } } List<String> topicIds = reader.list(EXO_TOPIC_IDS, new ArrayList<String>()); for (String id : topicIds) { node = getNodeById(sProvider, id, Utils.TOPIC); if (node != null && !forumIds.contains(node.getParent().getName())) { entries.addAll(topicUpdated(node)); } } } catch (PathNotFoundException e) { LOG.info(String.format("User %s doesn't subscribe anything.", userId)); } catch (RepositoryException e) { logDebug("Can not create feed data for user: " + userId, e); } try { SyndFeed feed = new SyndFeedImpl(); feed.setFeedType("rss_2.0"); feed.setTitle("Forum subscriptions for " + userId); feed.setPublishedDate(new Date()); feed.setLink(link); feed.setDescription(" "); feed.setEncoding("UTF-8"); feed.setEntries(entries); SyndFeedOutput output = new SyndFeedOutput(); String s = output.outputString(feed); s = StringUtils.replace(s, "&", "&"); s = s.replaceAll("<", "<").replaceAll(">", ">"); s = StringUtils.replace(s, "ST[CDATA[", "<![CDATA["); s = StringUtils.replace(s, "END]]", "]]>"); return new ByteArrayInputStream(s.getBytes()); } catch (FeedException e) { LOG.error("Can not create RSS for user: " + userId, e); return new ByteArrayInputStream(("Can not create RSS for user: " + userId + "<br/>" + e).getBytes()); } } /** * {@inheritDoc} */ public boolean populateUserProfile(User user, UserProfile profileTemplate, boolean isNew) throws Exception { boolean added = false; sessionManager.openSession(); try { Node profile = null; Node profileHome = getUserProfileHome(); final String userName = user.getUserName(); if (profileHome.hasNode(userName)) { if (isNew) { LOG.warn("Request to add user " + userName + " was ignored because it already exists."); } profile = profileHome.getNode(userName); added = false; } else { profile = profileHome.addNode(userName, EXO_FORUM_USER_PROFILE); added = true; } Calendar cal = getGreenwichMeanTime(); profile.setProperty(EXO_USER_ID, userName); profile.setProperty(EXO_LAST_LOGIN_DATE, cal); profile.setProperty(EXO_EMAIL, user.getEmail()); profile.setProperty(EXO_FULL_NAME, user.getDisplayName()); cal.setTime(user.getCreatedDate()); profile.setProperty(EXO_JOINED_DATE, cal); if (isAdminRole(userName)) { profile.setProperty(EXO_USER_TITLE, "Administrator"); profile.setProperty(EXO_USER_ROLE, UserProfile.ADMIN); // } else { profile.setProperty(EXO_USER_ROLE, UserProfile.USER); // } if (profileTemplate != null) { profile.setProperty(EXO_TIME_ZONE, profileTemplate.getTimeZone()); profile.setProperty(EXO_SHORT_DATEFORMAT, profileTemplate.getShortDateFormat()); profile.setProperty(EXO_LONG_DATEFORMAT, profileTemplate.getLongDateFormat()); profile.setProperty(EXO_TIME_FORMAT, profileTemplate.getTimeFormat()); profile.setProperty(EXO_MAX_TOPIC, profileTemplate.getMaxTopicInPage()); profile.setProperty(EXO_MAX_POST, profileTemplate.getMaxPostInPage()); } if (profileHome.isNew()) { profileHome.getSession().save(); } else { profileHome.save(); } return added; } catch (Exception e) { LOG.error("Error while populating user profile: " + e.getMessage()); throw e; } finally { sessionManager.closeSession(true); } } public String getLatestUser() throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); try { Node profileHome = getUserProfileHome(sProvider); if (profileHome.hasNodes()) { QueryManager qm = profileHome.getSession().getWorkspace().getQueryManager(); StringBuilder pathQuery = new StringBuilder(); pathQuery.append("/jcr:root").append(profileHome.getPath()) .append("/element(*,exo:forumUserProfile) order by @exo:joinedDate descending"); Query query = qm.createQuery(pathQuery.toString(), Query.XPATH); QueryResult result = query.execute(); NodeIterator iter = result.getNodes(); if (iter.getSize() > 0) { Node node = iter.nextNode(); return node.getName(); } } } catch (Exception e) { if (LOG.isDebugEnabled()) { LOG.debug("Failed to get latest user login.", e); } } return ""; } public void updateLastLoginDate(String userId) throws Exception { sessionManager.openSession(); try { Node userProfileHome = getUserProfileHome(); if (userProfileHome.hasNode(userId)) { userProfileHome.getNode(userId).setProperty(EXO_LAST_LOGIN_DATE, getGreenwichMeanTime()); userProfileHome.save(); } } finally { sessionManager.closeSession(); } } //get all categories for user can view. private List<String> getCategoriesUserCanview(Node categoryHome, List<String> listOfUser) throws Exception { /* * cateids = list query cateids = listinput -> public for property (null for view) * cateids = {cateid} for private --> can not view * cateids = new array for view --> can not view */ List<String> categoryCanView = new ArrayList<String>(); Map<String, List<String>> mapPrivate = getCategoryViewer(categoryHome, listOfUser, new ArrayList<String>(), new ArrayList<String>(), EXO_USER_PRIVATE); // all categoryid public for private user List<String> categoryIds = mapPrivate.get(Utils.CATEGORY); // all categoryid public for Viewer Map<String, List<String>> mapList = getCategoryViewer(categoryHome, listOfUser, null, new ArrayList<String>(), EXO_VIEWER); List<String> categoryView = mapList.get(Utils.CATEGORY); // user not in restricted audience or can not viewer if (categoryIds.contains("cateId") || (categoryView != null && categoryView.isEmpty())) { return null; } if (categoryIds.isEmpty()) { categoryCanView.addAll((categoryView == null ? new ArrayList<String>() : categoryView)); } else { for (String string : categoryIds) { if (categoryView == null || categoryView.contains(string)) { categoryCanView.add(string); } } } return categoryCanView; } // check permission for everyone can view the post private boolean postIsPublicByParent(Node postNode) throws Exception { Node node = postNode.getParent(); // checking from the topic parent. Check by canView if (!new PropertyReader(node).list(EXO_CAN_VIEW, Collections.EMPTY_LIST).isEmpty()) return false; // checking from the forum parent. Check by canView if (!new PropertyReader(node = node.getParent()).list(EXO_VIEWER, Collections.EMPTY_LIST).isEmpty()) return false; // checking from the category parent. Check by canView if (!new PropertyReader(node = node.getParent()).list(EXO_VIEWER, Collections.EMPTY_LIST).isEmpty()) return false; // Check by restricted audience if (!new PropertyReader(node).list(EXO_USER_PRIVATE, Collections.EMPTY_LIST).isEmpty()) return false; return true; } // check permssion user can view private boolean checkPermssionCanView(Node postNode, boolean isUserLogin, List<String> categoryCanView, List<String> forumCanView) throws Exception { if (isUserLogin) { String[] path = postNode.getPath().split("/"); return (categoryCanView.isEmpty() || categoryCanView.contains(path[path.length - 4])) && (forumCanView.isEmpty() || forumCanView.contains(path[path.length - 3])); } else { return postIsPublicByParent(postNode); } } // get post by query. private List<Post> getPostByQuery(Node categoryHome, QueryImpl impl, int number, String userName, boolean isAdmin) throws Exception { List<Post> list = new ArrayList<Post>(); List<String> categoryCanView = new ArrayList<String>(); List<String> forumCanView = new ArrayList<String>(); boolean isUserLogin = false; if (!Utils.isEmpty(userName) && !UserProfile.USER_GUEST.equals(userName)) { isUserLogin = true; if (!isAdmin) { List<String> listOfUser = UserHelper.getAllGroupAndMembershipOfUser(null); categoryCanView = getCategoriesUserCanview(categoryHome, listOfUser); if (categoryCanView == null) { return list; } forumCanView .addAll(getCachedDataStorage().getForumUserCanView(listOfUser, new ArrayList<String>())); } } int offset = 0, count = 0, limit; QueryResult qr; NodeIterator iter; Node node; while (count < number) { impl.setOffset(offset); limit = number + offset; impl.setLimit(limit); qr = impl.execute(); iter = qr.getNodes(); if (iter.getSize() <= 0) { return list; } while (iter.hasNext()) { node = iter.nextNode(); if (isAdmin || checkPermssionCanView(node, isUserLogin, categoryCanView, forumCanView)) { list.add(getPost(node)); count++; if (count == number) { break; } } } offset = limit; } return list; } // the function use to get recent post for user. public List<Post> getRecentPostsForUser(String userName, int number) throws Exception { if (number <= 0) { return new ArrayList<Post>(); } if (Utils.isEmpty(userName) || UserProfile.USER_GUEST.equals(userName)) { return getNewPosts(number); } List<Post> list = new ArrayList<Post>(); SessionProvider sProvider = CommonUtils.createSystemProvider(); try { boolean isAdmin = isAdminRole(userName); if (!isAdmin) { isAdmin = (new PropertyReader(getUserProfileNode(getUserProfileHome(sProvider), userName)) .l(EXO_USER_ROLE, 3) == 0) ? true : false; } Node categoryHome = getCategoryHome(sProvider); StringBuffer stringBuffer = new StringBuffer(); stringBuffer.append(JCR_ROOT).append(categoryHome.getPath()).append("//element(*,").append(EXO_POST) .append(")[("); if (!isAdmin) stringBuffer.append("(@").append(EXO_IS_APPROVED).append("='true') and (@").append(EXO_IS_HIDDEN) .append("='false') and (@").append(EXO_IS_WAITING).append("='false') and (@") .append(EXO_IS_ACTIVE_BY_TOPIC).append("='true') and "); stringBuffer.append("(@").append(EXO_USER_PRIVATE).append("='exoUserPri' or @").append(EXO_USER_PRIVATE) .append("='").append(userName).append("'))]").append(" order by @").append(EXO_CREATED_DATE) .append(" descending"); QueryManager qm = categoryHome.getSession().getWorkspace().getQueryManager(); Query query = qm.createQuery(stringBuffer.toString(), Query.XPATH); // get posts if (query instanceof QueryImpl) { list = getPostByQuery(categoryHome, (QueryImpl) query, number, userName, isAdmin); } } catch (Exception e) { if (LOG.isDebugEnabled()) { LOG.debug("Failed to get new post.", e); } } return list; } //the function use to get recent post for everyone. public List<Post> getNewPosts(int number) throws Exception { List<Post> list = new ArrayList<Post>(); SessionProvider sProvider = CommonUtils.createSystemProvider(); try { Node categoryHome = getCategoryHome(sProvider); QueryManager qm = categoryHome.getSession().getWorkspace().getQueryManager(); StringBuffer stringBuffer = new StringBuffer(); stringBuffer.append(JCR_ROOT).append(categoryHome.getPath()).append("//element(*,").append(EXO_POST) .append(") [((@").append(EXO_IS_APPROVED).append("='true') and (@").append(EXO_IS_HIDDEN) .append("='false') and (@").append(EXO_IS_WAITING).append("='false') and (@") .append(EXO_IS_ACTIVE_BY_TOPIC).append("='true') and (@").append(EXO_USER_PRIVATE) .append("='exoUserPri'))] order by @").append(EXO_CREATED_DATE).append(" descending"); Query query = qm.createQuery(stringBuffer.toString(), Query.XPATH); // get posts if (query instanceof QueryImpl) { list = getPostByQuery(categoryHome, (QueryImpl) query, number, "", false); } } catch (Exception e) { if (LOG.isDebugEnabled()) { LOG.debug("Failed to get new post.", e); } } return list; } public boolean deleteUserProfile(String userId) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); try { Node profileHome = getUserProfileHome(sProvider); Node profileDeleted; Node profile = profileHome.getNode(userId); Session session = profileHome.getSession(); profile.setProperty(EXO_USER_ROLE, UserProfile.USER_DELETED); profile.setProperty(EXO_USER_TITLE, UserProfile.USER_REMOVED); profile.setProperty(EXO_MODERATE_CATEGORY, new String[] {}); profile.setProperty(EXO_MODERATE_FORUMS, new String[] {}); profile.save(); StringBuilder id = new StringBuilder(userId).append(Utils.DELETED); try { profileDeleted = profileHome.getNode(Utils.USER_PROFILE_DELETED); long index = profileDeleted.getNodes().getSize(); if (index > 0) { id.append(index); } } catch (Exception e) { profileDeleted = profileHome.addNode(Utils.USER_PROFILE_DELETED, EXO_USER_DELETED); session.save(); deletedUserCalculateListener(profileDeleted); } session.getWorkspace().move(profile.getPath(), new StringBuilder(profileDeleted.getPath()).append(CommonUtils.SLASH).append(id).toString()); try { Node avatarHome = session.getRootNode().getNode(dataLocator.getAvatarsLocation()); if (avatarHome.hasNode(userId)) { avatarHome.getNode(userId).remove(); } } catch (Exception e) { LOG.info("User deleted has not avatar !!!"); } session.save(); } catch (PathNotFoundException e) { return false; } return true; } public void calculateDeletedUser(String userName) throws Exception { SessionProvider sProvider = CommonUtils.createSystemProvider(); String tempUserName = userName; userName = tempUserName.substring(0, tempUserName.indexOf(Utils.DELETED)); try { Node categoryHome = getCategoryHome(sProvider); QueryManager qm = categoryHome.getSession().getWorkspace().getQueryManager(); String[] strs = new String[] { EXO_OWNER, EXO_MODIFIED_BY, EXO_LAST_POST_BY, EXO_USER_PRIVATE, EXO_MODERATORS, EXO_CREATE_TOPIC_ROLE, EXO_POSTER, EXO_VIEWER, EXO_CAN_POST, EXO_CAN_VIEW, EXO_USER_WATCHING, EXO_RSS_WATCHING }; StringBuilder builder = new StringBuilder(); for (int i = 0; i < strs.length; i++) { if (i > 0) builder.append(" or "); builder.append("(@").append(strs[i]).append("='").append(userName).append("')"); } StringBuilder pathQuery = new StringBuilder(); pathQuery.append(JCR_ROOT).append(categoryHome.getPath()).append("//*[").append(builder).append("]"); Query query = qm.createQuery(pathQuery.toString(), Query.XPATH); QueryResult result = query.execute(); NodeIterator iter = result.getNodes(); List<String> list; while (iter.hasNext()) { Node node = iter.nextNode(); if (node.isNodeType(EXO_FORUM_CATEGORY) || node.isNodeType(EXO_FORUM) || node.isNodeType(EXO_TOPIC) || node.isNodeType(EXO_POST)) { for (int i = 0; i < strs.length; i++) { if (i < 3) { if (new PropertyReader(node).string(strs[i], "").equals(userName)) { node.setProperty(strs[i], tempUserName); } } else { PropertyReader reader = new PropertyReader(node); list = reader.list(strs[i], new ArrayList<String>()); if (list.contains(userName)) { if (strs[i].equals(EXO_USER_WATCHING)) { try { int t = list.indexOf(userName); List<String> list2 = reader.list(EXO_EMAIL_WATCHING, new ArrayList<String>()); list2.remove(t); node.setProperty(EXO_EMAIL_WATCHING, list2.toArray(new String[list2.size()])); } catch (Exception e) { LOG.debug("Failed to get email watching by user deleted.", e); } } list.remove(userName); node.setProperty(strs[i], list.toArray(new String[list.size()])); } } } } } if (categoryHome.isNew()) { categoryHome.getSession().save(); } else { categoryHome.save(); } } catch (Exception e) { LOG.error("Failed to calculate deleting user.", e); } } public void calculateDeletedGroup(String groupId, String groupName) throws Exception { try { // remove forum in space Node forumSpaceNode = getNodeById(CommonUtils.createSystemProvider(), Utils.FORUM_SPACE_ID_PREFIX + groupName, Utils.FORUM); if (forumSpaceNode != null) { LOG.info("\nINFO: Delete forum in space: " + forumSpaceNode.getName()); removeForum(forumSpaceNode.getParent().getName(), forumSpaceNode.getName()); } // remove group storage in categories/forums/topics SessionProvider sProvider = CommonUtils.createSystemProvider(); Node categoryHome = getCategoryHome(sProvider); QueryManager qm = categoryHome.getSession().getWorkspace().getQueryManager(); String[] strs = new String[] { EXO_USER_PRIVATE, EXO_CREATE_TOPIC_ROLE, EXO_POSTER, EXO_VIEWER, EXO_CAN_POST, EXO_CAN_VIEW, EXO_MODERATORS }; StringBuilder pathQuery = new StringBuilder(JCR_ROOT).append(categoryHome.getPath()).append("//*["); for (int i = 0; i < strs.length; i++) { if (i > 0) { pathQuery.append(" or "); } pathQuery.append("(@").append(strs[i]).append("='").append(groupId).append("') or (jcr:contains(@") .append(strs[i]).append(", '").append(groupId).append("'))"); } pathQuery.append("]"); Query query = qm.createQuery(pathQuery.toString(), Query.XPATH); QueryResult result = query.execute(); NodeIterator iter = result.getNodes(); List<String> list; PropertyReader reader; boolean isSave; while (iter.hasNext()) { Node node = iter.nextNode(); if (node.isNodeType(EXO_FORUM_CATEGORY) || node.isNodeType(EXO_FORUM) || node.isNodeType(EXO_TOPIC)) { isSave = false; reader = new PropertyReader(node); for (int i = 0; i < strs.length; i++) { list = reader.list(strs[i], new ArrayList<String>()); if (!list.isEmpty()) { int oldSize = list.size(); list = containsGroup(list, groupId); if (oldSize > list.size() || list.get(0).equals(CommonUtils.EMPTY_STR)) { if (strs[i].equals(EXO_MODERATORS)) { // calculate moderator for users node.setProperty(EXO_TEMP_MODERATORS, reader.strings(EXO_MODERATORS, new String[] { CommonUtils.EMPTY_STR })); node.save(); } node.setProperty(strs[i], list.toArray(new String[list.size()])); isSave = true; } } } if (isSave) { node.save(); } } } } catch (Exception e) { logDebug("Failed to calculate deleted Group.", e); } } public static List<String> containsGroup(List<String> list, String groupId) { List<String> ls = new ArrayList<String>(); for (String string : list) { if (string.indexOf(groupId) >= 0) { continue; } ls.add(string); } if (ls.isEmpty()) { ls.add(CommonUtils.EMPTY_STR); } return ls; } public List<InitializeForumPlugin> getDefaultPlugins() { return defaultPlugins; } public List<RoleRulesPlugin> getRulesPlugins() { return rulesPlugins; } public Map<String, String> getServerConfig() { return serverConfig; } public KSDataLocation getDataLocation() { return dataLocator; } public void setDataLocator(KSDataLocation dataLocator) { this.dataLocator = dataLocator; sessionManager = dataLocator.getSessionManager(); repository = dataLocator.getRepository(); workspace = dataLocator.getWorkspace(); LOG.info("JCR Data Storage for forum initialized to " + dataLocator); } private static void logDebug(String message, Throwable e) { if (LOG.isDebugEnabled()) { if (e != null) { LOG.debug(message, e); } else { LOG.debug(message); } } } private static void logDebug(String message) { logDebug(message, null); } private Calendar getGreenwichMeanTime() { return CommonUtils.getGreenwichMeanTime(); } @Override public void saveActivityIdForOwner(String ownerId, String type, String activityId) { SessionProvider sProvider = CommonUtils.createSystemProvider(); try { Node ownerNode = getNodeById(sProvider, ownerId, type); ActivityTypeUtils.attachActivityId(ownerNode, activityId); ownerNode.save(); } catch (Exception e) { LOG.error(String.format("Failed to attach activityId %s for node %s ", activityId, ownerId), e); } } @Override public void saveActivityIdForOwner(String ownerPath, String activityId) { SessionProvider sProvider = CommonUtils.createSystemProvider(); try { Node ownerNode = getNodeAt(sProvider, ownerPath); ActivityTypeUtils.attachActivityId(ownerNode, activityId); ownerNode.save(); } catch (Exception e) { LOG.error(String.format("Failed to save attach activityId %s for node %s ", activityId, ownerPath), e); } } @Override public String getActivityIdForOwner(String ownerId, String type) { SessionProvider sProvider = CommonUtils.createSystemProvider(); try { Node ownerNode = getNodeById(sProvider, ownerId, type); return ActivityTypeUtils.getActivityId(ownerNode); } catch (Exception e) { LOG.error(String.format("Failed to get attach activityId for %s: %s ", type, ownerId), e); } return null; } @Override public String getActivityIdForOwner(String ownerPath) { SessionProvider sProvider = CommonUtils.createSystemProvider(); try { Node ownerNode = getNodeAt(sProvider, ownerPath); return ActivityTypeUtils.getActivityId(ownerNode); } catch (Exception e) { LOG.error(String.format("Failed to get attach activityId for %s ", ownerPath), e); } return null; } private StringBuilder jcrPathLikeAndNotLike(String nodeType, String fullPath) { StringBuilder sqlQuery = new StringBuilder("SELECT * FROM ").append(nodeType).append(" WHERE ("); sqlQuery.append(JCR_PATH).append(" LIKE '").append(fullPath).append("/%' AND NOT ").append(JCR_PATH) .append(" LIKE '").append(fullPath).append("/%/%')"); return sqlQuery; } private NodeIterator getNodeIteratorBySQLQuery(SessionProvider sProvider, String sqlQuery, int offset, int limit, boolean caseInsensitiveOrder) throws Exception { QueryManager qm = sessionManager.getSession(sProvider).getWorkspace().getQueryManager(); QueryImpl query = (QueryImpl) qm.createQuery(sqlQuery, Query.SQL); if (limit > 0) { query.setOffset(offset); query.setLimit(limit); } if (caseInsensitiveOrder) { query.setCaseInsensitiveOrder(true); } QueryResult result = query.execute(); return result.getNodes(); } }