/*
* 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);
}
}