Java tutorial
/* * Copyright (c) 2009, 2010, 2011, 2012, B3log Team * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.b3log.solo.util; import java.io.IOException; import java.net.URL; import java.util.logging.Level; import java.util.logging.Logger; import org.b3log.latke.Keys; import org.b3log.latke.mail.MailService; import org.b3log.latke.mail.MailService.Message; import org.b3log.latke.mail.MailServiceFactory; import org.b3log.latke.service.LangPropsService; import org.b3log.latke.util.Strings; import org.b3log.solo.SoloServletListener; import org.b3log.solo.model.*; import org.b3log.solo.repository.ArticleRepository; import org.b3log.solo.repository.PageRepository; import org.b3log.solo.repository.impl.ArticleRepositoryImpl; import org.b3log.solo.repository.impl.PageRepositoryImpl; import org.b3log.solo.service.PreferenceQueryService; import org.json.JSONException; import org.json.JSONObject; /** * Comment utilities. * * @author <a href="mailto:DL88250@gmail.com">Liang Ding</a> * @version 1.0.0.9, Mar 28, 2012 * @since 0.3.1 */ public final class Comments { /** * Logger. */ private static final Logger LOGGER = Logger.getLogger(Comments.class.getName()); /** * Language service. */ private static LangPropsService langPropsService = LangPropsService.getInstance(); /** * Preference query service. */ private static PreferenceQueryService preferenceQueryService = PreferenceQueryService.getInstance(); /** * Article repository. */ private static ArticleRepository articleRepository = ArticleRepositoryImpl.getInstance(); /** * Page repository. */ private static PageRepository pageRepository = PageRepositoryImpl.getInstance(); /** * Mail service. */ private static final MailService MAIL_SVC = MailServiceFactory.getMailService(); /** * Minimum length of comment name. */ private static final int MIN_COMMENT_NAME_LENGTH = 2; /** * Maximum length of comment name. */ private static final int MAX_COMMENT_NAME_LENGTH = 20; /** * Minimum length of comment content. */ private static final int MIN_COMMENT_CONTENT_LENGTH = 2; /** * Maximum length of comment content. */ private static final int MAX_COMMENT_CONTENT_LENGTH = 500; /** * Comment mail HTML body. */ public static final String COMMENT_MAIL_HTML_BODY = "<p>{articleOrPage} [<a href=\"" + "{articleOrPageURL}\">" + "{title}</a>]" + " received a new comment:</p>" + "{commenter}: <span><a href=\"http://{commentSharpURL}\">" + "{commentContent}</a></span>"; /** * Gets comment sharp URL with the specified page and comment id. * * @param page the specified page * @param commentId the specified comment id * @return comment sharp URL * @throws JSONException json exception */ public static String getCommentSharpURLForPage(final JSONObject page, final String commentId) throws JSONException { return page.getString(Page.PAGE_PERMALINK) + "#" + commentId; } /** * Gets comment sharp URL with the specified article and comment id. * * @param article the specified article * @param commentId the specified comment id * @return comment sharp URL * @throws JSONException json exception */ public static String getCommentSharpURLForArticle(final JSONObject article, final String commentId) throws JSONException { final String articleLink = article.getString(Article.ARTICLE_PERMALINK); return articleLink + "#" + commentId; } /** * Checks the specified comment adding request. * * @param requestJSONObject the specified comment adding request, for example, * <pre> * { * "type": "", // "article"/"page" * "oId": "", * "commentName": "", * "commentEmail": "", * "commentURL": "", * "commentContent": "", * } * </pre> * @return check result, for example, * <pre> * { * "sc": boolean, * "msg": "" // Exists if "sc" equals to false * } * </pre> */ public static JSONObject checkAddCommentRequest(final JSONObject requestJSONObject) { final JSONObject ret = new JSONObject(); try { ret.put(Keys.STATUS_CODE, false); final JSONObject preference = preferenceQueryService.getPreference(); if (null == preference || !preference.optBoolean(Preference.COMMENTABLE)) { ret.put(Keys.MSG, langPropsService.get("notAllowCommentLabel")); return ret; } final String id = requestJSONObject.optString(Keys.OBJECT_ID); final String type = requestJSONObject.optString(Common.TYPE); if (Article.ARTICLE.equals(type)) { final JSONObject article = articleRepository.get(id); if (null == article || !article.optBoolean(Article.ARTICLE_COMMENTABLE)) { ret.put(Keys.MSG, langPropsService.get("notAllowCommentLabel")); return ret; } } else { final JSONObject page = pageRepository.get(id); if (null == page || !page.optBoolean(Page.PAGE_COMMENTABLE)) { ret.put(Keys.MSG, langPropsService.get("notAllowCommentLabel")); return ret; } } final String commentName = requestJSONObject.getString(Comment.COMMENT_NAME); if (MAX_COMMENT_NAME_LENGTH < commentName.length() || MIN_COMMENT_NAME_LENGTH > commentName.length()) { LOGGER.log(Level.WARNING, "Comment name is too long[{0}]", commentName); ret.put(Keys.MSG, langPropsService.get("nameTooLongLabel")); return ret; } final String commentEmail = requestJSONObject.getString(Comment.COMMENT_EMAIL).trim().toLowerCase(); if (!Strings.isEmail(commentEmail)) { LOGGER.log(Level.WARNING, "Comment email is invalid[{0}]", commentEmail); ret.put(Keys.MSG, langPropsService.get("mailInvalidLabel")); return ret; } final String commentURL = requestJSONObject.optString(Comment.COMMENT_URL); try { new URL(commentURL); if (commentURL.contains("<") || commentURL.contains(">")) { throw new IllegalArgumentException(); } } catch (final Exception e) { LOGGER.log(Level.WARNING, "Comment URL is invalid[{0}]", commentURL); ret.put(Keys.MSG, langPropsService.get("urlInvalidLabel")); return ret; } final String commentContent = requestJSONObject.optString(Comment.COMMENT_CONTENT).replaceAll("\\n", SoloServletListener.ENTER_ESC); if (MAX_COMMENT_CONTENT_LENGTH < commentContent.length() || MIN_COMMENT_CONTENT_LENGTH > commentContent.length()) { LOGGER.log(Level.WARNING, "Comment conent length is invalid[{0}]", commentContent.length()); ret.put(Keys.MSG, langPropsService.get("commentContentCannotEmptyLabel")); return ret; } ret.put(Keys.STATUS_CODE, true); return ret; } catch (final Exception e) { LOGGER.log(Level.WARNING, "Checks add comment request[" + requestJSONObject.toString() + "] failed", e); ret.put(Keys.STATUS_CODE, false); ret.put(Keys.MSG, langPropsService.get("addFailLabel")); return ret; } } /** * Sends a notification mail to administrator for notifying the specified * article or page received the specified comment and original comment. * * @param articleOrPage the specified article or page * @param comment the specified comment * @param originalComment original comment, if not exists, set it as * {@code null} * @param preference the specified preference * @throws IOException io exception * @throws JSONException json exception */ public static void sendNotificationMail(final JSONObject articleOrPage, final JSONObject comment, final JSONObject originalComment, final JSONObject preference) throws IOException, JSONException { final String commentEmail = comment.getString(Comment.COMMENT_EMAIL); final String commentId = comment.getString(Keys.OBJECT_ID); final String commentContent = comment.getString(Comment.COMMENT_CONTENT) .replaceAll(SoloServletListener.ENTER_ESC, "<br/>"); final String adminEmail = preference.getString(Preference.ADMIN_EMAIL); if (adminEmail.equalsIgnoreCase(commentEmail)) { LOGGER.log(Level.FINER, "Do not send comment notification mail to admin itself[{0}]", adminEmail); return; } if (null != originalComment && comment.has(Comment.COMMENT_ORIGINAL_COMMENT_ID)) { final String originalEmail = originalComment.getString(Comment.COMMENT_EMAIL); if (originalEmail.equalsIgnoreCase(adminEmail)) { LOGGER.log(Level.FINER, "Do not send comment notification mail to admin while the specified comment[{0}] is an reply", commentId); return; } } final String blogTitle = preference.getString(Preference.BLOG_TITLE); final String blogHost = preference.getString(Preference.BLOG_HOST); boolean isArticle = true; String title = articleOrPage.optString(Article.ARTICLE_TITLE); if (Strings.isEmptyOrNull(title)) { title = articleOrPage.getString(Page.PAGE_TITLE); isArticle = false; } final String commentSharpURL = comment.getString(Comment.COMMENT_SHARP_URL); final Message message = new Message(); message.setFrom(adminEmail); message.addRecipient(adminEmail); String mailSubject = null; String articleOrPageURL = null; String mailBody = null; if (isArticle) { mailSubject = blogTitle + ": New comment on article [" + title + "]"; articleOrPageURL = "http://" + blogHost + articleOrPage.getString(Article.ARTICLE_PERMALINK); mailBody = COMMENT_MAIL_HTML_BODY.replace("{articleOrPage}", "Article"); } else { mailSubject = blogTitle + ": New comment on page [" + title + "]"; articleOrPageURL = "http://" + blogHost + articleOrPage.getString(Page.PAGE_PERMALINK); mailBody = COMMENT_MAIL_HTML_BODY.replace("{articleOrPage}", "Page"); } message.setSubject(mailSubject); final String commentName = comment.getString(Comment.COMMENT_NAME); final String commentURL = comment.getString(Comment.COMMENT_URL); String commenter = null; if (!"http://".equals(commentURL)) { commenter = "<a target=\"_blank\" " + "href=\"" + commentURL + "\">" + commentName + "</a>"; } else { commenter = commentName; } mailBody = mailBody.replace("{articleOrPageURL}", articleOrPageURL).replace("{title}", title) .replace("{commentContent}", commentContent) .replace("{commentSharpURL}", blogHost + commentSharpURL).replace("{commenter}", commenter); message.setHtmlBody(mailBody); LOGGER.log(Level.FINER, "Sending a mail[mailSubject={0}, mailBody=[{1}] to admin[email={2}]", new Object[] { mailSubject, mailBody, adminEmail }); MAIL_SVC.send(message); } /** * Gets the {@link Comments} singleton. * * @return the singleton */ public static Comments getInstance() { return SingletonHolder.SINGLETON; } /** * Private default constructor. */ private Comments() { } /** * Singleton holder. * * @author <a href="mailto:DL88250@gmail.com">Liang Ding</a> * @version 1.0.0.0, Jan 12, 2011 */ private static final class SingletonHolder { /** * Singleton. */ private static final Comments SINGLETON = new Comments(); /** * Private default constructor. */ private SingletonHolder() { } } }