/* * Copyright (C) 2003-2010 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.faq.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.Date; import java.util.GregorianCalendar; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Queue; import java.util.Random; import java.util.Set; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import java.util.zip.ZipOutputStream; import javax.jcr.ImportUUIDBehavior; import javax.jcr.Item; import javax.jcr.ItemExistsException; import javax.jcr.ItemNotFoundException; import javax.jcr.Node; import javax.jcr.NodeIterator; import javax.jcr.PathNotFoundException; import javax.jcr.Property; import javax.jcr.RepositoryException; import javax.jcr.Session; import javax.jcr.Value; import javax.jcr.Workspace; 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 org.apache.commons.lang.StringUtils; import org.exoplatform.container.PortalContainer; import org.exoplatform.container.StandaloneContainer; import org.exoplatform.container.component.ComponentPlugin; import org.exoplatform.faq.service.Answer; import org.exoplatform.faq.service.Cate; import org.exoplatform.faq.service.Category; import org.exoplatform.faq.service.CategoryInfo; import org.exoplatform.faq.service.Comment; import org.exoplatform.faq.service.DataStorage; import org.exoplatform.faq.service.FAQEventQuery; import org.exoplatform.faq.service.FAQNodeTypes; import org.exoplatform.faq.service.FAQServiceUtils; import org.exoplatform.faq.service.FAQSetting; import org.exoplatform.faq.service.FileAttachment; import org.exoplatform.faq.service.JCRPageList; import org.exoplatform.faq.service.ObjectSearchResult; import org.exoplatform.faq.service.Question; import org.exoplatform.faq.service.QuestionInfo; import org.exoplatform.faq.service.QuestionLanguage; import org.exoplatform.faq.service.QuestionNodeListener; import org.exoplatform.faq.service.QuestionPageList; import org.exoplatform.faq.service.SubCategoryInfo; import org.exoplatform.faq.service.Utils; import org.exoplatform.faq.service.Watch; import org.exoplatform.ks.common.EmailNotifyPlugin; import org.exoplatform.ks.common.NotifyInfo; import org.exoplatform.ks.common.UserHelper; import org.exoplatform.ks.common.conf.RoleRulesPlugin; import org.exoplatform.ks.common.jcr.KSDataLocation; import org.exoplatform.ks.common.jcr.PropertyReader; import org.exoplatform.ks.common.jcr.SessionManager; import org.exoplatform.services.jcr.ext.common.SessionProvider; import org.exoplatform.services.jcr.impl.core.query.QueryImpl; import org.exoplatform.services.log.ExoLogger; import org.exoplatform.services.log.Log; import org.exoplatform.services.mail.MailService; import org.exoplatform.services.mail.Message; 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.SyndFeedOutput; /** * Created by The eXo Platform SARL Author : Hung Nguyen Quang hung.nguyen@exoplatform.com Jul 10, 2007 */ public class JCRDataStorage implements DataStorage, FAQNodeTypes { private static final Log log = ExoLogger.getLogger(JCRDataStorage.class); final private static String MIMETYPE_TEXTHTML = TEXT_HTML.intern(); @SuppressWarnings("unused") private Map<String, String> serverConfig_ = new HashMap<String, String>(); private Map<String, NotifyInfo> messagesInfoMap_ = new HashMap<String, NotifyInfo>(); final Queue<NotifyInfo> pendingMessagesQueue = new ConcurrentLinkedQueue<NotifyInfo>(); private final String ADMIN_ = "ADMIN".intern(); private List<RoleRulesPlugin> rulesPlugins_ = new ArrayList<RoleRulesPlugin>(); private SessionManager sessionManager; private KSDataLocation dataLocator; public JCRDataStorage(KSDataLocation dataLocator) throws Exception { this.dataLocator = dataLocator; sessionManager = dataLocator.getSessionManager(); } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#addPlugin(org.exoplatform.container.component.ComponentPlugin) */ public void addPlugin(ComponentPlugin plugin) throws Exception { try { serverConfig_ = ((EmailNotifyPlugin) plugin).getServerConfiguration(); } catch (Exception e) { log.error("\nFailed to add plugin\n ", e); } } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#addRolePlugin(org.exoplatform.container.component.ComponentPlugin) */ public void addRolePlugin(ComponentPlugin plugin) throws Exception { try { if (plugin instanceof RoleRulesPlugin) { rulesPlugins_.add((RoleRulesPlugin) plugin); } } catch (Exception e) { log.error("Failed to add role plugin\n", e); } } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#isAdminRole(java.lang.String) */ public boolean isAdminRole(String userName) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { Node cateHomeNode = getCategoryHome(sProvider, null); for (int i = 0; i < rulesPlugins_.size(); ++i) { List<String> list = new ArrayList<String>(); list.addAll(rulesPlugins_.get(i).getRules(this.ADMIN_)); list.addAll(new PropertyReader(cateHomeNode).list(EXO_MODERATORS, new ArrayList<String>())); if (list.contains(userName)) return true; if (Utils.hasPermission(list, UserHelper.getAllGroupAndMembershipOfUser(userName))) return true; } } catch (Exception e) { log.debug("Check user whether is admin: ", e); } finally { sProvider.close(); } return false; } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#getAllFAQAdmin() */ public List<String> getAllFAQAdmin() throws Exception { List<String> list = new ArrayList<String>(); try { for (int i = 0; i < rulesPlugins_.size(); ++i) { list.addAll(rulesPlugins_.get(i).getRules(this.ADMIN_)); } list = FAQServiceUtils.getUserPermission(list.toArray(new String[] {})); } catch (Exception e) { log.error("Failed to get all FAQ admin: ", e); } return list; } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#getUserSetting(java.lang.String, org.exoplatform.faq.service.FAQSetting) */ public void getUserSetting(String userName, FAQSetting faqSetting) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { Node userSettingNode = getUserSettingHome(sProvider).getNode(userName); PropertyReader reader = new PropertyReader(userSettingNode); faqSetting.setOrderBy(reader.string(EXO_ORDE_BY, EMPTY_STR)); faqSetting.setOrderType(reader.string(EXO_ORDE_TYPE, EMPTY_STR)); faqSetting.setSortQuestionByVote(reader.bool(EXO_SORT_QUESTION_BY_VOTE)); } catch (Exception e) { saveFAQSetting(faqSetting, userName); } finally { sProvider.close(); } } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#saveFAQSetting(org.exoplatform.faq.service.FAQSetting, java.lang.String) */ public void saveFAQSetting(FAQSetting faqSetting, String userName) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { Node userSettingNode = getUserSettingHome(sProvider).getNode(userName); userSettingNode.setProperty(EXO_ORDE_BY, faqSetting.getOrderBy()); userSettingNode.setProperty(EXO_ORDE_TYPE, faqSetting.getOrderType()); userSettingNode.setProperty(EXO_SORT_QUESTION_BY_VOTE, faqSetting.isSortQuestionByVote()); userSettingNode.save(); } catch (PathNotFoundException e) { Node userSettingNode = getUserSettingHome(sProvider).addNode(userName, EXO_FAQ_USER_SETTING); userSettingNode.setProperty(EXO_ORDE_BY, faqSetting.getOrderBy()); userSettingNode.setProperty(EXO_ORDE_TYPE, faqSetting.getOrderType()); userSettingNode.setProperty(EXO_SORT_QUESTION_BY_VOTE, faqSetting.isSortQuestionByVote()); userSettingNode.getSession().save(); } finally { sProvider.close(); } } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#getUserAvatar(java.lang.String) */ public FileAttachment getUserAvatar(String userName) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { Node node = getKSUserAvatarHomeNode(sProvider).getNode(userName); if (node.isNodeType(NT_FILE)) { FileAttachment attachment = new FileAttachment(); Node nodeFile = node.getNode(JCR_CONTENT); attachment.setId(node.getPath()); attachment.setMimeType(nodeFile.getProperty(JCR_MIME_TYPE).getString()); attachment.setNodeName(node.getName()); attachment.setName("avatar." + attachment.getMimeType()); String workspace = node.getSession().getWorkspace().getName(); attachment.setWorkspace(workspace); attachment.setPath("/" + workspace + node.getPath()); attachment.setSize(nodeFile.getProperty(JCR_DATA).getStream().available()); return attachment; } } catch (PathNotFoundException e) { return null; } catch (RepositoryException e) { return null; } catch (Exception e) { log.error("Failed to get user avatar", e); } finally { sProvider.close(); } return null; } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#saveUserAvatar(java.lang.String, org.exoplatform.faq.service.FileAttachment) */ public void saveUserAvatar(String userId, FileAttachment fileAttachment) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { Node ksAvatarHomeNode = getKSUserAvatarHomeNode(sProvider); Node avatarNode; if (ksAvatarHomeNode.hasNode(userId)) avatarNode = ksAvatarHomeNode.getNode(userId); else avatarNode = ksAvatarHomeNode.addNode(userId, NT_FILE); FAQServiceUtils.reparePermissions(avatarNode, "any"); Node nodeContent; 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()); if (avatarNode.isNew()) ksAvatarHomeNode.getSession().save(); else ksAvatarHomeNode.save(); } catch (Exception e) { log.error("Failed to save user avatar: ", e); } finally { sProvider.close(); } } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#setDefaultAvatar(java.lang.String) */ public void setDefaultAvatar(String userName) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { Node avatarHome = getKSUserAvatarHomeNode(sProvider); if (avatarHome.hasNode(userName)) { Node node = avatarHome.getNode(userName); if (node.isNodeType(NT_FILE)) { node.remove(); avatarHome.save(); } } } catch (Exception e) { log.error("Failed to set default avatar: ", e); } finally { sProvider.close(); } } public NodeIterator getQuestionsIterator(SessionProvider sProvider) throws Exception { try { Node faqHome = getFAQServiceHome(sProvider); return getQuestionsIterator(faqHome, EMPTY_STR, true); } catch (Exception e) { log.error("Failed to get question iterator: ", e); return null; } } private NodeIterator getQuestionsIterator(Node parentNode, String strQuery, boolean isAll) throws Exception { StringBuffer queryString = new StringBuffer(JCR_ROOT).append(parentNode.getPath()).append((isAll) ? "//" : "/").append("element(*,exo:faqQuestion)").append(strQuery); QueryManager qm = parentNode.getSession().getWorkspace().getQueryManager(); Query query = qm.createQuery(queryString.toString(), Query.XPATH); QueryResult result = query.execute(); return result.getNodes(); } public void reInitQuestionNodeListeners() throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { NodeIterator iter = getQuestionsIterator(sProvider); if (iter == null) return; while (iter.hasNext()) { Node quesNode = iter.nextNode(); registerQuestionNodeListener(quesNode); } } catch (Exception e) { log.error("Failed to get question iterator: ", e); } finally { sProvider.close(); } } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#initRootCategory() */ public boolean initRootCategory() throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { Node faqServiceHome = getFAQServiceHome(sProvider); if (faqServiceHome.hasNode(Utils.CATEGORY_HOME)) { log.error("root category is already created"); return false; } Node categoryHome = faqServiceHome.addNode(Utils.CATEGORY_HOME, EXO_FAQ_CATEGORY); categoryHome.addMixin(MIX_FAQ_SUB_CATEGORY); categoryHome.setProperty(EXO_NAME, "Answers"); categoryHome.setProperty(EXO_IS_VIEW, true); faqServiceHome.save(); log.info("Initialized root category : " + categoryHome.getPath()); return true; } catch (Exception e) { log.error("Could not initialize root category", e); return false; } finally { sProvider.close(); } } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#getTemplate() */ public byte[] getTemplate() throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { Node templateHome = getTemplateHome(sProvider); Node fileNode = templateHome.getNode(Utils.UI_FAQ_VIEWER); if (fileNode.isNodeType(NT_FILE)) { Node contentNode = fileNode.getNode(JCR_CONTENT); InputStream inputStream = contentNode.getProperty(JCR_DATA).getStream(); byte[] data = new byte[inputStream.available()]; inputStream.read(data); inputStream.close(); return data; } } catch (Exception e) { log.error("Failed to get template", e); } finally { sProvider.close(); } return null; } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#saveTemplate(java.lang.String) */ public void saveTemplate(String str) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { Node templateHome = getTemplateHome(sProvider); Node fileNode; try { fileNode = templateHome.getNode(Utils.UI_FAQ_VIEWER); } catch (Exception e) { fileNode = templateHome.addNode(Utils.UI_FAQ_VIEWER, NT_FILE); } Node nodeContent = null; InputStream inputStream = null; byte[] byte_ = str.getBytes(); inputStream = new ByteArrayInputStream(byte_); try { nodeContent = fileNode.addNode(JCR_CONTENT, NT_RESOURCE); } catch (Exception e) { nodeContent = fileNode.getNode(JCR_CONTENT); } nodeContent.setProperty(JCR_MIME_TYPE, "application/x-groovy+html"); nodeContent.setProperty(JCR_DATA, inputStream); nodeContent.setProperty(JCR_LAST_MODIFIED, Calendar.getInstance().getTimeInMillis()); if (templateHome.isNew()) { templateHome.getSession().save(); } else { templateHome.save(); } } catch (Exception e) { log.error("Failed to save template: ", e); } finally { sProvider.close(); } } protected Value[] booleanToValues(Node node, Boolean[] bools) throws Exception { if (bools == null) return new Value[] { node.getSession().getValueFactory().createValue(true) }; Value[] values = new Value[bools.length]; for (int i = 0; i < values.length; i++) { values[i] = node.getSession().getValueFactory().createValue(bools[i]); } return values; } private boolean questionHasAnswer(Node questionNode) throws Exception { if (questionNode.hasNode(Utils.ANSWER_HOME) && questionNode.getNode(Utils.ANSWER_HOME).hasNodes()) return true; return false; } private void sendNotifyWatcher(SessionProvider sProvider, Question question, FAQSetting faqSetting, boolean isNew) { // Send notification when add new question in watching category List<String> emails = new ArrayList<String>(); List<String> users = new ArrayList<String>(); List<String> emailsList = new ArrayList<String>(); emailsList.add(question.getEmail()); try { Node cate = getCategoryNodeById(sProvider, question.getCategoryId()); PropertyReader reader = new PropertyReader(cate); // watch in category parent emails.addAll(reader.list(EXO_EMAIL_WATCHING, new ArrayList<String>())); users.addAll(reader.list(EXO_USER_WATCHING, new ArrayList<String>())); // watch in this question if (question.getEmailsWatch() != null && question.getEmailsWatch().length > 0) { emails.addAll(Arrays.asList(question.getEmailsWatch())); users.addAll(Arrays.asList(question.getUsersWatch())); } if (!question.isActivated() || (!question.isApproved() && faqSetting.getDisplayMode().equals("approved"))) { // only send notification to administrations or moderators List<String> moderators = reader.list(EXO_MODERATORS, new ArrayList<String>()); List<String> temps = new ArrayList<String>(); int i = 0; for (String user : users) { if (!temps.contains(user)) { temps.add(user); if (isAdminRole(user) || Utils.hasPermission(moderators, UserHelper.getAllGroupAndMembershipOfUser(user))) { emailsList.add(emails.get(i)); } } ++i; } } else { emailsList.addAll(emails); } if (emailsList != null && emailsList.size() > 0) { Message message = new Message(); message.setMimeType(MIMETYPE_TEXTHTML); message.setFrom(question.getAuthor()); message.setSubject(faqSetting.getEmailSettingSubject() + ": " + question.getQuestion()); String body = StringUtils.replace(faqSetting.getEmailSettingContent(), "&questionContent_", question.getDetail()); body = StringUtils.replace(body, "&questionLink_", question.getLink()); if (question.getAnswers() != null && question.getAnswers().length > 0) { body = StringUtils.replace(body, "&questionResponse_", question.getAnswers()[0].getResponses()); } else { body = StringUtils.replace(body, "&questionResponse_", EMPTY_STR); } message.setBody(body); sendEmailNotification(emailsList, message); } } catch (Exception e) { log.error("Failed to send a nofify for category watcher: ", e); } } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#sendMessage(org.exoplatform.services.mail.Message) */ public void sendMessage(Message message) throws Exception { try { MailService mService = (MailService) PortalContainer.getComponent(MailService.class); mService.sendMessage(message); } catch (NullPointerException e) { MailService mService = (MailService) StandaloneContainer.getInstance().getComponentInstanceOfType(MailService.class); mService.sendMessage(message); } } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#getQuestionLanguages(java.lang.String) */ public List<QuestionLanguage> getQuestionLanguages(String questionId) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); List<QuestionLanguage> listQuestionLanguage = new ArrayList<QuestionLanguage>(); try { Node questionNode = getFAQServiceHome(sProvider).getNode(questionId); try { listQuestionLanguage.add(getQuestionLanguage(questionNode)); } catch (Exception e) { log.debug("Adding a question node failed: ", e); } if (questionNode.hasNode(Utils.LANGUAGE_HOME)) { Node languageNode = questionNode.getNode(Utils.LANGUAGE_HOME); NodeIterator nodeIterator = languageNode.getNodes(); while (nodeIterator.hasNext()) { try { listQuestionLanguage.add(getQuestionLanguage(nodeIterator.nextNode())); } catch (Exception e) { } } } } catch (Exception e) { log.error("Failed to get question language: ", e); } finally { sProvider.close(); } return listQuestionLanguage; } private QuestionLanguage getQuestionLanguage(Node questionNode) throws Exception { QuestionLanguage questionLanguage = new QuestionLanguage(); questionLanguage.setState(QuestionLanguage.VIEW); questionLanguage.setId(questionNode.getName()); PropertyReader reader = new PropertyReader(questionNode); questionLanguage.setLanguage(reader.string(EXO_LANGUAGE, EMPTY_STR)); questionLanguage.setQuestion(reader.string(EXO_TITLE, EMPTY_STR)); questionLanguage.setDetail(reader.string(EXO_NAME, EMPTY_STR)); Comment[] comments = getComment(questionNode); Answer[] answers = getAnswers(questionNode); questionLanguage.setComments(comments); questionLanguage.setAnswers(answers); return questionLanguage; } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#deleteAnswer(java.lang.String, java.lang.String) */ public void deleteAnswer(String questionId, String answerId) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { Node questionNode = getFAQServiceHome(sProvider).getNode(questionId); Node answerNode = questionNode.getNode(Utils.ANSWER_HOME).getNode(answerId); answerNode.remove(); questionNode.save(); } catch (Exception e) { log.error("Failed to delete a answer: ", e); } finally { sProvider.close(); } } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#deleteComment(java.lang.String, java.lang.String) */ public void deleteComment(String questionId, String commentId) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { Node questionNode = getFAQServiceHome(sProvider).getNode(questionId); Node commnetNode = questionNode.getNode(Utils.COMMENT_HOME).getNode(commentId); commnetNode.remove(); questionNode.save(); } catch (Exception e) { log.error("Failed to delete a commnent: ", e); } finally { sProvider.close(); } } private Answer[] getAnswers(Node questionNode) throws Exception { try { if (!questionNode.hasNode(Utils.ANSWER_HOME)) return new Answer[] {}; NodeIterator nodeIterator = questionNode.getNode(Utils.ANSWER_HOME).getNodes(); List<Answer> answers = new ArrayList<Answer>(); Answer ans; String language = questionNode.getProperty(EXO_LANGUAGE).getString(); while (nodeIterator.hasNext()) { try { Node node = nodeIterator.nextNode(); ans = getAnswerByNode(node); ans.setLanguage(language); answers.add(ans); } catch (Exception e) { log.error("Failed to get anwser", e); } } return answers.toArray(new Answer[] {}); } catch (Exception e) { log.error("Failed to get answer: ", e); } return new Answer[] {}; } private Answer getAnswerByNode(Node answerNode) throws Exception { Answer answer = new Answer(); answer.setId(answerNode.getName()); PropertyReader reader = new PropertyReader(answerNode); answer.setResponses(reader.string(EXO_RESPONSES, EMPTY_STR)); answer.setResponseBy(reader.string(EXO_RESPONSE_BY, EMPTY_STR)); answer.setFullName(reader.string(EXO_FULL_NAME, EMPTY_STR)); answer.setDateResponse((answerNode.getProperty(EXO_DATE_RESPONSE).getDate().getTime())); answer.setUsersVoteAnswer(reader.strings(EXO_USERS_VOTE_ANSWER, new String[] {})); answer.setMarkVotes(reader.l(EXO_MARK_VOTE, 0)); answer.setApprovedAnswers(reader.bool(EXO_APPROVE_RESPONSES, true)); answer.setActivateAnswers(reader.bool(EXO_ACTIVATE_RESPONSES, true)); answer.setPostId(reader.string(EXO_POST_ID, EMPTY_STR)); String path = answerNode.getPath(); answer.setPath(path.substring(path.indexOf(Utils.FAQ_APP) + Utils.FAQ_APP.length() + 1)); return answer; } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#getPageListAnswer(java.lang.String, java.lang.Boolean) */ public JCRPageList getPageListAnswer(String questionId, boolean isSortByVote) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { Node questionNode = getFAQServiceHome(sProvider).getNode(questionId); if (questionNode.hasNode(Utils.ANSWER_HOME)) { Node answerHome = questionNode.getNode(Utils.ANSWER_HOME); QueryManager qm = answerHome.getSession().getWorkspace().getQueryManager(); StringBuffer queryString = new StringBuffer(JCR_ROOT).append(answerHome.getPath()).append("//element(*,exo:answer)"); if ((Boolean) isSortByVote == null) queryString.append("order by @exo:dateResponse ascending"); else if (isSortByVote) queryString.append("order by @exo:MarkVotes ascending"); else queryString.append("order by @exo:MarkVotes descending"); Query query = qm.createQuery(queryString.toString(), Query.XPATH); QueryResult result = query.execute(); QuestionPageList pageList = new QuestionPageList(result.getNodes(), 10, queryString.toString(), true); return pageList; } } catch (Exception e) { log.error("Failed to get page list answers", e); } finally { sProvider.close(); } return null; } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#saveAnswer(java.lang.String, org.exoplatform.faq.service.Answer, boolean) */ public void saveAnswer(String questionId, Answer answer, boolean isNew) throws Exception { Answer[] answers = { answer }; saveAnswer(questionId, answers); } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#saveAnswer(java.lang.String, org.exoplatform.faq.service.Answer[]) */ public void saveAnswer(String questionId, Answer[] answers) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { Node quesNode = getFAQServiceHome(sProvider).getNode(questionId); if (!quesNode.isNodeType(MIX_FAQI_1_8N)) { quesNode.addMixin(MIX_FAQI_1_8N); } Node answerHome; String qId = quesNode.getName(); String categoryId = quesNode.getProperty(EXO_CATEGORY_ID).getString(); String defaultLang = quesNode.getProperty(EXO_LANGUAGE).getString(); for (Answer answer : answers) { if (answer.getLanguage().equals(defaultLang)) { try { answerHome = quesNode.getNode(Utils.ANSWER_HOME); } catch (Exception e) { answerHome = quesNode.addNode(Utils.ANSWER_HOME, EXO_ANSWER_HOME); } } else { // answer for other languages Node langNode = getLanguageNodeByLanguage(quesNode, answer.getLanguage()); try { answerHome = langNode.getNode(Utils.ANSWER_HOME); } catch (Exception e) { answerHome = langNode.addNode(Utils.ANSWER_HOME, EXO_ANSWER_HOME); } } saveAnswer(answer, answerHome, qId, categoryId); } quesNode.save(); } catch (Exception e) { log.error("Failed to save answer: ", e); } finally { sProvider.close(); } } private void saveAnswer(Answer answer, Node answerHome, String questionId, String categoryId) throws Exception { Node answerNode; try { answerNode = answerHome.getNode(answer.getId()); } catch (PathNotFoundException e) { answerNode = answerHome.addNode(answer.getId(), EXO_ANSWER); } if (!answer.isNew()) { // remove answer answerNode.remove(); return; } try { if (answerNode.isNew()) { java.util.Calendar calendar = GregorianCalendar.getInstance(); if (answer.getDateResponse() != null) calendar.setTime(answer.getDateResponse()); answerNode.setProperty(EXO_DATE_RESPONSE, calendar); answerNode.setProperty(EXO_ID, answer.getId()); answerNode.setProperty(EXO_APPROVE_RESPONSES, answer.getApprovedAnswers()); answerNode.setProperty(EXO_ACTIVATE_RESPONSES, answer.getActivateAnswers()); } else { if (new PropertyReader(answerNode).bool(EXO_APPROVE_RESPONSES, false) != answer.getApprovedAnswers()) answerNode.setProperty(EXO_APPROVE_RESPONSES, answer.getApprovedAnswers()); if (new PropertyReader(answerNode).bool(EXO_ACTIVATE_RESPONSES, false) != answer.getActivateAnswers()) answerNode.setProperty(EXO_ACTIVATE_RESPONSES, answer.getActivateAnswers()); } if (answer.getPostId() != null && answer.getPostId().length() > 0) { answerNode.setProperty(EXO_POST_ID, answer.getPostId()); } answerNode.setProperty(EXO_RESPONSES, answer.getResponses()); answerNode.setProperty(EXO_RESPONSE_BY, answer.getResponseBy()); answerNode.setProperty(EXO_FULL_NAME, answer.getFullName()); answerNode.setProperty(EXO_USERS_VOTE_ANSWER, answer.getUsersVoteAnswer()); answerNode.setProperty(EXO_MARK_VOTES, answer.getMarkVotes()); answerNode.setProperty(EXO_RESPONSE_LANGUAGE, answer.getLanguage()); answerNode.setProperty(EXO_QUESTION_ID, questionId); answerNode.setProperty(EXO_CATEGORY_ID, categoryId); } catch (Exception e) { log.error("Failed to save Answer: ", e); } } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#saveComment(java.lang.String, org.exoplatform.faq.service.Comment, boolean) */ public void saveComment(String questionId, Comment comment, boolean isNew) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { Node quesNode = getFAQServiceHome(sProvider).getNode(questionId); if (!quesNode.isNodeType(MIX_FAQI_1_8N)) { quesNode.addMixin(MIX_FAQI_1_8N); } Node commentHome = null; try { commentHome = quesNode.getNode(Utils.COMMENT_HOME); } catch (PathNotFoundException e) { commentHome = quesNode.addNode(Utils.COMMENT_HOME, EXO_COMMENT_HOME); } Node commentNode; if (isNew) { commentNode = commentHome.addNode(comment.getId(), EXO_COMMENT); java.util.Calendar calendar = GregorianCalendar.getInstance(); commentNode.setProperty(EXO_DATE_COMMENT, calendar); commentNode.setProperty(EXO_ID, comment.getId()); } else { commentNode = commentHome.getNode(comment.getId()); } if (comment.getPostId() != null && comment.getPostId().length() > 0) { commentNode.setProperty(EXO_POST_ID, comment.getPostId()); } commentNode.setProperty(EXO_COMMENTS, comment.getComments()); commentNode.setProperty(EXO_COMMENT_BY, comment.getCommentBy()); commentNode.setProperty(EXO_FULL_NAME, comment.getFullName()); commentNode.setProperty(EXO_CATEGORY_ID, quesNode.getProperty(EXO_CATEGORY_ID).getString()); commentNode.setProperty(EXO_QUESTION_ID, quesNode.getName()); commentNode.setProperty(EXO_COMMENT_LANGUAGE, quesNode.getProperty(EXO_LANGUAGE).getString()); if (commentNode.isNew()) quesNode.getSession().save(); else quesNode.save(); } catch (Exception e) { log.error("Failed to save comment: ", e); } finally { sProvider.close(); } } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#saveAnswerQuestionLang(java.lang.String, org.exoplatform.faq.service.Answer, java.lang.String, boolean) */ public void saveAnswerQuestionLang(String questionId, Answer answer, String language, boolean isNew) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { Node quesNode = getFAQServiceHome(sProvider).getNode(questionId); Node answerHome = null; try { answerHome = quesNode.getNode(Utils.ANSWER_HOME); } catch (PathNotFoundException e) { answerHome = quesNode.addNode(Utils.ANSWER_HOME, EXO_ANSWER_HOME); } Node answerNode; if (isNew) { answerNode = answerHome.addNode(answer.getId(), EXO_ANSWER); java.util.Calendar calendar = GregorianCalendar.getInstance(); answerNode.setProperty("exo:dateResponses", calendar); answerNode.setProperty(EXO_APPROVE_RESPONSES, answer.getApprovedAnswers()); answerNode.setProperty(EXO_ACTIVATE_RESPONSES, answer.getActivateAnswers()); } else { answerNode = answerHome.getNode(answer.getId()); if (new PropertyReader(answerNode).bool(EXO_APPROVE_RESPONSES, false) != answer.getApprovedAnswers()) answerNode.setProperty(EXO_APPROVE_RESPONSES, answer.getApprovedAnswers()); if (new PropertyReader(answerNode).bool(EXO_ACTIVATE_RESPONSES, false) != answer.getActivateAnswers()) answerNode.setProperty(EXO_ACTIVATE_RESPONSES, answer.getActivateAnswers()); } answerNode.setProperty(EXO_RESPONSES, answer.getResponses()); answerNode.setProperty(EXO_RESPONSE_BY, answer.getResponseBy()); answerNode.setProperty(EXO_FULL_NAME, answer.getFullName()); answerNode.setProperty(EXO_USERS_VOTE_ANSWER, answer.getUsersVoteAnswer()); } catch (Exception e) { log.error("Failed to save answer question language: ", e); } finally { sProvider.close(); } } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#getAnswerById(java.lang.String, java.lang.String) */ public Answer getAnswerById(String questionId, String answerid) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { Node answerNode = getFAQServiceHome(sProvider).getNode(questionId).getNode(Utils.ANSWER_HOME).getNode(answerid); return getAnswerByNode(answerNode); } catch (Exception e) { log.error("Failed to get answer by id.", e); } finally { sProvider.close(); } return null; } private Comment[] getComment(Node questionNode) throws Exception { try { if (!questionNode.hasNode(Utils.COMMENT_HOME)) return new Comment[] {}; NodeIterator nodeIterator = questionNode.getNode(Utils.COMMENT_HOME).getNodes(); Comment[] comments = new Comment[(int) nodeIterator.getSize()]; Node commentNode = null; int i = 0; while (nodeIterator.hasNext()) { commentNode = nodeIterator.nextNode(); comments[i] = getCommentByNode(commentNode); i++; } return comments; } catch (Exception e) { log.error("Failed to get comment: ", e); return new Comment[] {}; } } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#getPageListComment(java.lang.String) */ public JCRPageList getPageListComment(String questionId) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { Node commentHome = getFAQServiceHome(sProvider).getNode(questionId + "/" + Utils.COMMENT_HOME); QueryManager qm = commentHome.getSession().getWorkspace().getQueryManager(); StringBuffer queryString = new StringBuffer(JCR_ROOT).append(commentHome.getPath()).append("//element(*,exo:comment)").append("order by @exo:dateComment ascending"); Query query = qm.createQuery(queryString.toString(), Query.XPATH); QueryResult result = query.execute(); QuestionPageList pageList = new QuestionPageList(result.getNodes(), 10, queryString.toString(), true); return pageList; } catch (Exception e) { log.debug("Failed to get page list comments", e); return null; } finally { sProvider.close(); } } private Comment getCommentByNode(Node commentNode) throws Exception { Comment comment = new Comment(); comment.setId(commentNode.getName()); PropertyReader reader = new PropertyReader(commentNode); comment.setComments((reader.string(EXO_COMMENTS, EMPTY_STR))); comment.setCommentBy((reader.string(EXO_COMMENT_BY, EMPTY_STR))); comment.setDateComment((commentNode.getProperty(EXO_DATE_COMMENT).getDate().getTime())); comment.setFullName((reader.string(EXO_FULL_NAME, EMPTY_STR))); comment.setPostId(reader.string(EXO_POST_ID, EMPTY_STR)); return comment; } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#getCommentById(java.lang.String, java.lang.String) */ public Comment getCommentById(String questionId, String commentId) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { Node commentNode = getFAQServiceHome(sProvider).getNode(questionId + "/" + Utils.COMMENT_HOME + "/" + commentId); return getCommentByNode(commentNode); } catch (Exception e) { log.error("Failed to get comment by id: " + commentId, e); return null; } finally { sProvider.close(); } } private Node getLanguageNodeByLanguage(Node questionNode, String languge) throws Exception { NodeIterator nodeIterator = questionNode.getNode(Utils.LANGUAGE_HOME).getNodes(); Node languageNode = null; while (nodeIterator.hasNext()) { languageNode = nodeIterator.nextNode(); if (languageNode.getProperty(EXO_LANGUAGE).getString().equals(languge)) return languageNode; } return null; } @SuppressWarnings("static-access") private void saveQuestion(Node questionNode, Question question, boolean isNew, SessionProvider sProvider, FAQSetting faqSetting) throws Exception { // boolean isMoveQuestion = false; questionNode.setProperty(EXO_ID, questionNode.getName()); questionNode.setProperty(EXO_NAME, question.getDetail()); questionNode.setProperty(EXO_AUTHOR, question.getAuthor()); questionNode.setProperty(EXO_EMAIL, question.getEmail()); questionNode.setProperty(EXO_TITLE, question.getQuestion()); questionNode.setProperty(EXO_LAST_ACTIVITY, getLastActivityInfo(question.getAuthor(), Utils.getInstanceTempCalendar().getTimeInMillis())); if (isNew) { GregorianCalendar cal = new GregorianCalendar(); cal.setTime(question.getCreatedDate()); questionNode.setProperty(EXO_CREATED_DATE, cal.getInstance()); questionNode.setProperty(EXO_LANGUAGE, question.getLanguage()); } String catId = question.getCategoryId(); if (!question.getCategoryId().equals(Utils.CATEGORY_HOME)) { catId = catId.substring(catId.lastIndexOf("/") + 1); } questionNode.setProperty(EXO_CATEGORY_ID, catId); questionNode.setProperty(EXO_IS_ACTIVATED, question.isActivated()); questionNode.setProperty(EXO_IS_APPROVED, question.isApproved()); questionNode.setProperty(EXO_USERS_VOTE, question.getUsersVote()); questionNode.setProperty(EXO_MARK_VOTE, question.getMarkVote()); questionNode.setProperty(EXO_LINK, question.getLink()); List<FileAttachment> listFileAtt = question.getAttachMent(); List<String> listNodeNames = new ArrayList<String>(); if (!listFileAtt.isEmpty()) { for (FileAttachment att : listFileAtt) { listNodeNames.add(att.getNodeName()); try { Node nodeFile = null; if (questionNode.hasNode(att.getNodeName())) nodeFile = questionNode.getNode(att.getNodeName()); else nodeFile = questionNode.addNode(att.getNodeName(), EXO_FAQ_ATTACHMENT); // fix permission to download file in ie 6: FAQServiceUtils.reparePermissions(nodeFile, "any"); Node nodeContent = null; if (nodeFile.hasNode(JCR_CONTENT)) nodeContent = nodeFile.getNode(JCR_CONTENT); else nodeContent = nodeFile.addNode(JCR_CONTENT, EXO_FAQ_RESOURCE); nodeContent.setProperty(EXO_FILE_NAME, att.getName()); nodeContent.setProperty(EXO_CATEGORY_ID, catId); nodeContent.setProperty(JCR_MIME_TYPE, att.getMimeType()); nodeContent.setProperty(JCR_DATA, att.getInputStream()); nodeContent.setProperty(JCR_LAST_MODIFIED, Calendar.getInstance().getTimeInMillis()); } catch (Exception e) { log.error("Failed to save question: ", e); } } } // remove attachments NodeIterator nodeIterator = questionNode.getNodes(); Node node = null; while (nodeIterator.hasNext()) { node = nodeIterator.nextNode(); if (node.isNodeType(EXO_FAQ_ATTACHMENT) && !listNodeNames.contains(node.getName())) node.remove(); } question.setId(questionNode.getName()); String catePath = questionNode.getParent().getParent().getPath(); question.setCategoryId(catePath.substring(catePath.indexOf(Utils.FAQ_APP) + Utils.FAQ_APP.length() + 1)); sendNotifyWatcher(sProvider, question, faqSetting, isNew); } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#saveQuestion(org.exoplatform.faq.service.Question, boolean, org.exoplatform.faq.service.FAQSetting) */ public Node saveQuestion(Question question, boolean isAddNew, FAQSetting faqSetting) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { Node questionNode; Node questionHome; Node category; if (isAddNew) { category = getFAQServiceHome(sProvider).getNode(question.getCategoryId()); try { questionHome = category.getNode(Utils.QUESTION_HOME); } catch (PathNotFoundException ex) { questionHome = category.addNode(Utils.QUESTION_HOME, EXO_FAQ_QUESTION_HOME); } questionNode = questionHome.addNode(question.getId(), EXO_FAQ_QUESTION); } else { questionNode = getFAQServiceHome(sProvider).getNode(question.getPath()); } saveQuestion(questionNode, question, isAddNew, sProvider, faqSetting); if (questionNode.isNew()) { questionNode.getSession().save(); registerQuestionNodeListener(questionNode); } else questionNode.save(); return questionNode; } catch (Exception e) { log.error("Failed to save question ", e); } finally { sProvider.close(); } return null; } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#removeQuestion(java.lang.String) */ public void removeQuestion(String questionId) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { Node questionNode = getFAQServiceHome(sProvider).getNode(questionId); Node questionHome = questionNode.getParent(); questionNode.remove(); questionHome.save(); } catch (Exception e) { log.error("Fail ro remove question: ", e); } finally { sProvider.close(); } } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#getCommentById(javax.jcr.Node, java.lang.String) */ public Comment getCommentById(Node questionNode, String commentId) throws Exception { try { Comment comment = new Comment(); Node commentNode = questionNode.getNode(Utils.COMMENT_HOME).getNode(commentId); comment.setId(commentNode.getName()); PropertyReader reader = new PropertyReader(commentNode); comment.setComments((reader.string(EXO_COMMENTS, EMPTY_STR))); comment.setCommentBy((reader.string(EXO_COMMENT_BY, EMPTY_STR))); comment.setDateComment(reader.date(EXO_DATE_COMMENT)); comment.setPostId(reader.string(EXO_POST_ID, EMPTY_STR)); return comment; } catch (Exception e) { log.error("Failed to get comment through id: ", e); return null; } } private Question getQuestion(Node questionNode) throws Exception { Question question = new Question(); PropertyReader reader = new PropertyReader(questionNode); question.setId(questionNode.getName()); question.setLanguage(reader.string(EXO_LANGUAGE, EMPTY_STR)); question.setDetail(reader.string(EXO_NAME, EMPTY_STR)); question.setAuthor(reader.string(EXO_AUTHOR, EMPTY_STR)); question.setEmail(reader.string(EXO_EMAIL, EMPTY_STR)); question.setQuestion(reader.string(EXO_TITLE, EMPTY_STR)); question.setCreatedDate(reader.date(EXO_CREATED_DATE)); question.setCategoryId(reader.string(EXO_CATEGORY_ID, EMPTY_STR)); question.setActivated(reader.bool(EXO_IS_ACTIVATED, true)); question.setApproved(reader.bool(EXO_IS_APPROVED, true)); question.setRelations(reader.strings(EXO_RELATIVES, new String[] {})); question.setNameAttachs(reader.strings(EXO_NAME_ATTACHS, new String[] {})); question.setUsersVote(reader.strings(EXO_USERS_VOTE, new String[] {})); question.setMarkVote(reader.d(EXO_MARK_VOTE)); question.setEmailsWatch(reader.strings(EXO_EMAIL_WATCHING, new String[] {})); question.setUsersWatch(reader.strings(EXO_USER_WATCHING, new String[] {})); question.setTopicIdDiscuss(reader.string(EXO_TOPIC_ID_DISCUSS, EMPTY_STR)); question.setLink(reader.string(EXO_LINK, EMPTY_STR)); question.setLastActivity(reader.string(EXO_LAST_ACTIVITY, EMPTY_STR)); question.setNumberOfPublicAnswers(reader.l(EXO_NUMBER_OF_PUBLIC_ANSWERS, 0)); String path = questionNode.getPath(); question.setPath(path.substring(path.indexOf(Utils.FAQ_APP) + Utils.FAQ_APP.length() + 1)); List<FileAttachment> listFile = new ArrayList<FileAttachment>(); NodeIterator nodeIterator = questionNode.getNodes(); Node nodeFile; Node node; FileAttachment attachment = null; String workspace = questionNode.getSession().getWorkspace().getName(); while (nodeIterator.hasNext()) { node = nodeIterator.nextNode(); if (node.isNodeType(EXO_FAQ_ATTACHMENT)) { attachment = new FileAttachment(); nodeFile = node.getNode(JCR_CONTENT); attachment.setId(node.getPath()); attachment.setMimeType(nodeFile.getProperty(JCR_MIME_TYPE).getString()); attachment.setNodeName(node.getName()); attachment.setName(nodeFile.getProperty(EXO_FILE_NAME).getString()); attachment.setWorkspace(workspace); attachment.setPath("/" + workspace + node.getPath()); try { if (nodeFile.hasProperty(JCR_DATA)) attachment.setSize(nodeFile.getProperty(JCR_DATA).getStream().available()); else attachment.setSize(0); } catch (Exception e) { attachment.setSize(0); log.error("Failed to get question: ", e); } listFile.add(attachment); } } question.setAttachMent(listFile); question.setAnswers(getAnswers(questionNode)); question.setComments(getComment(questionNode)); return question; } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#getQuestionById(java.lang.String) */ public Question getQuestionById(String questionId) throws Exception { SessionProvider sessionProvider = SessionProvider.createSystemProvider(); try { return getQuestion(getQuestionNodeById(sessionProvider, questionId)); } finally { sessionProvider.close(); } } private List<String> getViewableCategoryIds(SessionProvider sessionProvider) throws Exception { List<String> listId = new ArrayList<String>(); Node cateHomeNode = getCategoryHome(sessionProvider, null); StringBuffer queryString = new StringBuffer(JCR_ROOT).append(cateHomeNode.getPath()).append("//element(*,exo:faqCategory)[@exo:isView='true'] order by @exo:createdDate descending"); QueryManager qm = cateHomeNode.getSession().getWorkspace().getQueryManager(); Query query = qm.createQuery(queryString.toString(), Query.XPATH); QueryResult result = query.execute(); NodeIterator iter = result.getNodes(); while (iter.hasNext()) { listId.add(iter.nextNode().getName()); } listId.add(Utils.CATEGORY_HOME); return listId; } private List<String> getRetrictedCategories(String userId, List<String> usermemberships) throws Exception { List<String> categoryList = new ArrayList<String>(); SessionProvider sessionProvider = SessionProvider.createSystemProvider(); try { Node faqHome = getFAQServiceHome(sessionProvider); StringBuffer queryString = new StringBuffer(JCR_ROOT).append(faqHome.getPath()).append("//element(*,exo:faqCategory)[@exo:userPrivate != ''] order by @exo:createdDate descending"); QueryManager qm = faqHome.getSession().getWorkspace().getQueryManager(); Query query = qm.createQuery(queryString.toString(), Query.XPATH); QueryResult result = query.execute(); NodeIterator iter = result.getNodes(); boolean isAudience = false; List<String> audiences; while (iter.hasNext()) { if (usermemberships.size() > 0) { Node cat = iter.nextNode(); try { audiences = new PropertyReader(cat).list(EXO_USER_PRIVATE, new ArrayList<String>()); isAudience = false; for (String id : usermemberships) { for (String audien : audiences) { if (id.equals(audien)) { isAudience = true; break; } } if (isAudience) break; } if (!isAudience) categoryList.add(cat.getName()); } catch (Exception e) { log.error("Failed to check audience ", e); } } else { categoryList.add(iter.nextNode().getName()); } } } catch (Exception e) { log.error("Failed to get restricte category: ", e); } finally { sessionProvider.close(); } return categoryList; } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#getAllQuestions() */ public QuestionPageList getAllQuestions() throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { Node categoryHome = getCategoryHome(sProvider, null); QueryManager qm = categoryHome.getSession().getWorkspace().getQueryManager(); StringBuffer queryString = new StringBuffer(JCR_ROOT).append(categoryHome.getPath()).append("//element(*,exo:faqQuestion)["); List<String> listIds = getViewableCategoryIds(sProvider); for (int i = 0; i < listIds.size(); i++) { if (i > 0) queryString.append(" or "); queryString.append("(exo:categoryId='").append(listIds.get(i)).append("')"); } queryString.append("]order by @exo:createdDate ascending"); Query query = qm.createQuery(queryString.toString(), Query.XPATH); QueryResult result = query.execute(); QuestionPageList pageList = new QuestionPageList(result.getNodes(), 10, queryString.toString(), true); return pageList; } catch (Exception e) { log.error("Failed to get all questions: ", e); } finally { sProvider.close(); } return null; } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#getQuestionsNotYetAnswer(java.lang.String, boolean) */ public QuestionPageList getQuestionsNotYetAnswer(String categoryId, boolean isApproved) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { Node categoryHome = getCategoryHome(sProvider, null); QueryManager qm = categoryHome.getSession().getWorkspace().getQueryManager(); String qr = EMPTY_STR; boolean isOpenQs = false; if (categoryId.indexOf(" ") > 0) { String[] strs = categoryId.split(" "); categoryId = strs[0]; if (strs.length == 3) { qr = strs[1]; isOpenQs = Boolean.parseBoolean(strs[2]); } else { isOpenQs = Boolean.parseBoolean(strs[1]); } } StringBuffer queryString = new StringBuffer(JCR_ROOT).append(categoryHome.getPath()).append("//element(*,exo:faqQuestion)["); if (categoryId.equals(Utils.ALL)) { List<String> listIds = getViewableCategoryIds(sProvider); for (int i = 0; i < listIds.size(); i++) { if (i > 0) queryString.append(" or "); queryString.append("(exo:categoryId='").append(listIds.get(i)).append("')"); } } else { queryString.append("((@exo:categoryId='").append(categoryId).append("')").append((categoryId.indexOf("/") > 0) ? (" or (@exo:categoryId='" + categoryId.substring(categoryId.lastIndexOf("/") + 1) + "'))") : ")"); } if (isApproved) queryString.append(" and (@exo:isApproved='true')"); if (qr.length() > 0) queryString.append(" and ((@exo:isApproved='true') or ").append(qr).append(")"); queryString.append("] order by @exo:createdDate ascending"); Query query = qm.createQuery(queryString.toString(), Query.XPATH); QueryResult result = query.execute(); QuestionPageList pageList = new QuestionPageList(result.getNodes(), 10, queryString.toString(), true); pageList.setNotYetAnswered(true); pageList.setOpenQuestion(isOpenQs); return pageList; } catch (Exception e) { log.error("Get question not yet answer failed: ", e); } finally { sProvider.close(); } return null; } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#getPendingQuestionsByCategory(java.lang.String, org.exoplatform.faq.service.FAQSetting) */ public QuestionPageList getPendingQuestionsByCategory(String categoryId, FAQSetting faqSetting) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { Node categoryHome = getCategoryHome(sProvider, null); QueryManager qm = categoryHome.getSession().getWorkspace().getQueryManager(); StringBuffer queryString = null; if (categoryId == null || categoryId.trim().length() < 1) categoryId = "null"; queryString = new StringBuffer(JCR_ROOT).append(categoryHome.getPath()) .append("//element(*,") .append(EXO_FAQ_QUESTION) .append(")[((") .append(AT) .append(EXO_CATEGORY_ID) .append("='") .append(categoryId) .append("')") .append((categoryId.indexOf("/") > 0) ? (" or (" + AT + EXO_CATEGORY_ID + "='" + categoryId.substring(categoryId.lastIndexOf("/") + 1) + "'))") : ")") .append(" and (") .append(AT) .append(EXO_IS_ACTIVATED) .append("='true') and (") .append(AT) .append(EXO_IS_APPROVED) .append("='false')]"); queryString.append("order by ").append(Utils.getOderBy(faqSetting)); Query query = qm.createQuery(queryString.toString(), Query.XPATH); QueryResult result = query.execute(); QuestionPageList pageList = new QuestionPageList(result.getNodes(), 10, queryString.toString(), true); return pageList; } catch (Exception e) { log.error("Get pedding question through category failed: ", e); } finally { sProvider.close(); } return null; } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#getQuestionsByCatetory(java.lang.String, org.exoplatform.faq.service.FAQSetting) */ public QuestionPageList getQuestionsByCatetory(String categoryId, FAQSetting faqSetting) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { String id; Node categoryNode; if (categoryId == null || Utils.CATEGORY_HOME.equals(categoryId)) { id = Utils.CATEGORY_HOME; categoryId = Utils.CATEGORY_HOME; categoryNode = getCategoryHome(sProvider, null); } else { id = categoryId.substring(categoryId.lastIndexOf("/") + 1); categoryNode = getFAQServiceHome(sProvider).getNode(categoryId); } categoryNode = getFAQServiceHome(sProvider).getNode(categoryId); QueryManager qm = categoryNode.getSession().getWorkspace().getQueryManager(); String userId = faqSetting.getCurrentUser(); StringBuffer queryString = new StringBuffer(JCR_ROOT).append(categoryNode.getPath()).append("/").append(Utils.QUESTION_HOME).append("/element(*,exo:faqQuestion)[(@exo:categoryId='").append(id).append("') and (@exo:isActivated='true')"); if (!faqSetting.isCanEdit()) { queryString.append(" and (@exo:isApproved='true'"); if (userId != null && userId.length() > 0 && faqSetting.getDisplayMode().equals("both")) { queryString.append(" or @exo:author='").append(userId).append("')"); } else { queryString.append(")"); } } else { if (faqSetting.getDisplayMode().equals("approved")) { queryString.append(" and (@exo:isApproved='true')"); } } queryString.append("] order by ").append(Utils.getOderBy(faqSetting)); Query query = qm.createQuery(queryString.toString(), Query.XPATH); QueryResult result = query.execute(); QuestionPageList pageList = new QuestionPageList(result.getNodes(), 10, queryString.toString(), true); return pageList; } catch (Exception e) { log.debug("Getting question through category failed: ", e); } finally { sProvider.close(); } return null; } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#getAllQuestionsByCatetory(java.lang.String, org.exoplatform.faq.service.FAQSetting) */ public QuestionPageList getAllQuestionsByCatetory(String categoryId, FAQSetting faqSetting) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { Node categoryHome = getCategoryHome(sProvider, null); QueryManager qm = categoryHome.getSession().getWorkspace().getQueryManager(); StringBuffer queryString = null; if (faqSetting.getDisplayMode().equals("approved")) { queryString = new StringBuffer(JCR_ROOT).append(categoryHome.getPath()).append("//element(*,exo:faqQuestion)[(@exo:categoryId='").append(categoryId).append("')").append(" and (@exo:isApproved='true')").append("]"); } else { queryString = new StringBuffer(JCR_ROOT).append(categoryHome.getPath()).append("//element(*,exo:faqQuestion)[@exo:categoryId='").append(categoryId).append("'").append("]"); } queryString.append("order by ").append(Utils.getOderBy(faqSetting)); Query query = qm.createQuery(queryString.toString(), Query.XPATH); QueryResult result = query.execute(); QuestionPageList pageList = new QuestionPageList(result.getNodes(), 10, queryString.toString(), true); return pageList; } catch (Exception e) { log.debug("Failed to get all question through category: ", e); } finally { sProvider.close(); } return null; } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#getQuestionsByListCatetory(java.util.List, boolean) */ public QuestionPageList getQuestionsByListCatetory(List<String> listCategoryId, boolean isNotYetAnswer) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { Node categoryHome = getCategoryHome(sProvider, null); QueryManager qm = categoryHome.getSession().getWorkspace().getQueryManager(); StringBuffer queryString = new StringBuffer(JCR_ROOT).append(categoryHome.getPath()).append("//element(*,exo:faqQuestion) ["); queryString.append(" ("); int i = 0; for (String categoryId : listCategoryId) { if (i > 0) queryString.append(" or "); queryString.append("(@exo:categoryId='").append(categoryId).append("')"); i++; } queryString.append(")]"); queryString.append(" order by @exo:createdDate ascending"); Query query = qm.createQuery(queryString.toString(), Query.XPATH); QueryResult result = query.execute(); QuestionPageList pageList = null; pageList = new QuestionPageList(result.getNodes(), 10, queryString.toString(), true); pageList.setNotYetAnswered(isNotYetAnswer); return pageList; } catch (Exception e) { log.debug("Failed get questions through list of category: ", e); } finally { sProvider.close(); } return null; } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#getQuickQuestionsByListCatetory(java.util.List, boolean) */ public List<Question> getQuickQuestionsByListCatetory(List<String> listCategoryId, boolean isNotYetAnswer) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); List<Question> questions = new ArrayList<Question>(); try { Node categoryHome = getCategoryHome(sProvider, null); QueryManager qm = categoryHome.getSession().getWorkspace().getQueryManager(); StringBuffer queryString = new StringBuffer(JCR_ROOT).append(categoryHome.getPath()).append("//element(*,exo:faqQuestion)[("); int i = 0; for (String categoryId : listCategoryId) { if (i > 0) queryString.append(" or "); queryString.append("(@exo:categoryId='").append(categoryId).append("')"); i++; } queryString.append(")]order by @exo:createdDate ascending"); Query query = qm.createQuery(queryString.toString(), Query.XPATH); QueryResult result = query.execute(); NodeIterator iter = result.getNodes(); while (iter.hasNext()) { questions.add(getQuickQuestion(iter.nextNode())); } } catch (Exception e) { log.debug("Getting quick questions through list of category failed: ", e); } finally { sProvider.close(); } return questions; } private Question getQuickQuestion(Node questionNode) throws Exception { Question question = new Question(); question.setId(questionNode.getName()); PropertyReader reader = new PropertyReader(questionNode); question.setCategoryId(reader.string(EXO_CATEGORY_ID, EMPTY_STR)); String path = questionNode.getPath(); question.setPath(path.substring(path.indexOf(Utils.FAQ_APP) + Utils.FAQ_APP.length() + 1)); question.setQuestion(reader.string(EXO_TITLE, EMPTY_STR)); question.setApproved(reader.bool(EXO_IS_APPROVED)); return question; } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#getCategoryPathOfQuestion(java.lang.String) */ public String getCategoryPathOfQuestion(String questionPath) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); String path = EMPTY_STR; Node faqHome = null; try { faqHome = getFAQServiceHome(sProvider); Node question = faqHome.getNode(questionPath); Node subCat = question.getParent().getParent(); String pathName = EMPTY_STR; while (!subCat.getName().equals(Utils.CATEGORY_HOME)) { pathName = "/" + subCat.getProperty(EXO_NAME).getString() + pathName; subCat = subCat.getParent(); } try { pathName = faqHome.getProperty(EXO_NAME).getString() + pathName; } catch (Exception e) { pathName = "home" + pathName; } } catch (Exception e) { log.debug("Getting category path of the question failed: ", e); } finally { sProvider.close(); } return path; } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#moveQuestions(java.util.List, java.lang.String) */ public void moveQuestions(List<String> questions, String destCategoryId, String questionLink, FAQSetting faqSetting) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { Node faqHome = getFAQServiceHome(sProvider); String homePath = faqHome.getPath(); Node destQuestionHome; try { destQuestionHome = (Node) faqHome.getNode(destCategoryId + "/" + Utils.QUESTION_HOME); } catch (Exception e) { destQuestionHome = faqHome.getNode(destCategoryId).addNode(Utils.QUESTION_HOME, EXO_FAQ_QUESTION_HOME); faqHome.getSession().save(); } for (String id : questions) { try { Node destCateNode = faqHome.getNode(id).getParent(); faqHome.getSession().move(homePath + "/" + id, destQuestionHome.getPath() + id.substring(id.lastIndexOf("/"))); faqHome.getSession().save(); Node questionNode = faqHome.getNode(destCategoryId + "/" + Utils.QUESTION_HOME + id.substring(id.lastIndexOf("/"))); String catId = destCategoryId.substring(destCategoryId.lastIndexOf("/") + 1); questionNode.setProperty(EXO_CATEGORY_ID, catId); NodeIterator iter = questionNode.getNodes(); Node attNode; while (iter.hasNext()) { attNode = iter.nextNode(); if (attNode.isNodeType(EXO_FAQ_ATTACHMENT)) { attNode.getNode(JCR_CONTENT).setProperty(EXO_CATEGORY_ID, catId); } } updateDatas(questionNode, catId, true); updateDatas(questionNode, catId, false); questionNode.save(); try { sendNotifyMoveQuestion(destCateNode, questionNode, catId, questionLink, faqSetting); } catch (Exception e) { } } catch (ItemNotFoundException ex) { } } } catch (Exception e) { log.error("Failed to remove question: ", e); } finally { sProvider.close(); } } private void sendNotifyMoveQuestion(Node destCateNode, Node questionNode, String cateId, String link, FAQSetting faqSetting) throws Exception { String contentMail = faqSetting.getEmailMoveQuestion(); String categoryName = null; try { categoryName = questionNode.getParent().getParent().getProperty(EXO_NAME).getString(); } catch (Exception e) { categoryName = "Root"; } Message message = new Message(); message.setMimeType(MIMETYPE_TEXTHTML); message.setFrom(questionNode.getProperty(EXO_AUTHOR).getString()); message.setSubject(faqSetting.getEmailSettingSubject() + ": " + questionNode.getProperty(EXO_TITLE).getString()); if (categoryName == null || categoryName.trim().length() < 1) categoryName = "Root"; String questionDetail = questionNode.getProperty(EXO_TITLE).getString(); if (questionNode.hasProperty(EXO_NAME)) { questionDetail = questionDetail + "<br/> <span style=\"font-weight:normal\"> " + questionNode.getProperty(EXO_NAME).getString() + "</span>"; } contentMail = StringUtils.replace(contentMail, "&questionContent_", questionDetail); contentMail = StringUtils.replace(contentMail, "&categoryName_", categoryName); contentMail = StringUtils.replace(contentMail, "&questionLink_", link); message.setBody(contentMail); Set<String> emails = new HashSet<String>(); emails.addAll(calculateMoveEmail(destCateNode)); emails.addAll(calculateMoveEmail(questionNode.getParent())); emails.add(questionNode.getProperty(EXO_EMAIL).getString()); sendEmailNotification(new ArrayList<String>(emails), message); } private Set<String> calculateMoveEmail(Node node) throws Exception { Set<String> set = new HashSet<String>(); while (!node.getName().equals(Utils.CATEGORY_HOME)) { if (node.isNodeType(EXO_FAQ_WATCHING)) { set.addAll(new PropertyReader(node).list(EXO_EMAIL_WATCHING, new ArrayList<String>())); } node = node.getParent(); } return set; } private void updateDatas(Node question, String catId, boolean isAnswer) throws Exception { try { QueryManager qm = question.getSession().getWorkspace().getQueryManager(); StringBuffer queryString = new StringBuffer(JCR_ROOT).append(question.getPath()).append("//element(*,").append((isAnswer) ? EXO_ANSWER : EXO_COMMENT).append(")"); Query query = qm.createQuery(queryString.toString(), Query.XPATH); QueryResult result = query.execute(); NodeIterator iter = result.getNodes(); while (iter.hasNext()) { iter.nextNode().setProperty(EXO_CATEGORY_ID, catId); } } catch (Exception e) { log.error((isAnswer) ? "Updating answers failed: " : "Updating comments failed: ", e); } } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#changeStatusCategoryView(java.util.List) */ public void changeStatusCategoryView(List<String> listCateIds) throws Exception { if (listCateIds == null || listCateIds.size() < 1) return; SessionProvider sProvider = SessionProvider.createSystemProvider(); try { Node faqHome = getFAQServiceHome(sProvider); Node cat; for (String id : listCateIds) { cat = faqHome.getNode(id); cat.setProperty(EXO_IS_VIEW, !cat.getProperty(EXO_IS_VIEW).getBoolean()); } faqHome.save(); } catch (Exception e) { log.error("Changing status category view failed: ", e); } finally { sProvider.close(); } } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#getMaxindexCategory(java.lang.String) */ public long getMaxindexCategory(String parentId) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); long max = 0; try { NodeIterator iter = getFAQServiceHome(sProvider).getNode((parentId == null) ? Utils.CATEGORY_HOME : parentId).getNodes(); while (iter.hasNext()) { Node node = iter.nextNode(); if (node.isNodeType(EXO_FAQ_CATEGORY)) max = max + 1; } } catch (Exception e) { log.error("Failed to get max index category", e); } finally { sProvider.close(); } return max; } private void saveCategory(Node categoryNode, Category category, boolean isNew, SessionProvider sProvider) throws Exception { Map<String, String> moderators = new HashMap<String, String>(); if (!categoryNode.getName().equals(Utils.CATEGORY_HOME)) { Node parentCategory = categoryNode.getParent(); if (parentCategory.hasProperty(EXO_MODERATORS)) { for (Value vl : parentCategory.getProperty(EXO_MODERATORS).getValues()) { moderators.put(vl.getString(), vl.getString()); } } } if (category.getId() != null) { categoryNode.setProperty(EXO_ID, category.getId()); categoryNode.setProperty(EXO_CREATED_DATE, GregorianCalendar.getInstance()); categoryNode.setProperty(EXO_IS_VIEW, category.isView()); } categoryNode.setProperty(EXO_INDEX, category.getIndex()); categoryNode.setProperty(EXO_NAME, category.getName()); categoryNode.setProperty(EXO_DESCRIPTION, category.getDescription()); for (String mod : category.getModerators()) { moderators.put(mod, mod); } categoryNode.setProperty(EXO_MODERATORS, moderators.values().toArray(new String[] {})); categoryNode.setProperty(EXO_IS_MODERATE_QUESTIONS, category.isModerateQuestions()); categoryNode.setProperty(EXO_VIEW_AUTHOR_INFOR, category.isViewAuthorInfor()); categoryNode.setProperty(EXO_IS_MODERATE_ANSWERS, category.isModerateAnswers()); categoryNode.setProperty(EXO_USER_PRIVATE, category.getUserPrivate()); if (!isNew) { try { updateModeratorForChildCategories(categoryNode, moderators); } catch (Exception e) { log.debug("Updating moderator for child category failed: ", e); } } if (categoryNode.isNew()) categoryNode.getSession().save(); else categoryNode.save(); } private void updateModeratorForChildCategories(Node currentCategory, Map<String, String> moderators) throws Exception { Map<String, String> modMap = new HashMap<String, String>(); Node cat; NodeIterator iter = currentCategory.getNodes(); while (iter.hasNext()) { cat = iter.nextNode(); if (cat.isNodeType(EXO_FAQ_CATEGORY)) { modMap.clear(); modMap.putAll(moderators); for (Value vl : cat.getProperty(EXO_MODERATORS).getValues()) { modMap.put(vl.getString(), vl.getString()); } cat.setProperty(EXO_MODERATORS, modMap.values().toArray(new String[] {})); cat.save(); if (cat.hasNodes()) { updateModeratorForChildCategories(cat, modMap); } } } } private void resetIndex(Node category, long index) throws Exception { QueryManager qm = category.getSession().getWorkspace().getQueryManager(); Node parent = category.getParent(); StringBuffer queryString = new StringBuffer(JCR_ROOT + parent.getPath()); queryString.append("/element(*,exo:faqCategory)order by @exo:index ascending, @exo:dateModified descending"); Query query = qm.createQuery(queryString.toString(), Query.XPATH); QueryResult result = query.execute(); NodeIterator iter = result.getNodes(); if (iter.getSize() >= index) { long i = 1; Node cat; while (iter.hasNext()) { cat = iter.nextNode(); cat.setProperty(EXO_INDEX, i); i++; } parent.save(); } } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#saveCategory(java.lang.String, org.exoplatform.faq.service.Category, boolean) */ public void saveCategory(String parentId, Category cat, boolean isAddNew) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { Node newCategory; if (isAddNew) { Node parentNode = getFAQServiceHome(sProvider).getNode(parentId); newCategory = parentNode.addNode(cat.getId(), EXO_FAQ_CATEGORY); newCategory.addMixin(MIX_FAQ_SUB_CATEGORY); newCategory.addNode(Utils.QUESTION_HOME, EXO_FAQ_QUESTION_HOME); newCategory.getSession().save(); } else { newCategory = getFAQServiceHome(sProvider).getNode(cat.getPath()); } saveCategory(newCategory, cat, isAddNew, sProvider); resetIndex(newCategory, cat.getIndex()); } catch (Exception e) { log.error("Failed to save category: ", e); } finally { sProvider.close(); } } private List<Cate> listingSubTree(Node currentCategory, int i) throws Exception { Node cat; int j = i; j = j + 1; List<Cate> cateList = new ArrayList<Cate>(); Cate cate; NodeIterator iter = currentCategory.getNodes(); while (iter.hasNext()) { cat = iter.nextNode(); if (cat.isNodeType(EXO_FAQ_CATEGORY)) { cate = new Cate(); cate.setCategory(getCategory(cat)); cate.setDeft(i); cateList.add(cate); if (cat.hasNodes()) { cateList.addAll(listingSubTree(cat, j)); ; } } } return cateList; } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#listingCategoryTree() */ public List<Cate> listingCategoryTree() throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { Node cateHome = getCategoryHome(sProvider, null); int i = 1; List<Cate> cateList = new ArrayList<Cate>(); cateList.addAll(listingSubTree(cateHome, i)); return cateList; } finally { sProvider.close(); } } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#removeCategory(java.lang.String) */ public void removeCategory(String categoryId) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { Node faqHome = getFAQServiceHome(sProvider); faqHome.getNode(categoryId).remove(); faqHome.save(); } catch (Exception e) { log.error("Can not remove category has id: " + categoryId); } finally { sProvider.close(); } } private Category getCategory(Node categoryNode) throws Exception { if (categoryNode == null) return null; Category category = new Category(); PropertyReader reader = new PropertyReader(categoryNode); category.setId(categoryNode.getName()); category.setName(reader.string(EXO_NAME, EMPTY_STR)); category.setDescription(reader.string(EXO_DESCRIPTION, EMPTY_STR)); category.setCreatedDate(reader.date(EXO_CREATED_DATE)); category.setModerators(reader.strings(EXO_MODERATORS, new String[] {})); category.setUserPrivate(reader.strings(EXO_USER_PRIVATE, new String[] {})); category.setModerateQuestions(reader.bool(EXO_IS_MODERATE_QUESTIONS)); category.setModerateAnswers(reader.bool(EXO_IS_MODERATE_ANSWERS)); category.setViewAuthorInfor(reader.bool(EXO_VIEW_AUTHOR_INFOR)); category.setIndex(reader.l(EXO_INDEX, 1)); category.setView(reader.bool(EXO_IS_VIEW, true)); String path = categoryNode.getPath(); category.setPath(path.substring(path.indexOf(Utils.FAQ_APP) + Utils.FAQ_APP.length() + 1)); return category; } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#getCategoryById(java.lang.String) */ public Category getCategoryById(String categoryId) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { return getCategory(getCategoryNodeById(sProvider, categoryId)); } catch (Exception e) { log.debug("Category not found " + categoryId); } finally { sProvider.close(); } return null; } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#findCategoriesByName(java.lang.String) */ public List<Category> findCategoriesByName(String categoryName) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { Node categoryHome = getCategoryHome(sProvider, null); QueryManager qm = categoryHome.getSession().getWorkspace().getQueryManager(); StringBuffer queryString = new StringBuffer(JCR_ROOT).append(categoryHome.getPath()).append("//element(*,exo:faqCategory)[@exo:name='").append(categoryName).append("']"); Query query = qm.createQuery(queryString.toString(), Query.XPATH); QueryResult queryResult = query.execute(); NodeIterator iter = queryResult.getNodes(); List<Category> result = new ArrayList<Category>(); while (iter.hasNext()) { result.add(getCategory(iter.nextNode())); } return result; } catch (Exception e) { log.error("Could not retrieve categories by name " + categoryName, e); } finally { sProvider.close(); } return null; } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#getListCateIdByModerator(java.lang.String) */ public List<String> getListCateIdByModerator(String user) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { Node categoryHome = getCategoryHome(sProvider, null); QueryManager qm = categoryHome.getSession().getWorkspace().getQueryManager(); StringBuffer queryString = new StringBuffer(JCR_ROOT).append(categoryHome.getParent().getPath()).append("//element(*,exo:faqCategory)[@exo:moderators='").append(user.trim()).append("'").append(" and @exo:isView='true' ]"); Query query = qm.createQuery(queryString.toString(), Query.XPATH); QueryResult result = query.execute(); NodeIterator iter = result.getNodes(); List<String> listCateId = new ArrayList<String>(); while (iter.hasNext()) { Node cate = iter.nextNode(); try { listCateId.add(cate.getName() + cate.getProperty(EXO_NAME).getString()); } catch (Exception e) { log.debug("Getting property of " + cate + " node failed: ", e); } } return listCateId; } catch (Exception e) { log.error("Failed to get list of CateID through Moderator: ", e); } finally { sProvider.close(); } return null; } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#getAllCategories() */ public List<Category> getAllCategories() throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { Node categoryHome = getCategoryHome(sProvider, null); QueryManager qm = categoryHome.getSession().getWorkspace().getQueryManager(); StringBuffer queryString = new StringBuffer(JCR_ROOT).append(categoryHome.getPath()).append("//element(*,exo:faqCategory)"); Query query = qm.createQuery(queryString.toString(), Query.XPATH); QueryResult result = query.execute(); NodeIterator iter = result.getNodes(); List<Category> catList = new ArrayList<Category>(); while (iter.hasNext()) { catList.add(getCategory(iter.nextNode())); } return catList; } catch (Exception e) { log.error("Getting all category failed: ", e); } finally { sProvider.close(); } return null; } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#existingCategories() */ public long existingCategories() throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { Node categoryHome = getCategoryHome(sProvider, null); QueryManager qm = categoryHome.getSession().getWorkspace().getQueryManager(); StringBuffer queryString = new StringBuffer(JCR_ROOT).append(categoryHome.getPath()).append("//element(*,exo:faqCategory)"); Query query = qm.createQuery(queryString.toString(), Query.XPATH); QueryResult result = query.execute(); result.getNodes().getSize(); } catch (Exception e) { log.error("Failed to check existing categories", e); } finally { sProvider.close(); } return 0; } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#getCategoryNodeById(java.lang.String) */ public Node getCategoryNodeById(String categoryId) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { return getCategoryNodeById(sProvider, categoryId); } catch (Exception e) { log.error("Getting node failed: ", e); } finally { sProvider.close(); } return null; } private Node getCategoryNodeById(SessionProvider sProvider, String categoryId) throws Exception { try { Node faqHome = getFAQServiceHome(sProvider); return faqHome.getNode(categoryId); } catch (PathNotFoundException e) { Node categoryHome = getCategoryHome(sProvider, null); QueryManager qm = categoryHome.getSession().getWorkspace().getQueryManager(); StringBuffer queryString = new StringBuffer(JCR_ROOT).append(categoryHome.getPath()).append("//element(*,exo:faqCategory)").append("[fn:name()='").append(categoryId).append("']"); Query query = qm.createQuery(queryString.toString(), Query.XPATH); QueryResult result = query.execute(); NodeIterator iter = result.getNodes(); if (iter.getSize() != 0) return iter.nextNode(); } return null; } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#getSubCategories(java.lang.String, org.exoplatform.faq.service.FAQSetting, boolean, java.util.List) */ public List<Category> getSubCategories(String categoryId, FAQSetting faqSetting, boolean isGetAll, List<String> limitedUsers) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); List<Category> catList = new ArrayList<Category>(); try { Node parentCategory; if (categoryId == null || categoryId.equals(Utils.CATEGORY_HOME)) { parentCategory = getCategoryHome(sProvider, null); } else parentCategory = getFAQServiceHome(sProvider).getNode(categoryId); if (!faqSetting.isAdmin()) { PropertyReader reader = new PropertyReader(parentCategory); List<String> userPrivates = reader.list(EXO_USER_PRIVATE, new ArrayList<String>()); if (!userPrivates.isEmpty() && !Utils.hasPermission(limitedUsers, userPrivates)) return catList; } StringBuffer queryString = new StringBuffer(JCR_ROOT).append(parentCategory.getPath()); if (faqSetting.isAdmin()) queryString.append("/element(*,exo:faqCategory) [@exo:isView='true'] order by @exo:index ascending"); else { queryString.append("/element(*,exo:faqCategory)[@exo:isView='true' and ( not(@exo:userPrivate) or @exo:userPrivate=''"); if (limitedUsers != null) { for (String id : limitedUsers) { queryString.append(" or @exo:userPrivate = '").append(id).append("' "); queryString.append(" or @exo:moderators = '").append(id).append("' "); } } queryString.append(" )] order by @exo:index"); } QueryManager qm = parentCategory.getSession().getWorkspace().getQueryManager(); String qString = queryString.toString(); Query query = qm.createQuery(qString, Query.XPATH); QueryResult result = query.execute(); NodeIterator iter = result.getNodes(); while (iter.hasNext()) { catList.add(getCategory(iter.nextNode())); } } catch (Exception e) { throw e; } finally { sProvider.close(); } return catList; } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#getCategoryInfo(java.lang.String, org.exoplatform.faq.service.FAQSetting) */ public long[] getCategoryInfo(String categoryId, FAQSetting faqSetting) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); long[] cateInfo = new long[] { 0, 0, 0, 0 };// categories, all, open, pending try { Node parentCategory; String id; parentCategory = getFAQServiceHome(sProvider).getNode(categoryId); if (categoryId.indexOf("/") > 0) id = categoryId.substring(categoryId.lastIndexOf("/") + 1); else id = categoryId; NodeIterator iter = parentCategory.getNodes(); cateInfo[0] = iter.getSize(); QueryManager qm = parentCategory.getSession().getWorkspace().getQueryManager(); StringBuffer queryString = new StringBuffer(JCR_ROOT).append(parentCategory.getPath()).append("//element(*,exo:faqQuestion)[(@exo:categoryId='").append(id).append("') and (@exo:isActivated='true')").append("]").append("order by @exo:createdDate ascending"); // System.out.println("Infor queryString ==> " + queryString); Query query = qm.createQuery(queryString.toString(), Query.XPATH); QueryResult result = query.execute(); NodeIterator nodeIterator = result.getNodes(); cateInfo[1] = nodeIterator.getSize();// all Node questionNode = null; boolean onlyGetApproved, questionIsApproved = true, isShow = true; onlyGetApproved = (faqSetting.getDisplayMode().equals("approved")); while (nodeIterator.hasNext()) { questionNode = nodeIterator.nextNode(); questionIsApproved = questionNode.getProperty(EXO_IS_APPROVED).getBoolean(); isShow = (questionIsApproved || ((faqSetting.isCanEdit() || questionNode.getProperty(EXO_AUTHOR).getString().equals(faqSetting.getCurrentUser())) && !onlyGetApproved)); if (!questionIsApproved) { cateInfo[3]++;// pending if (!isShow) cateInfo[1]--; } if (isShow) { if (!hasAnswerInQuestion(qm, questionNode)) cateInfo[2]++;// open } } } catch (Exception e) { log.error("Failed to get category info: ", e); } finally { sProvider.close(); } return cateInfo; } private boolean hasAnswerInQuestion(QueryManager qm, Node questionNode) throws Exception { StringBuffer queryString = new StringBuffer(JCR_ROOT).append(questionNode.getPath()).append("//element(*,exo:answer)[(@exo:approveResponses='true') and (@exo:activateResponses='true')]"); Query query = qm.createQuery(queryString.toString(), Query.XPATH); QueryResult result = query.execute(); NodeIterator iter = result.getNodes(); return (iter.getSize() > 0) ? true : false; } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#moveCategory(java.lang.String, java.lang.String) */ public void moveCategory(String categoryId, String destCategoryId) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { Node faqHome = getFAQServiceHome(sProvider); Node srcNode = faqHome.getNode(categoryId); String srcPath = srcNode.getPath(); String destPath = faqHome.getPath() + "/" + destCategoryId + "/" + srcNode.getName(); faqHome.getSession().move(srcPath, destPath); faqHome.getSession().save(); Node destNode = faqHome.getNode(destCategoryId + "/" + srcNode.getName()); destNode.setProperty(EXO_INDEX, destNode.getParent().getNodes().getSize()); destNode.save(); // resetIndex(category, index) // Should be update moderators for moving category } catch (ItemExistsException e) { throw e; } catch (Exception e) { if (log.isDebugEnabled()) log.debug(e.getMessage()); } finally { sProvider.close(); } } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#addWatchCategory(java.lang.String, org.exoplatform.faq.service.Watch) */ public void addWatchCategory(String id, Watch watch) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { Node faqHome = getFAQServiceHome(sProvider); Map<String, String> watchs = new HashMap<String, String>(); Node watchingNode = faqHome.getNode(id); ; if (watchingNode.isNodeType(EXO_FAQ_WATCHING)) { Value[] emails = watchingNode.getProperty(EXO_EMAIL_WATCHING).getValues(); Value[] users = watchingNode.getProperty(EXO_USER_WATCHING).getValues(); if (emails != null && users != null) { for (int i = 0; i < users.length; i++) { watchs.put(users[i].getString(), emails[i].getString()); } } watchs.put(watch.getUser(), watch.getEmails()); watchingNode.setProperty(EXO_EMAIL_WATCHING, watchs.values().toArray(new String[] {})); watchingNode.setProperty(EXO_USER_WATCHING, watchs.keySet().toArray(new String[] {})); } else { watchingNode.addMixin(EXO_FAQ_WATCHING); watchingNode.setProperty(EXO_EMAIL_WATCHING, new String[] { watch.getEmails() }); watchingNode.setProperty(EXO_USER_WATCHING, new String[] { watch.getUser() }); } watchingNode.save(); } catch (Exception e) { log.error("Failed to add watch category: ", e); } finally { sProvider.close(); } } // TODO Going to remove /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#getListMailInWatch(java.lang.String) */ public QuestionPageList getListMailInWatch(String categoryId) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { Node categoryHome = getCategoryHome(sProvider, null); QueryManager qm = categoryHome.getSession().getWorkspace().getQueryManager(); StringBuffer queryString = new StringBuffer(JCR_ROOT).append(categoryHome.getPath()).append("//element(*,exo:faqCategory)[@exo:id='").append(categoryId).append("']"); Query query = qm.createQuery(queryString.toString(), Query.XPATH); QueryResult result = query.execute(); QuestionPageList pageList = new QuestionPageList(result.getNodes(), 5, queryString.toString(), true); return pageList; } catch (Exception e) { log.error("Failed to get list of mail watch: ", e); } finally { sProvider.close(); } return null; } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#getWatchByCategory(java.lang.String) */ public List<Watch> getWatchByCategory(String categoryId) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); List<Watch> listWatches = new ArrayList<Watch>(); try { Node category = getFAQServiceHome(sProvider).getNode(categoryId); if (category.isNodeType(EXO_FAQ_WATCHING)) { PropertyReader reader = new PropertyReader(category); String[] userWatch = reader.strings(EXO_EMAIL_WATCHING); String[] emails = reader.strings(EXO_USER_WATCHING); if (userWatch != null && userWatch.length > 0) { Watch watch; for (int i = 0; i < userWatch.length; i++) { watch = new Watch(); watch.setEmails(emails[i]); watch.setUser(userWatch[i]); listWatches.add(watch); } } } return listWatches; } catch (Exception e) { log.error("Failed to get watch through category: ", e); } finally { sProvider.close(); } return listWatches; } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#hasWatch(java.lang.String) */ public boolean hasWatch(String categoryPath) { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { Node cat = getFAQServiceHome(sProvider).getNode(categoryPath); if (new PropertyReader(cat).strings(EXO_USER_WATCHING, new String[] {}).length > 0) return true; } catch (Exception e) { log.error("Failed to check has watch", e); } finally { sProvider.close(); } return false; } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#addWatchQuestion(java.lang.String, org.exoplatform.faq.service.Watch, boolean) */ public void addWatchQuestion(String questionId, Watch watch, boolean isNew) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); Map<String, String> watchMap = new HashMap<String, String>(); try { Node questionNode = getFAQServiceHome(sProvider).getNode(questionId); if (questionNode.isNodeType(EXO_FAQ_WATCHING)) { Value[] values = questionNode.getProperty(EXO_EMAIL_WATCHING).getValues(); Value[] users = questionNode.getProperty(EXO_USER_WATCHING).getValues(); for (int i = 0; i < users.length; i++) { watchMap.put(users[i].getString(), values[i].getString()); } watchMap.put(watch.getUser(), watch.getEmails()); questionNode.setProperty(EXO_EMAIL_WATCHING, watchMap.values().toArray(new String[] {})); questionNode.setProperty(EXO_USER_WATCHING, watchMap.keySet().toArray(new String[] {})); questionNode.save(); } else { questionNode.addMixin(EXO_FAQ_WATCHING); questionNode.setProperty(EXO_EMAIL_WATCHING, new String[] { watch.getEmails() }); questionNode.setProperty(EXO_USER_WATCHING, new String[] { watch.getUser() }); questionNode.save(); } // questionHome.save(); } catch (Exception e) { log.error("Failed to add a watch question: ", e); } finally { sProvider.close(); } } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#getWatchByQuestion(java.lang.String) */ public List<Watch> getWatchByQuestion(String questionId) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); List<Watch> listWatches = new ArrayList<Watch>(); try { Node quetionNode = getFAQServiceHome(sProvider).getNode(questionId); if (quetionNode.isNodeType(EXO_FAQ_WATCHING)) { PropertyReader reader = new PropertyReader(quetionNode); String[] userWatch = reader.strings(EXO_EMAIL_WATCHING); String[] emails = reader.strings(EXO_USER_WATCHING); if (userWatch != null && userWatch.length > 0) { Watch watch; for (int i = 0; i < userWatch.length; i++) { watch = new Watch(); watch.setEmails(emails[i]); watch.setUser(userWatch[i]); listWatches.add(watch); } } } } catch (Exception e) { log.error("Failed to get watch through question: ", e); } finally { sProvider.close(); } return listWatches; } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#getWatchedCategoryByUser(java.lang.String) */ public QuestionPageList getWatchedCategoryByUser(String userId) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { Node categoryHome = getCategoryHome(sProvider, null); QueryManager qm = categoryHome.getSession().getWorkspace().getQueryManager(); StringBuffer queryString = null; queryString = new StringBuffer(JCR_ROOT).append(categoryHome.getPath()).append("//element(*,exo:faqCategory)[(@exo:userWatching='").append(userId).append("')]"); Query query = qm.createQuery(queryString.toString(), Query.XPATH); QueryResult result = query.execute(); QuestionPageList pageList = new QuestionPageList(result.getNodes(), 10, queryString.toString(), true); return pageList; } catch (Exception e) { log.error("Failed to get watched category through user: ", e); } finally { sProvider.close(); } return null; } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#isUserWatched(java.lang.String, java.lang.String) */ public boolean isUserWatched(String userId, String cateId) { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { Node faqHome = getFAQServiceHome(sProvider); Node cate = faqHome.getNode(cateId); List<String> list = new PropertyReader(cate).list(EXO_USER_WATCHING, new ArrayList<String>()); for (String vl : list) { if (vl.equals(userId)) return true; } } catch (Exception e) { log.error("Failed to check user watched", e); } finally { sProvider.close(); } return false; } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#getWatchedSubCategory(java.lang.String, java.lang.String) */ public List<String> getWatchedSubCategory(String userId, String cateId) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); List<String> watchedSub = new ArrayList<String>(); try { Node faqHome = getFAQServiceHome(sProvider); Node category = faqHome.getNode(cateId); QueryManager qm = faqHome.getSession().getWorkspace().getQueryManager(); StringBuffer queryString = new StringBuffer(JCR_ROOT).append(category.getPath()).append("/element(*,exo:faqCategory)[(@exo:userWatching='").append(userId).append("')]"); Query query = qm.createQuery(queryString.toString(), Query.XPATH); QueryResult result = query.execute(); NodeIterator iter = result.getNodes(); while (iter.hasNext()) { watchedSub.add(iter.nextNode().getName()); } } catch (Exception e) { log.error("Getting watched sub category failed: ", e); } finally { sProvider.close(); } return watchedSub; } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#getListQuestionsWatch(org.exoplatform.faq.service.FAQSetting, java.lang.String) */ public QuestionPageList getListQuestionsWatch(FAQSetting faqSetting, String currentUser) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { Node categoryHome = getCategoryHome(sProvider, null); QueryManager qm = categoryHome.getSession().getWorkspace().getQueryManager(); StringBuffer queryString = new StringBuffer(JCR_ROOT).append(categoryHome.getPath()).append("//element(*,exo:faqQuestion)[(@exo:userWatching='").append(currentUser).append("')"); if (faqSetting.getDisplayMode().equals("approved")) { queryString.append(" and (@exo:isApproved='true')"); } if (!faqSetting.isAdmin()) queryString.append(" and (@exo:isActivated='true')"); queryString.append("] order by ").append(Utils.getOderBy(faqSetting)); Query query = qm.createQuery(queryString.toString(), Query.XPATH); QueryResult result = query.execute(); QuestionPageList pageList = new QuestionPageList(result.getNodes(), 10, queryString.toString(), true); return pageList; } catch (Exception e) { log.error("Failed to get list of question watch: ", e); } finally { sProvider.close(); } return null; } // Going to remove /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#deleteCategoryWatch(java.lang.String, java.lang.String) */ public void deleteCategoryWatch(String categoryId, String user) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { Node category = getFAQServiceHome(sProvider).getNode(categoryId); Map<String, String> emailMap = new HashMap<String, String>(); Value[] emailValues = category.getProperty(EXO_EMAIL_WATCHING).getValues(); Value[] userValues = category.getProperty(EXO_USER_WATCHING).getValues(); for (int i = 0; i < emailValues.length; i++) { emailMap.put(userValues[i].getString(), emailValues[i].getString()); } emailMap.remove(user); category.setProperty(EXO_USER_WATCHING, emailMap.keySet().toArray(new String[] {})); category.setProperty(EXO_EMAIL_WATCHING, emailMap.values().toArray(new String[] {})); category.save(); } catch (Exception e) { log.error("Failed to deleted category watch", e); } finally { sProvider.close(); } } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#unWatchCategory(java.lang.String, java.lang.String) */ public void unWatchCategory(String categoryId, String user) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { Node category = getFAQServiceHome(sProvider).getNode(categoryId); Map<String, String> userMap = new HashMap<String, String>(); Value[] emailValues = category.getProperty(EXO_EMAIL_WATCHING).getValues(); Value[] userValues = category.getProperty(EXO_USER_WATCHING).getValues(); for (int i = 0; i < userValues.length; i++) { userMap.put(userValues[i].getString(), emailValues[i].getString()); } userMap.remove(user); category.setProperty(EXO_EMAIL_WATCHING, userMap.values().toArray(new String[] {})); category.setProperty(EXO_USER_WATCHING, userMap.keySet().toArray(new String[] {})); category.save(); } catch (Exception e) { log.error("Failed to unWatch category", e); } finally { sProvider.close(); } } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#unWatchQuestion(java.lang.String, java.lang.String) */ public void unWatchQuestion(String questionId, String user) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { Node question = getFAQServiceHome(sProvider).getNode(questionId); Map<String, String> userMap = new HashMap<String, String>(); Value[] emailValues = question.getProperty(EXO_EMAIL_WATCHING).getValues(); Value[] userValues = question.getProperty(EXO_USER_WATCHING).getValues(); for (int i = 0; i < userValues.length; i++) { userMap.put(userValues[i].getString(), emailValues[i].getString()); } userMap.remove(user); question.setProperty(EXO_EMAIL_WATCHING, userMap.values().toArray(new String[] {})); question.setProperty(EXO_USER_WATCHING, userMap.keySet().toArray(new String[] {})); question.save(); } catch (Exception e) { log.error("Unwatching question failed: ", e); } finally { sProvider.close(); } } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#getSearchResults(org.exoplatform.faq.service.FAQEventQuery) */ public List<ObjectSearchResult> getSearchResults(FAQEventQuery eventQuery) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); eventQuery.setViewingCategories(getViewableCategoryIds(sProvider)); List<String> retrictedCategoryList = new ArrayList<String>(); if (!eventQuery.isAdmin()) retrictedCategoryList = getRetrictedCategories(eventQuery.getUserId(), eventQuery.getUserMembers()); Node categoryHome = getCategoryHome(sProvider, null); eventQuery.setPath(categoryHome.getPath()); try { QueryManager qm = categoryHome.getSession().getWorkspace().getQueryManager(); // System.out.println("Query ====>" + eventQuery.getQuery()); Query query = qm.createQuery(eventQuery.getQuery(), Query.XPATH); QueryResult result = query.execute(); NodeIterator iter = result.getNodes(); // System.out.println("size ====>" + iter.getSize()); Node nodeObj = null; if (eventQuery.getType().equals(FAQEventQuery.FAQ_CATEGORY)) { // Category search List<ObjectSearchResult> results = new ArrayList<ObjectSearchResult>(); while (iter.hasNext()) { if (eventQuery.isAdmin()) { Node cat = iter.nextNode(); // for retricted audiences if (retrictedCategoryList.size() > 0) { String path = cat.getPath(); for (String id : retrictedCategoryList) { if (path.indexOf(id) > 0) { results.add(getResultObj(cat)); break; } } } else { results.add(getResultObj(cat)); } } else { results.add(getResultObj(iter.nextNode())); } } return results; } else if (eventQuery.getType().equals(FAQEventQuery.FAQ_QUESTION)) { // Question search List<ObjectSearchResult> results = new ArrayList<ObjectSearchResult>(); Map<String, Node> mergeQuestion = new HashMap<String, Node>(); Map<String, Node> mergeQuestion2 = new HashMap<String, Node>(); List<Node> listQuestion = new ArrayList<Node>(); List<Node> listLanguage = new ArrayList<Node>(); Map<String, Node> listAnswerandComment = new HashMap<String, Node>(); while (iter.hasNext()) { nodeObj = iter.nextNode(); if (!eventQuery.isAdmin()) { try { if (nodeObj.isNodeType(EXO_FAQ_QUESTION)) { if ((nodeObj.getProperty(EXO_IS_APPROVED).getBoolean() == true && nodeObj.getProperty(EXO_IS_ACTIVATED).getBoolean() == true) || (nodeObj.getProperty(EXO_AUTHOR).getString().equals(eventQuery.getUserId()) && nodeObj.getProperty(EXO_IS_ACTIVATED).getBoolean() == true)) // for retricted audiences if (retrictedCategoryList.size() > 0) { String path = nodeObj.getPath(); boolean isCanView = true; for (String id : retrictedCategoryList) { if (path.indexOf(id) > 0) { isCanView = false; break; } } if (isCanView) listQuestion.add(nodeObj); } else { listQuestion.add(nodeObj); } } if (nodeObj.isNodeType(EXO_FAQ_RESOURCE)) { Node nodeQuestion = nodeObj.getParent().getParent(); if ((nodeQuestion.getProperty(EXO_IS_APPROVED).getBoolean() == true && nodeQuestion.getProperty(EXO_IS_ACTIVATED).getBoolean() == true) || (nodeQuestion.getProperty(EXO_AUTHOR).getString().equals(eventQuery.getUserId()) && nodeQuestion.getProperty(EXO_IS_ACTIVATED).getBoolean() == true)) // for retricted audiences if (retrictedCategoryList.size() > 0) { boolean isCanView = true; String path = nodeObj.getPath(); for (String id : retrictedCategoryList) { if (path.indexOf(id) > 0) { isCanView = false; break; } } if (isCanView) listQuestion.add(nodeQuestion); } else { listQuestion.add(nodeQuestion); } } if (nodeObj.isNodeType(EXO_FAQ_LANGUAGE)) { Node nodeQuestion = nodeObj.getParent().getParent(); if ((nodeQuestion.getProperty(EXO_IS_APPROVED).getBoolean() == true && nodeQuestion.getProperty(EXO_IS_ACTIVATED).getBoolean() == true) || (nodeQuestion.getProperty(EXO_AUTHOR).getString().equals(eventQuery.getUserId()) && nodeQuestion.getProperty(EXO_IS_ACTIVATED).getBoolean() == true)) // for retricted audiences if (retrictedCategoryList.size() > 0) { boolean isCanView = true; String path = nodeObj.getPath(); for (String id : retrictedCategoryList) { if (path.indexOf(id) > 0) { isCanView = false; break; } } if (isCanView) listLanguage.add(nodeObj); } else { listLanguage.add(nodeObj); } } if (nodeObj.isNodeType(EXO_ANSWER) || nodeObj.isNodeType(EXO_COMMENT)) { // answers of default language String quesId = nodeObj.getProperty(EXO_QUESTION_ID).getString(); if (!listAnswerandComment.containsKey(quesId)) { Node nodeQuestion = nodeObj.getParent().getParent(); if (nodeQuestion.isNodeType(EXO_FAQ_QUESTION)) { if ((nodeQuestion.getProperty(EXO_IS_APPROVED).getBoolean() == true && nodeQuestion.getProperty(EXO_IS_ACTIVATED).getBoolean() == true) || (nodeQuestion.getProperty(EXO_AUTHOR).getString().equals(eventQuery.getUserId()) && nodeQuestion.getProperty(EXO_IS_ACTIVATED).getBoolean() == true)) // for retricted audiences if (retrictedCategoryList.size() > 0) { boolean isCanView = true; String path = nodeObj.getPath(); for (String id : retrictedCategoryList) { if (path.indexOf(id) > 0) { isCanView = false; break; } } if (isCanView) listAnswerandComment.put(quesId, nodeObj); } else { listAnswerandComment.put(quesId, nodeObj); } } else { // answers of other languages nodeQuestion = nodeObj.getParent().getParent().getParent().getParent(); if ((nodeQuestion.getProperty(EXO_IS_APPROVED).getBoolean() == true && nodeQuestion.getProperty(EXO_IS_ACTIVATED).getBoolean() == true) || (nodeQuestion.getProperty(EXO_AUTHOR).getString().equals(eventQuery.getUserId()) && nodeQuestion.getProperty(EXO_IS_ACTIVATED).getBoolean() == true)) { // for retricted audiences if (retrictedCategoryList.size() > 0) { boolean isCanView = true; String path = nodeObj.getPath(); for (String id : retrictedCategoryList) { if (path.indexOf(id) > 0) { isCanView = false; break; } } if (isCanView) listAnswerandComment.put(quesId, nodeObj); } else { listAnswerandComment.put(quesId, nodeObj); } } } } } } catch (Exception e) { log.error("Failed to add item in list search", e); } } else { if (nodeObj.isNodeType(EXO_FAQ_QUESTION)) listQuestion.add(nodeObj); if (nodeObj.isNodeType(EXO_FAQ_RESOURCE)) listQuestion.add(nodeObj.getParent().getParent()); if (nodeObj.isNodeType(EXO_FAQ_LANGUAGE)) listLanguage.add(nodeObj); if (nodeObj.isNodeType(EXO_ANSWER) || nodeObj.isNodeType(EXO_COMMENT)) listAnswerandComment.put(nodeObj.getProperty(EXO_QUESTION_ID).getString(), nodeObj); } } boolean isInitiated = false; if (eventQuery.isQuestionLevelSearch()) { // directly return because there is only one this type of search if (!eventQuery.isLanguageLevelSearch() && !eventQuery.isAnswerCommentLevelSearch()) { List<String> list = new ArrayList<String>(); for (Node node : listQuestion) { if (list.contains(node.getName())) continue; else list.add(node.getName()); results.add(getResultObj(node)); } return results; } // merging results if (!listQuestion.isEmpty()) { isInitiated = true; for (Node node : listQuestion) { mergeQuestion.put(node.getName(), node); } } } if (eventQuery.isLanguageLevelSearch()) { // directly return because there is only one this type of search if (!eventQuery.isQuestionLevelSearch() && !eventQuery.isAnswerCommentLevelSearch()) { for (Node node : listLanguage) { results.add(getResultObj(node)); } return results; } // merging results if (isInitiated) { for (Node node : listLanguage) { String id = node.getProperty(EXO_QUESTION_ID).getString(); if (mergeQuestion.containsKey(id)) { mergeQuestion2.put(id, mergeQuestion.get(id)); } } } else { for (Node node : listLanguage) { mergeQuestion2.put(node.getProperty(EXO_QUESTION_ID).getString(), node); } isInitiated = true; } } if (eventQuery.isAnswerCommentLevelSearch()) { // directly return because there is only one this type of search if (!eventQuery.isLanguageLevelSearch() && !eventQuery.isQuestionLevelSearch()) { for (Node node : listAnswerandComment.values()) { results.add(getResultObj(node)); } return results; } // merging results if (isInitiated) { if (eventQuery.isLanguageLevelSearch()) { if (mergeQuestion2.isEmpty()) return results; for (Node node : listAnswerandComment.values()) { String id = node.getProperty(EXO_QUESTION_ID).getString(); if (mergeQuestion2.containsKey(id)) { results.add(getResultObj(node)); } } } else { // search on question level if (mergeQuestion.isEmpty()) return results; for (Node node : listAnswerandComment.values()) { String id = node.getProperty(EXO_QUESTION_ID).getString(); if (mergeQuestion.containsKey(id)) { results.add(getResultObj(node)); } } } } else { for (Node node : listAnswerandComment.values()) { results.add(getResultObj(node)); } } } // mix all result for fultext search on questions if (!eventQuery.isQuestionLevelSearch() && !eventQuery.isAnswerCommentLevelSearch() && !eventQuery.isLanguageLevelSearch()) { Map<String, ObjectSearchResult> tmpResult = new HashMap<String, ObjectSearchResult>(); ObjectSearchResult rs; for (Node node : listAnswerandComment.values()) { rs = getResultObj(node); tmpResult.put(rs.getId(), rs); } for (Node node : listQuestion) { rs = getResultObj(node); tmpResult.put(rs.getId(), rs); } for (Node node : listLanguage) { rs = getResultObj(node); tmpResult.put(rs.getId(), rs); } results.addAll(tmpResult.values()); } return results; } else if (eventQuery.getType().equals(FAQEventQuery.CATEGORY_AND_QUESTION)) { // Quick search String nodePath = EMPTY_STR; Session session = categoryHome.getSession(); Map<String, ObjectSearchResult> searchMap = new HashMap<String, ObjectSearchResult>(); while (iter.hasNext()) { boolean isResult = true; nodeObj = iter.nextNode(); nodePath = nodeObj.getPath(); if (nodePath.indexOf("/Question") > 0 && nodePath.lastIndexOf("/") >= nodePath.indexOf("/Question")) { nodePath = nodePath.substring(0, nodePath.indexOf("/Question") + 41); nodeObj = (Node) session.getItem(nodePath); if (!eventQuery.isAdmin()) { try { if ((nodeObj.getProperty(EXO_IS_APPROVED).getBoolean() == true && nodeObj.getProperty(EXO_IS_ACTIVATED).getBoolean() == true) || (nodeObj.getProperty(EXO_AUTHOR).getString().equals(eventQuery.getUserId()) && nodeObj.getProperty(EXO_IS_ACTIVATED).getBoolean() == true)) { // for retricted audiences if (retrictedCategoryList.size() > 0) { String path = nodeObj.getPath(); for (String id : retrictedCategoryList) { if (path.indexOf(id) > 0) { isResult = false; break; } } } } else { isResult = false; } } catch (Exception e) { log.debug(nodeObj + " node must exist: ", e); isResult = false; } } } else if (nodeObj.isNodeType(EXO_FAQ_CATEGORY)) { if (!eventQuery.isAdmin()) { // for restricted audiences if (retrictedCategoryList.size() > 0) { String path = nodeObj.getPath(); for (String id : retrictedCategoryList) { if (path.indexOf(id) > 0) { isResult = false; break; } } } } } if (!searchMap.containsKey(nodeObj.getName()) && isResult) { searchMap.put(nodeObj.getName(), getResultObj(nodeObj)); } } return new ArrayList<ObjectSearchResult>(searchMap.values()); } } catch (Exception e) { throw e; } finally { sProvider.close(); } return new ArrayList<ObjectSearchResult>(); } private ObjectSearchResult getResultObj(Node node) throws Exception { ObjectSearchResult objectResult = new ObjectSearchResult(); if (node.isNodeType(EXO_FAQ_CATEGORY)) { objectResult.setIcon("FAQCategorySearch"); objectResult.setName(node.getProperty(EXO_NAME).getString()); objectResult.setType("faqCategory"); String path = node.getPath(); objectResult.setId(path.substring(path.indexOf(Utils.FAQ_APP) + Utils.FAQ_APP.length() + 1)); objectResult.setCreatedDate(node.getProperty(EXO_CREATED_DATE).getDate().getTime()); } else { if (node.isNodeType(EXO_FAQ_QUESTION)) { if (questionHasAnswer(node)) { objectResult.setIcon("QuestionSearch"); } else { objectResult.setIcon("NotResponseSearch"); } objectResult.setName(node.getProperty(EXO_TITLE).getString()); String path = node.getPath(); objectResult.setId(path.substring(path.indexOf(Utils.FAQ_APP) + Utils.FAQ_APP.length() + 1)); objectResult.setCreatedDate(node.getProperty(EXO_CREATED_DATE).getDate().getTime()); } else { objectResult.setIcon("QuestionSearch"); String nodePath = node.getPath(); nodePath = nodePath.substring(0, nodePath.indexOf("/Question") + 41); Node questionNode = (Node) node.getSession().getItem(nodePath); objectResult.setName(questionNode.getProperty(EXO_TITLE).getString()); String path = questionNode.getPath(); objectResult.setId(path.substring(path.indexOf(Utils.FAQ_APP) + Utils.FAQ_APP.length() + 1)); objectResult.setCreatedDate(questionNode.getProperty(EXO_CREATED_DATE).getDate().getTime()); // } } objectResult.setType("faqQuestion"); } return objectResult; } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#getCategoryPath(java.lang.String) */ public List<String> getCategoryPath(String categoryId) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); List<String> breadcums = new ArrayList<String>(); try { Node category = getFAQServiceHome(sProvider).getNode(categoryId); while (!category.getName().equals(Utils.CATEGORY_HOME)) { breadcums.add(category.getName()); category = category.getParent(); } } catch (Exception e) { log.error("Failed to get category: ", e); } finally { sProvider.close(); } return breadcums; } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#getParentCategoriesName(java.lang.String) */ public String getParentCategoriesName(String path) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); StringBuilder names = new StringBuilder(); List<String> list = new ArrayList<String>(); try { Node category = getFAQServiceHome(sProvider).getNode(path); while (category.isNodeType(EXO_FAQ_CATEGORY)) { if (category.hasProperty(EXO_NAME)) { list.add(category.getProperty(EXO_NAME).getString()); } else { list.add(category.getName()); } category = category.getParent(); } for (int i = list.size() - 1; i >= 0; i--) { if (i != list.size() - 1) names.append(" > "); names.append(list.get(i)); } } catch (Exception e) { log.error("Failed to get parent categories name", e); } finally { sProvider.close(); } return names.toString(); } private void sendEmailNotification(List<String> addresses, Message message) throws Exception { pendingMessagesQueue.add(new NotifyInfo(addresses, message)); } public Iterator<NotifyInfo> getPendingMessages() throws Exception { Iterator<NotifyInfo> pending = new ArrayList<NotifyInfo>(pendingMessagesQueue).iterator(); pendingMessagesQueue.clear(); return pending; } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#getMessageInfo(java.lang.String) */ public NotifyInfo getMessageInfo(String name) throws Exception { NotifyInfo messageInfo = messagesInfoMap_.get(name); messagesInfoMap_.remove(name); return messageInfo; } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#swapCategories(java.lang.String, java.lang.String) */ public void swapCategories(String cateId1, String cateId2) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { Node goingCategory = getFAQServiceHome(sProvider).getNode(cateId1); Node mockCategory = getFAQServiceHome(sProvider).getNode(cateId2); long index = mockCategory.getProperty(EXO_INDEX).getLong(); if (goingCategory.getParent().getPath().equals(mockCategory.getParent().getPath())) { goingCategory.setProperty(EXO_INDEX, index); goingCategory.save(); resetIndex(goingCategory, index); } else { String id = goingCategory.getName(); mockCategory.getSession().move(goingCategory.getPath(), mockCategory.getParent().getPath() + "/" + id); mockCategory.getSession().save(); Node destCat = mockCategory.getParent().getNode(id); destCat.setProperty(EXO_INDEX, index); destCat.save(); resetIndex(destCat, index); } } catch (Exception e) { log.error("Failed to swap category", e); } finally { sProvider.close(); } } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#saveTopicIdDiscussQuestion(java.lang.String, java.lang.String) */ public void saveTopicIdDiscussQuestion(String questionId, String topicId) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { Node questionNode = getFAQServiceHome(sProvider).getNode(questionId); questionNode.setProperty(EXO_TOPIC_ID_DISCUSS, topicId); questionNode.save(); } catch (Exception e) { log.error("Failed to save topic discuss question: ", e); } finally { sProvider.close(); } } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#exportData(java.lang.String, boolean) */ public InputStream exportData(String categoryId, boolean createZipFile) throws Exception { Node categoryNode = getCategoryNodeById(categoryId); Session session = categoryNode.getSession(); ByteArrayOutputStream bos = new ByteArrayOutputStream(); File file = null; List<File> listFiles = new ArrayList<File>(); Calendar date = GregorianCalendar.getInstance(); session.exportSystemView(categoryNode.getPath(), bos, false, false); listFiles.add(org.exoplatform.ks.common.Utils.getXMLFile(bos, "eXo Knowledge Suite - Answers", "Category", date.getTime(), categoryNode.getName())); ZipOutputStream zipOutputStream = new ZipOutputStream(new FileOutputStream("exportCategory.zip")); try { int byteReads; byte[] buffer = new byte[4096]; // Create a buffer for copying FileInputStream inputStream = null; ZipEntry zipEntry = null; for (File f : listFiles) { try { inputStream = new FileInputStream(f); 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 = new File("exportCategory.zip"); InputStream fileInputStream = new FileInputStream(file); return fileInputStream; } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#importData(java.lang.String, java.io.InputStream, boolean) */ public boolean importData(String parentId, InputStream inputStream, boolean isZip) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { List<String> patchNodeImport = new ArrayList<String>(); Node categoryNode = getFAQServiceHome(sProvider).getNode(parentId); Session session = categoryNode.getSession(); NodeIterator iter = categoryNode.getNodes(); while (iter.hasNext()) { patchNodeImport.add(iter.nextNode().getName()); } if (isZip) { // Import from zipfile ZipInputStream zipStream = new ZipInputStream(inputStream); ZipEntry entry; while ((entry = zipStream.getNextEntry()) != null) { ByteArrayOutputStream out = new ByteArrayOutputStream(); int available = -1; byte[] data = new byte[2048]; while ((available = zipStream.read(data, 0, 1024)) > -1) { out.write(data, 0, available); } zipStream.closeEntry(); out.close(); InputStream input = new ByteArrayInputStream(out.toByteArray()); session.importXML(categoryNode.getPath(), input, ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW); session.save(); } zipStream.close(); calculateImportRootCategory(categoryNode); } else { // import from xml session.importXML(categoryNode.getPath(), inputStream, ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW); session.save(); } categoryNode = (Node) session.getItem(categoryNode.getPath()); iter = categoryNode.getNodes(); while (iter.hasNext()) { Node node = iter.nextNode(); if (patchNodeImport.contains(node.getName())) patchNodeImport.remove(node.getName()); else patchNodeImport.add(node.getName()); } for (String string : patchNodeImport) { Node nodeParentQuestion = categoryNode.getNode(string); iter = getQuestionsIterator(nodeParentQuestion, EMPTY_STR, true); // Update number answers and regeister question node listener while (iter.hasNext()) { Node node = iter.nextNode(); reUpdateNumberOfPublicAnswers(node); registerQuestionNodeListener(node); } } } catch (Exception e) { log.error("Failed to import data in category " + parentId, e); return false; } finally { sProvider.close(); } return true; } private void calculateImportRootCategory(Node categoryRootNode) throws Exception { try { NodeIterator iterator0 = categoryRootNode.getNodes(); int i = 0; while (iterator0.hasNext()) { if (iterator0.nextNode().isNodeType(EXO_FAQ_CATEGORY)) { i = i + 1; } } Node categoryNode = categoryRootNode.getNode(Utils.CATEGORY_HOME); NodeIterator iterator = categoryNode.getNodes(); String rootPath = categoryRootNode.getPath(); Session session = categoryRootNode.getSession(); Workspace workspace = session.getWorkspace(); while (iterator.hasNext()) { Node node = iterator.nextNode(); try { if (node.isNodeType(EXO_FAQ_CATEGORY)) { node.setProperty(EXO_INDEX, i); i = i + 1; workspace.move(node.getPath(), rootPath + "/" + node.getName()); } else if (node.isNodeType(EXO_FAQ_QUESTION_HOME)) { if (categoryRootNode.hasNode(Utils.QUESTION_HOME)) { NodeIterator iter = node.getNodes(); while (iter.hasNext()) { Node node_ = iter.nextNode(); workspace.move(node_.getPath(), rootPath + "/" + Utils.QUESTION_HOME + "/" + node_.getName()); } } else { workspace.move(node.getPath(), rootPath + "/" + node.getName()); } } } catch (Exception e) { } } categoryNode.remove(); session.save(); } catch (Exception e) { } } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#isExisting(java.lang.String) */ public boolean isExisting(String path) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { return getFAQServiceHome(sProvider).hasNode(path); } finally { sProvider.close(); } } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#getCategoryPathOf(java.lang.String) */ public String getCategoryPathOf(String id) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { Node node = getFAQServiceHome(sProvider).getNode(id); String path; if (node.isNodeType(EXO_FAQ_QUESTION)) path = node.getParent().getParent().getPath(); else if (node.isNodeType(EXO_FAQ_CATEGORY)) path = node.getPath(); else return null; return path.substring(path.indexOf(Utils.CATEGORY_HOME)); } catch (Exception e) { log.error("Failed to get category of path: " + id, e); } finally { sProvider.close(); } return null; } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#isModerateAnswer(java.lang.String) */ public boolean isModerateAnswer(String id) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { Node node = getFAQServiceHome(sProvider).getNode(id); if (node.isNodeType(EXO_FAQ_QUESTION)) node = node.getParent().getParent(); return new PropertyReader(node).bool(EXO_IS_MODERATE_ANSWERS, false); } catch (Exception e) { log.error("Failed to check moderate answer", e); } finally { sProvider.close(); } return false; } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#isModerateQuestion(java.lang.String) */ public boolean isModerateQuestion(String id) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { Node node = getFAQServiceHome(sProvider).getNode(id); if (node.isNodeType(EXO_FAQ_QUESTION)) node = node.getParent().getParent(); return node.getProperty(EXO_IS_MODERATE_QUESTIONS).getBoolean(); } catch (PathNotFoundException e) { return false; } catch (Exception e) { log.error("Failed to moderate question", e); } finally { sProvider.close(); } return false; } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#isViewAuthorInfo(java.lang.String) */ public boolean isViewAuthorInfo(String id) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { Node node; if (id == null) node = getCategoryHome(sProvider, null); else node = getCategoryNodeById(sProvider, id); if (node.isNodeType(EXO_FAQ_QUESTION)) node = node.getParent().getParent(); return new PropertyReader(node).bool(EXO_VIEW_AUTHOR_INFOR, false); } catch (Exception e) { log.error("Failed to check view author infor", e); } finally { sProvider.close(); } return false; } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#isCategoryModerator(java.lang.String, java.lang.String) */ public boolean isCategoryModerator(String categoryId, String user) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); boolean isCalMod = false; try { List<String> userGroups = UserHelper.getAllGroupAndMembershipOfUser(user); Node node = getCategoryNodeById(sProvider, categoryId); PropertyReader reader = new PropertyReader(node); List<String> values = reader.list(EXO_MODERATORS, new ArrayList<String>()); if (!values.isEmpty()) isCalMod = Utils.hasPermission(userGroups, values); } catch (Exception e) { log.error("Cheking whether category moderator failed: ", e); } finally { sProvider.close(); } return isCalMod; } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#isCategoryExist(java.lang.String, java.lang.String) */ public boolean isCategoryExist(String name, String path) { if (path == null || path.trim().length() <= 0) return false; SessionProvider sProvider = SessionProvider.createSystemProvider(); try { Node category = getFAQServiceHome(sProvider).getNode(path); NodeIterator iter = category.getNodes(); while (iter.hasNext()) { Node cat = iter.nextNode(); try { if (name.equals(cat.getProperty(EXO_NAME).getString())) return true; } catch (Exception e) { log.debug("Failed to check exist category by name", e); } } } catch (Exception e) { log.error("Cheking whether catagory is exist: ", e); } finally { sProvider.close(); } return false; } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#getQuestionContents(java.util.List) */ public List<String> getQuestionContents(List<String> paths) throws Exception { List<String> contents = new ArrayList<String>(); SessionProvider sProvider = SessionProvider.createSystemProvider(); try { for (String path : paths) { try { contents.add(getQuestionNodeById(sProvider, path).getProperty(EXO_TITLE).getString()); } catch (Exception e) { } } } finally { sProvider.close(); } return contents; } // will be remove /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#getQuestionNodeById(java.lang.String) */ public Node getQuestionNodeById(String path) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { return getQuestionNodeById(sProvider, path); } catch (Exception e) { log.error("Failed to get question node by path:" + path, e); } finally { sProvider.close(); } return null; } private Node getQuestionNodeById(SessionProvider sProvider, String path) throws Exception { Node serviceHome = getFAQServiceHome(sProvider); try { return serviceHome.getNode(path); } catch (PathNotFoundException e) { StringBuffer queryString = new StringBuffer(JCR_ROOT).append(serviceHome.getPath()).append("//element(*,exo:faqQuestion)[fn:name()='").append(path).append("']"); QueryManager qm = serviceHome.getSession().getWorkspace().getQueryManager(); Query query = qm.createQuery(queryString.toString(), Query.XPATH); QueryResult result = query.execute(); NodeIterator iter = result.getNodes(); if (iter.getSize() > 0) return iter.nextNode(); } return null; } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#getModeratorsOf(java.lang.String) */ public String[] getModeratorsOf(String path) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { Node node = getFAQServiceHome(sProvider).getNode(path); if (node.isNodeType(EXO_FAQ_QUESTION)) { return new PropertyReader(node.getParent().getParent()).strings(EXO_MODERATORS, new String[] {}); } else if (node.isNodeType(EXO_FAQ_CATEGORY)) { return new PropertyReader(node).strings(EXO_MODERATORS, new String[] {}); } } catch (Exception e) { log.error("Failed to get moderators of path: " + path, e); } finally { sProvider.close(); } return new String[] {}; } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#getCategoryNameOf(java.lang.String) */ public String getCategoryNameOf(String categoryPath) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { Node node = getFAQServiceHome(sProvider).getNode(categoryPath); if (node.hasProperty(EXO_NAME)) return node.getProperty(EXO_NAME).getString(); return node.getName(); } catch (Exception e) { log.error("Failed to get category name of path: " + categoryPath, e); } finally { sProvider.close(); } return null; } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#getCategoryInfo(java.lang.String, java.util.List) */ public CategoryInfo getCategoryInfo(String categoryPath, List<String> categoryIdScoped) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); CategoryInfo categoryInfo = new CategoryInfo(); try { Node categoryNode = getFAQServiceHome(sProvider).getNode(categoryPath); categoryInfo.setId(categoryNode.getName()); String path = categoryNode.getPath(); categoryInfo.setPath(path.substring(path.indexOf(Utils.FAQ_APP) + Utils.FAQ_APP.length() + 1)); if (categoryNode.hasProperty(EXO_NAME)) categoryInfo.setName(categoryNode.getProperty(EXO_NAME).getString()); else categoryInfo.setName(categoryNode.getName()); // set Path Name Node node = categoryNode; List<String> pathName = new ArrayList<String>(); String categoryName; while (node.isNodeType(EXO_FAQ_CATEGORY)) { if (node.hasProperty(EXO_NAME)) categoryName = node.getProperty(EXO_NAME).getString(); else categoryName = node.getName(); pathName.add(categoryName); node = node.getParent(); } categoryInfo.setPathName(pathName); // declare question info categoryInfo.setQuestionInfos(getQuestionInfo(categoryNode)); // declare category info if (categoryNode.hasNodes()) { List<SubCategoryInfo> subList = new ArrayList<SubCategoryInfo>(); NodeIterator subIter = categoryNode.getNodes(); Node sub; SubCategoryInfo subCat; while (subIter.hasNext()) { sub = subIter.nextNode(); if (categoryIdScoped.isEmpty() || categoryIdScoped.contains(sub.getName())) { if (sub.isNodeType(EXO_FAQ_CATEGORY)) { subCat = new SubCategoryInfo(); subCat.setId(sub.getName()); subCat.setName(sub.getProperty(EXO_NAME).getString()); subCat.setPath(categoryInfo.getPath() + "/" + sub.getName()); subCat.setSubCateInfos(getSubCategoryInfo(sub, categoryIdScoped)); subCat.setQuestionInfos(getQuestionInfo(sub)); subList.add(subCat); } } } categoryInfo.setSubCateInfos(subList); } } catch (Exception e) { return null; } finally { sProvider.close(); } return categoryInfo; } private void registerQuestionNodeListener(Node questionNode) { try { ObservationManager observation = questionNode.getSession().getWorkspace().getObservationManager(); QuestionNodeListener listener = new QuestionNodeListener(); observation.addEventListener(listener, Event.NODE_ADDED | Event.NODE_REMOVED | Event.PROPERTY_ADDED | Event.PROPERTY_CHANGED, questionNode.getPath(), true, null, null, false); } catch (Exception e) { log.error("can not add listener to question node", e); } } public void reCalculateInfoOfQuestion(String absPathOfProp) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { Item item = null; Node quesNode = null; Node serviceHomeNode = getFAQServiceHome(sProvider); // ----- get Question Node ------------- int quesNameIndex = absPathOfProp.lastIndexOf(Utils.QUESTION_HOME) + Utils.QUESTION_HOME.length() + 2; String quesPath = absPathOfProp.substring(0, absPathOfProp.indexOf("/", quesNameIndex)); try { quesNode = (Node) serviceHomeNode.getSession().getItem(quesPath); } catch (PathNotFoundException pe) { return; } String lastActivityInfo = null; if (quesNode.hasProperty(EXO_LAST_ACTIVITY)) lastActivityInfo = quesNode.getProperty(EXO_LAST_ACTIVITY).getString(); long timeOfLastActivity = Utils.getTimeOfLastActivity(lastActivityInfo); long numberOfAnswers = 0; if (quesNode.hasProperty(EXO_NUMBER_OF_PUBLIC_ANSWERS)) { numberOfAnswers = quesNode.getProperty(EXO_NUMBER_OF_PUBLIC_ANSWERS).getLong(); } // ------------- end ----------------- // -------------- get updated Item ---------------- try { item = getFAQServiceHome(sProvider).getSession().getItem(absPathOfProp); } catch (PathNotFoundException pnfe) { // item has been removed. Update last activity of question. reUpdateLastActivityOfQuestion(quesNode); reUpdateNumberOfPublicAnswers(quesNode); return; } if (item instanceof Property) { Property prop = (Property) item; if (prop.getName().equalsIgnoreCase(EXO_ACTIVATE_RESPONSES) || prop.getName().equalsIgnoreCase(EXO_APPROVE_RESPONSES)) { // if activate or approve property has been changed. boolean value = prop.getBoolean(); Node answerNode = prop.getParent(); boolean isActivated = false, isApproved = false; if (answerNode.hasProperty(EXO_ACTIVATE_RESPONSES)) isActivated = answerNode.getProperty(EXO_ACTIVATE_RESPONSES).getBoolean(); if (answerNode.hasProperty(EXO_APPROVE_RESPONSES)) isApproved = answerNode.getProperty(EXO_APPROVE_RESPONSES).getBoolean(); long answerTime = 0; if (answerNode.hasProperty(EXO_DATE_RESPONSE)) answerTime = answerNode.getProperty(EXO_DATE_RESPONSE).getDate().getTimeInMillis(); if (isActivated && isApproved) { numberOfAnswers++; quesNode.setProperty(EXO_NUMBER_OF_PUBLIC_ANSWERS, numberOfAnswers); // admin changed this answer to public ... if (timeOfLastActivity < answerTime) { String author = answerNode.getProperty(EXO_RESPONSE_BY).getString(); quesNode.setProperty(EXO_LAST_ACTIVITY, getLastActivityInfo(author, answerTime)); } quesNode.save(); return; } else { // if admin change answer status from viewable to unapproved and // inactivated reUpdateNumberOfPublicAnswers(quesNode); // reUpdateLastActivityOfQuestion(quesNode); if (timeOfLastActivity == answerTime) { // re-update last activity now reUpdateLastActivityOfQuestion(quesNode); return; } } } } if (item instanceof Node) { // case of adding new comment. Node node = (Node) item; if (node.getPrimaryNodeType().getName().equalsIgnoreCase(EXO_COMMENT)) { long commentTime = node.getProperty(EXO_DATE_COMMENT).getDate().getTimeInMillis(); if (commentTime > timeOfLastActivity) { String author = node.getProperty(EXO_COMMENT_BY).getString(); quesNode.setProperty(EXO_LAST_ACTIVITY, author + "-" + String.valueOf(commentTime)); quesNode.save(); } } } } catch (Exception e) { log.error("Failed to re calculateInfo of question", e); } finally { sProvider.close(); } } private void reUpdateNumberOfPublicAnswers(Node questionNode) throws RepositoryException { QueryManager qm = questionNode.getSession().getWorkspace().getQueryManager(); StringBuilder sb = new StringBuilder(); sb.append(JCR_ROOT).append(questionNode.getPath()).append("//element(*, exo:answer)[@exo:activateResponses='true' and @exo:approveResponses='true']"); Query query = qm.createQuery(sb.toString(), Query.XPATH); QueryResult result = query.execute(); long size = result.getNodes().getSize(); size = size < 0 ? 0 : size; questionNode.setProperty(EXO_NUMBER_OF_PUBLIC_ANSWERS, size); questionNode.save(); } private void reUpdateLastActivityOfQuestion(Node quesNode) throws RepositoryException { QueryManager qm = quesNode.getSession().getWorkspace().getQueryManager(); StringBuilder sb = new StringBuilder(); sb.append(JCR_ROOT).append(quesNode.getPath()).append("//element(*, exo:answer)[@exo:activateResponses='true' and @exo:approveResponses='true'] order by @exo:dateResponse descending"); QueryImpl query = (QueryImpl) qm.createQuery(sb.toString(), Query.XPATH); query.setLimit(1); QueryResult result = query.execute(); NodeIterator iter = result.getNodes(); String author = null; long lastTime = -1; if (iter.hasNext()) { Node node = iter.nextNode(); if (node.hasProperty(EXO_DATE_RESPONSE)) { lastTime = node.getProperty(EXO_DATE_RESPONSE).getDate().getTimeInMillis(); } if (node.hasProperty(EXO_RESPONSE_BY)) { author = node.getProperty(EXO_RESPONSE_BY).getString(); } } sb = new StringBuilder(); sb.append(JCR_ROOT).append(quesNode.getPath()).append("//element(*, exo:comment) order by @exo:dateComment descending"); query = (QueryImpl) qm.createQuery(sb.toString(), Query.XPATH); query.setLimit(1); result = query.execute(); iter = result.getNodes(); if (iter.hasNext()) { Node commentNode = iter.nextNode(); if (commentNode.hasProperty(EXO_DATE_COMMENT) && commentNode.hasProperty(EXO_COMMENT_BY)) { long commentTime = commentNode.getProperty(EXO_DATE_COMMENT).getDate().getTimeInMillis(); if (lastTime < commentTime) { lastTime = commentTime; author = commentNode.getProperty(EXO_COMMENT_BY).getString(); } } } if (lastTime > 0) { quesNode.setProperty(EXO_LAST_ACTIVITY, author + "-" + String.valueOf(lastTime)); quesNode.save(); } else { quesNode.setProperty(EXO_LAST_ACTIVITY, (String) null); } } private List<SubCategoryInfo> getSubCategoryInfo(Node category, List<String> categoryIdScoped) throws Exception { List<SubCategoryInfo> subList = new ArrayList<SubCategoryInfo>(); if (category.hasNodes()) { NodeIterator iter = category.getNodes(); Node sub; SubCategoryInfo cat; while (iter.hasNext()) { try { sub = iter.nextNode(); if (sub.isNodeType(EXO_FAQ_CATEGORY)) { if (categoryIdScoped.isEmpty() || categoryIdScoped.contains(sub.getName())) { cat = new SubCategoryInfo(); cat.setName(sub.getProperty(EXO_NAME).getString()); String path = sub.getPath(); cat.setPath(path.substring(path.indexOf(Utils.FAQ_APP) + Utils.FAQ_APP.length() + 1)); cat.setId(sub.getName()); subList.add(cat); } } } catch (Exception e) { log.error("Failed to get sub category info: ", e); } } } return subList; } private NodeIterator getNodeIteratorAnswerAccess(Node answerHome) throws Exception { StringBuffer queryString = new StringBuffer(JCR_ROOT).append(answerHome.getPath()).append("/element(*,exo:answer)[@exo:approveResponses='true' and @exo:activateResponses='true']"); QueryManager qm = answerHome.getSession().getWorkspace().getQueryManager(); Query query = qm.createQuery(queryString.toString(), Query.XPATH); QueryResult result = query.execute(); return result.getNodes(); } private List<QuestionInfo> getQuestionInfo(Node categoryNode) throws Exception { List<QuestionInfo> questionInfoList = new ArrayList<QuestionInfo>(); if (categoryNode.hasNode(Utils.QUESTION_HOME)) { QuestionInfo questionInfo; String strQuery = "[@exo:isActivated='true' and @exo:isApproved='true']"; NodeIterator iter = getQuestionsIterator(categoryNode.getNode(Utils.QUESTION_HOME), strQuery, false); Node question; while (iter.hasNext()) { question = iter.nextNode(); questionInfo = new QuestionInfo(); try { questionInfo.setQuestion(question.getProperty(EXO_TITLE).getString()); questionInfo.setDetail(question.getProperty(EXO_NAME).getString()); questionInfo.setId(question.getName()); if (question.hasNode(Utils.ANSWER_HOME)) { List<String> answers = new ArrayList<String>(); NodeIterator ansIter = getNodeIteratorAnswerAccess(question.getNode(Utils.ANSWER_HOME)); while (ansIter.hasNext()) { answers.add(ansIter.nextNode().getProperty(EXO_RESPONSES).getString()); } questionInfo.setAnswers(answers); } questionInfoList.add(questionInfo); } catch (Exception e) { log.error("Failed to add answer by question node: " + question.getName(), e); } } } return questionInfoList; } /* * (non-Javadoc) * @see org.exoplatform.faq.service.impl.DataStorage#updateQuestionRelatives(java.lang.String, java.lang.String[]) */ public void updateQuestionRelatives(String questionPath, String[] relatives) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { Node question = getFAQServiceHome(sProvider).getNode(questionPath); question.setProperty(EXO_RELATIVES, relatives); question.save(); } catch (Exception e) { log.error("Failed to update question relatives: ", e); } finally { sProvider.close(); } } public void calculateDeletedUser(String userName) throws Exception { // remove setting by user SessionProvider sProvider = SessionProvider.createSystemProvider(); try { Node node = getUserSettingHome(sProvider); if (node.hasNode(userName)) node.getNode(userName).remove(); StringBuilder queryString = new StringBuilder(JCR_ROOT).append("/").append(dataLocator.getFaqCategoriesLocation()).append("//*["); String[] strs = new String[] { EXO_RESPONSE_BY, EXO_COMMENT_BY, EXO_AUTHOR, EXO_USER_WATCHING }; for (int i = 0; i < strs.length; i++) { queryString.append("@").append(strs[i]).append("='").append(userName).append((i == strs.length - 1) ? "']" : "' or "); } Session session = node.getSession(); QueryManager qm = session.getWorkspace().getQueryManager(); Query query = qm.createQuery(queryString.toString(), Query.XPATH); QueryResult result = query.execute(); NodeIterator iter = result.getNodes(); Node item; String newUserName = userName + Utils.DELETED + (new Random(100)); while (iter.hasNext()) { item = iter.nextNode(); for (int i = 0; i < strs.length; i++) { if (i < 3 && item.hasProperty(strs[i]) && item.getProperty(strs[i]).getString().equals(userName)) { item.setProperty(strs[i], newUserName); } else if (item.hasProperty(strs[i])) { List<String> list = new PropertyReader(item).list(strs[i], new ArrayList<String>()); int t = list.indexOf(userName); if (t > 0 && strs[i].equals(EXO_USER_WATCHING)) { List<String> list2 = new PropertyReader(item).list(EXO_EMAIL_WATCHING, new ArrayList<String>()); list2.remove(t); item.setProperty(EXO_EMAIL_WATCHING, list2.toArray(new String[list2.size()])); } } } } session.save(); // LastActivity queryString = new StringBuilder(JCR_ROOT).append("/").append(dataLocator.getFaqCategoriesLocation()).append("//element(*,exo:faqQuestion)[(jcr:contains(@").append(EXO_LAST_ACTIVITY).append(", '").append(userName).append("'))]"); query = qm.createQuery(queryString.toString(), Query.XPATH); iter = query.execute().getNodes(); Question question = new Question(); while (iter.hasNext()) { item = iter.nextNode(); if (item.hasProperty(EXO_LAST_ACTIVITY)) { question.setLastActivity(item.getProperty(EXO_LAST_ACTIVITY).getString()); if (userName.equals(question.getAuthorOfLastActivity())) { item.setProperty(EXO_LAST_ACTIVITY, newUserName + "-" + question.getTimeOfLastActivity()); } } } session.save(); } catch (Exception e) { log.error("Failed to create answer RSS ", e); } finally { sProvider.close(); } } public InputStream createAnswerRSS(String cateId) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { Node cateNode = getCategoryNodeById(sProvider, cateId); List<SyndEntry> entries = new ArrayList<SyndEntry>(); StringBuilder queryString = new StringBuilder(JCR_ROOT).append(cateNode.getPath()).append("//element(*,exo:faqQuestion)"); List<String> list = getListCategoryIdPublic(sProvider, cateNode); if (!list.isEmpty()) queryString.append("["); PropertyReader reader = new PropertyReader(cateNode); if (reader.list(EXO_USER_PRIVATE, new ArrayList<String>()).isEmpty()) { if (!list.isEmpty()) list.add(cateNode.getName()); } boolean isOr = false; for (String id : list) { if (isOr) { queryString.append(" or (@exo:categoryId='").append(id).append("')"); } else { queryString.append("(@exo:categoryId='").append(id).append("')"); isOr = true; } } if (!list.isEmpty()) queryString.append("]"); QueryManager qm = cateNode.getSession().getWorkspace().getQueryManager(); Query query = qm.createQuery(queryString.toString(), Query.XPATH); QueryResult result = query.execute(); NodeIterator iter = result.getNodes(); Node nodeQs; while (iter.hasNext()) { nodeQs = iter.nextNode(); if (nodeQs.getParent().getParent().isNodeType(EXO_FAQ_CATEGORY)) { entries.add(createQuestionEntry(sProvider, nodeQs)); } } SyndFeed feed = createNewFeed(cateNode, "http://www.exoplatform.com"); 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) { log.error("Failed to create answer RSS ", e); } finally { sProvider.close(); } return null; } private List<String> getListCategoryIdPublic(SessionProvider sProvider, Node cateNode) throws Exception { List<String> list = new ArrayList<String>(); StringBuilder queryString = new StringBuilder(JCR_ROOT).append(cateNode.getPath()).append("//element(*,exo:faqCategory)[@exo:isView='true' and ( not(@exo:userPrivate) or @exo:userPrivate='')]"); QueryManager qm = cateNode.getSession().getWorkspace().getQueryManager(); Query query = qm.createQuery(queryString.toString(), Query.XPATH); QueryResult result = query.execute(); NodeIterator iter = result.getNodes(); while (iter.hasNext()) { list.add(iter.nextNode().getName()); } return list; } private SyndEntry createQuestionEntry(SessionProvider sProvider, Node questionNode) throws Exception { // Create new entry List<String> listContent = new ArrayList<String>(); StringBuffer content = new StringBuffer(); for (String answer : getStrAnswers(questionNode)) content.append(answer); for (String comment : getComments(questionNode)) content.append(comment); listContent.add(content.toString()); SyndEntry entry = createNewEntry(questionNode, listContent); return entry; } private List<String> getStrAnswers(Node questionNode) throws Exception { List<String> listAnswers = new ArrayList<String>(); try { Node answerHome = questionNode.getNode(Utils.ANSWER_HOME); QueryManager qm = answerHome.getSession().getWorkspace().getQueryManager(); StringBuffer queryString = new StringBuffer(JCR_ROOT).append(answerHome.getPath()).append("//element(*,exo:answer)[(@exo:approveResponses='true') and (@exo:activateResponses='true')]").append("order by @exo:dateResponse ascending"); Query query = qm.createQuery(queryString.toString(), Query.XPATH); QueryResult result = query.execute(); NodeIterator nodeIterator = result.getNodes(); Node answerNode = null; while (nodeIterator.hasNext()) { answerNode = nodeIterator.nextNode(); if (answerNode.hasProperty(EXO_RESPONSES)) listAnswers.add("<b><u>Answer:</u></b> " + (answerNode.getProperty(EXO_RESPONSES).getString()) + "<br/>"); } } catch (Exception e) { log.error("Failed to get answers for " + questionNode.getName()); } return listAnswers; } public Comment[] getComments(String questionId) throws Exception { SessionProvider sProvider = SessionProvider.createSystemProvider(); try { Node questionNode = getQuestionNodeById(sProvider, questionId); return getComment(questionNode); } finally { sProvider.close(); } } private List<String> getComments(Node questionNode) throws Exception { List<String> listComment = new ArrayList<String>(); try { Node commentHome = questionNode.getNode(Utils.COMMENT_HOME); QueryManager qm = commentHome.getSession().getWorkspace().getQueryManager(); StringBuffer queryString = new StringBuffer(JCR_ROOT).append(commentHome.getPath()).append("//element(*,exo:comment)").append(" order by @exo:dateComment ascending"); Query query = qm.createQuery(queryString.toString(), Query.XPATH); QueryResult result = query.execute(); NodeIterator nodeIterator = result.getNodes(); Node commentNode = null; while (nodeIterator.hasNext()) { commentNode = nodeIterator.nextNode(); if (commentNode.hasProperty(EXO_COMMENTS)) listComment.add("<b><u>Comment:</u></b>" + (commentNode.getProperty(EXO_COMMENTS).getString()) + "<br/>"); } } catch (Exception e) { log.error("Failed to get comments for " + questionNode.getName()); } return listComment; } 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("ST[CDATA[" + reader.string(EXO_NAME, "Root") + "END]]"); feed.setPublishedDate(reader.date(EXO_CREATED_DATE, new Date())); feed.setLink("ST[CDATA[" + link + "END]]"); feed.setDescription("ST[CDATA[" + desc + "END]]"); feed.setEncoding("UTF-8"); return feed; } private SyndEntry createNewEntry(Node questionNode, List<String> listContent) throws Exception { PropertyReader question = new PropertyReader(questionNode); SyndContent description = new SyndContentImpl(); description.setType("text/plain"); description.setValue("ST[CDATA[" + question.string(EXO_TITLE, EMPTY_STR) + "<br/>" + (listContent.isEmpty() ? EMPTY_STR : listContent.get(0)) + "END]]"); SyndEntry entry = new SyndEntryImpl(); entry.setUri("ST[CDATA[" + questionNode.getName() + "END]]"); entry.setTitle("ST[CDATA[" + question.string(EXO_TITLE) + "END]]"); entry.setLink("ST[CDATA[" + question.string(EXO_LINK, "http://www.exoplatform.com") + "END]]"); entry.setContributors(listContent); entry.setDescription(description); entry.setPublishedDate(question.date(EXO_CREATED_DATE, new Date())); entry.setAuthor("ST[CDATA[" + question.string(EXO_AUTHOR) + "END]]"); return entry; } protected Node getFAQServiceHome(SessionProvider sProvider) throws Exception { String path = dataLocator.getFaqHomeLocation(); return sessionManager.getSession(sProvider).getRootNode().getNode(path); } private Node getKSUserAvatarHomeNode(SessionProvider sProvider) throws Exception { String path = dataLocator.getAvatarsLocation(); return sessionManager.getSession(sProvider).getRootNode().getNode(path); } private Node getUserSettingHome(SessionProvider sProvider) throws Exception { String path = dataLocator.getFaqUserSettingsLocation(); return sessionManager.getSession(sProvider).getRootNode().getNode(path); } private Node getCategoryHome(SessionProvider sProvider, String username) throws Exception { String path = dataLocator.getFaqCategoriesLocation(); return sessionManager.getSession(sProvider).getRootNode().getNode(path); } private Node getTemplateHome(SessionProvider sProvider) throws Exception { String path = dataLocator.getFaqTemplatesLocation(); return sessionManager.getSession(sProvider).getRootNode().getNode(path); } private String getLastActivityInfo(String author, long answerTime) { return author + "-" + String.valueOf(answerTime); } }