ForumActivityBuilder.java
/*
* Copyright (C) 2003-2013 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.exoplatform.forum.ext.activity;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.lang.StringEscapeUtils;
import org.exoplatform.commons.utils.StringCommonUtils;
import org.exoplatform.forum.bbcode.api.BBCode;
import org.exoplatform.forum.bbcode.core.BBCodeRenderer;
import org.exoplatform.forum.common.CommonUtils;
import org.exoplatform.forum.common.TransformHTML;
import org.exoplatform.forum.rendering.MarkupRenderingService;
import org.exoplatform.forum.rendering.core.SupportedSyntaxes;
import org.exoplatform.forum.service.Post;
import org.exoplatform.forum.service.Topic;
import org.exoplatform.social.core.activity.model.ExoSocialActivity;
import org.exoplatform.social.core.activity.model.ExoSocialActivityImpl;
import org.exoplatform.social.core.identity.model.Identity;
/**
* Created by The eXo Platform SAS
* Author : thanh_vucong
* thanh_vucong@exoplatform.com
* Jan 10, 2013
*/
public class ForumActivityBuilder {
public static final String FORUM_ACTIVITY_TYPE = "ks-forum:spaces";
public static final String FORUM_ID_KEY = "ForumId";
public static final String CATE_ID_KEY = "CateId";
public static final String POST_TYPE = "Post";
public static final String POST_ID_KEY = "PostId";
public static final String POST_OWNER_KEY = "PostOwner";
public static final String POST_LINK_KEY = "PostLink";
public static final String POST_NAME_KEY = "PostName";
public static final String TOPIC_ID_KEY = "TopicId";
public static final String TOPIC_LINK_KEY = "TopicLink";
public static final String TOPIC_OWNER_KEY = "TopicOwner";
public static final String TOPIC_POST_COUNT_KEY = "NumberOfReplies";
public static final String TOPIC_VOTE_RATE_KEY = "TopicVoteRate";
private static final int NUMBER_CHARS = 430;
public static final String SPACE_GROUP_ID = "SpaceGroupId";
private ForumActivityBuilder() {
}
public static ExoSocialActivity createActivityComment(Post post, ForumActivityContext ctx) {
ExoSocialActivity activity = new ExoSocialActivityImpl();
return updateActivityComment(activity, post, ctx);
}
public static ExoSocialActivity updateActivityComment(ExoSocialActivity activity, Post post, ForumActivityContext ctx) {
String message = post.getMessage();
message = getMessageWithoutQuotedPost(post, post.getModifiedBy() != null);
String title = processContent(message, 3);
//activity.setUserId(post.getOwner());
activity.setTitle(title);
activity.setBody(CommonUtils.processBBCode(message));
activity.isComment(true);
activity.setType(FORUM_ACTIVITY_TYPE);
//activity.setTitleId(title); => Resource Bundle Key
//
Map<String, String> templateParams = new HashMap<String, String>();
templateParams.put(POST_ID_KEY, post.getId());
templateParams.put(POST_LINK_KEY, post.getLink());
templateParams.put(POST_NAME_KEY, post.getName());
templateParams.put(POST_OWNER_KEY, post.getOwner());
//
templateParams.put(FORUM_ID_KEY, post.getForumId());
templateParams.put(CATE_ID_KEY, post.getCategoryId());
templateParams.put(TOPIC_ID_KEY, post.getTopicId());
activity.setTemplateParams(templateParams);
return activity;
}
private static String getMessageWithoutQuotedPost(Post post, boolean edit) {
String parentCommentId = post.getQuotedPostId();
String parentMessage;
String fullName;
try {
if (edit) {
ExoSocialActivity postCommentActivity = ForumActivityUtils.getCommentOfPost(post.getPath());
if (postCommentActivity != null && postCommentActivity.getParentCommentId() != null) {
ExoSocialActivity parentActivity = ForumActivityUtils.getActivityManager()
.getActivity(postCommentActivity.getParentCommentId());
if (parentActivity != null) {
parentMessage = parentActivity.getBody();
Identity posterIdentity = ForumActivityUtils.getIdentityManager().getIdentity(parentActivity.getPosterId(), true);
fullName = posterIdentity.getProfile().getFullName();
} else {
parentMessage = null;
fullName = null;
}
} else {
parentMessage = null;
fullName = null;
}
} else if (parentCommentId != null) {
Post parentPost = ForumActivityUtils.getForumService().getPost(post.getCategoryId(),
post.getForumId(),
post.getTopicId(),
parentCommentId);
fullName = ForumActivityUtils.getForumService().getScreenName(parentPost.getOwner());
parentMessage = parentPost.getMessage();
} else {
parentMessage = null;
fullName = null;
}
} catch (Exception e) {
parentMessage = null;
fullName = null;
}
String message = post.getMessage();
if (parentMessage != null && fullName != null) {
parentMessage = StringCommonUtils.decodeSpecialCharToHTMLnumber(parentMessage);
parentMessage = CommonUtils.processBBCode(parentMessage);
parentMessage = TransformHTML.cleanHtmlCode(StringEscapeUtils.unescapeHtml(TransformHTML.getPlainText(parentMessage)), null);
message = TransformHTML.cleanHtmlCode(StringEscapeUtils.unescapeHtml(TransformHTML.getPlainText(post.getMessage())), null);
message = message.replaceFirst(fullName + ":((\\r)?(\\n)?( )*)*" + parentMessage + "((\\r)?(\\n)?( )*)*", "").trim();
message = message.replaceAll("((\\r|\\n)+( )*)+", "<br/>");
}
return message;
}
public static ExoSocialActivity createActivityComment(Topic topic, ForumActivityContext ctx) {
ExoSocialActivity activity = new ExoSocialActivityImpl();
String body = processContent(topic.getDescription(), 4);
//activity.setUserId(topic.getOwner());
String title = StringCommonUtils.decodeSpecialCharToHTMLnumber(topic.getTopicName());
activity.setTitle(title);
activity.setBody(body);
activity.isComment(true);
activity.setType(FORUM_ACTIVITY_TYPE);
return activity;
}
public static String decodeHTMLInput(String message) {
message = StringCommonUtils.decodeSpecialCharToHTMLnumber(message);
String[] tab = TransformHTML.getPlainText(message).replaceAll("(?m)^\\s*$[\n\r]{1,}", "").split("\\r?\\n");
StringBuilder sb = new StringBuilder();
for (int i=0; i<tab.length; i++) {
sb.append(StringEscapeUtils.unescapeHtml(tab[i]));
sb.append("<br/>");
}
return sb.toString();
}
/**
* No more than nbOfLines lines
* No more than 430 characters
* If the content is larger than these limits, we add "..." at the end of the abstract.
* @param content
* @param nbOfLines
* @return
*/
public static String processContent(String content, int nbOfLines) {
content = content.replaceAll(" ", "");
String[] tab = TransformHTML.getPlainText(content).replaceAll("(?m)^\\s*$[\n\r]{1,}", "").split("\\r?\\n");
//
int numberOfLine = Math.min(nbOfLines, tab.length);
StringBuilder sb = new StringBuilder();
//
for (int i=0; i<numberOfLine; i++) {
sb.append(tab[i]);
//
if(i < numberOfLine - 1) {
sb.append("BR_");
}
}
String str = TransformHTML.cleanHtmlCode(sb.toString(), null).trim();
str = trunc(str.replaceAll("BR_", "<br/>"), NUMBER_CHARS, tab.length > nbOfLines);
str = CommonUtils.processBBCode(str);
// The string could be truncated at middle of an BB Tag
// So there may be an incomplete BB code at string after process, we need to clean them
str = cleanupBBCode(str);
return str;
}
/**
* Truncates large Strings showing a portion of the String's head and tail
* with the head cut out and replaced with '...'.
*
* @param str
* the string to truncate
* @param head
* the amount of the head to display
* @return the head truncated string
*/
public static final String trunc(String str, int head, boolean needTail) {
StringBuffer buf = null;
// Return as-is if String is smaller than or equal to the head plus the
// tail plus the number of characters added to the trunc representation
// plus the number of digits in the string length.
buf = new StringBuffer();
if (str.length() <= (head + 7 + str.length() / 10)) {
buf.append(str);
if (needTail) {
buf.append("...");
}
return buf.toString();
}
//
buf.append(str.substring(0, head)).append("...");
return buf.toString();
}
private static String cleanupBBCode(String str) {
MarkupRenderingService markupRenderingService = CommonUtils.getComponent(MarkupRenderingService.class);
BBCodeRenderer r = (BBCodeRenderer)markupRenderingService.getRenderer(SupportedSyntaxes.bbcode.name());
if (r != null) {
String tag = null;
for (BBCode bbcode : r.getBbcodes()) {
tag = bbcode.getTagName();
String pattern = "\\[" + tag + "[^\\]]*\\]";
str = str.replaceAll(pattern, "");
}
}
return str;
}
public static ExoSocialActivity createActivity(Topic topic, ForumActivityContext ctx) {
ExoSocialActivity activity = new ExoSocialActivityImpl();
String body = processContent(topic.getDescription(), 4);
//processing in execute of task.
//avoid get Identity here to write UT
//activity.setUserId(topic.getOwner());
activity.setTitle(StringCommonUtils.decodeSpecialCharToHTMLnumber(topic.getTopicName()));
activity.setBody(body);
activity.isComment(false);
activity.isHidden(!topic.getIsApproved());
activity.setType(FORUM_ACTIVITY_TYPE);
//
Map<String, String> templateParams = new HashMap<String, String>();
templateParams.put(TOPIC_POST_COUNT_KEY, "" + topic.getPostCount());
templateParams.put(TOPIC_VOTE_RATE_KEY, "" + topic.getVoteRating());
templateParams.put(TOPIC_ID_KEY, topic.getId());
templateParams.put(TOPIC_OWNER_KEY, topic.getOwner());
//
templateParams.put(TOPIC_LINK_KEY, CommonUtils.getURI(topic.getLink()));
//
templateParams.put(FORUM_ID_KEY, topic.getForumId());
templateParams.put(CATE_ID_KEY, topic.getCategoryId());
if (ForumActivityUtils.hasSpace(topic.getForumId())) {
templateParams.put(SPACE_GROUP_ID, ForumActivityUtils.getSpaceGroupId(topic.getForumId()));
}
activity.setTemplateParams(templateParams);
return activity;
}
public static ExoSocialActivity updateNumberOfReplies(Topic topic, ExoSocialActivity activity) {
//
Map<String, String> templateParams = activity.getTemplateParams();
templateParams.put(TOPIC_POST_COUNT_KEY, "" + topic.getPostCount());
return activity;
}
public static ExoSocialActivity updateNumberOfReplies(ExoSocialActivity activity, boolean isDelete) {
//
Map<String, String> templateParams = activity.getTemplateParams();
int nbReplies = Integer.parseInt(templateParams.get(TOPIC_POST_COUNT_KEY));
if (isDelete == true) {
templateParams.put(TOPIC_POST_COUNT_KEY, "" + (nbReplies - 1));
} else {
templateParams.put(TOPIC_POST_COUNT_KEY, "" + (nbReplies + 1));
}
activity.setTemplateParams(templateParams);
return activity;
}
public static ExoSocialActivity updateVoteRate(Topic topic, ExoSocialActivity activity) {
//
Map<String, String> templateParams = activity.getTemplateParams();
templateParams.put(TOPIC_VOTE_RATE_KEY, "" + topic.getVoteRating());
return activity;
}
}