org.b3log.solo.util.Comments.java Source code

Java tutorial

Introduction

Here is the source code for org.b3log.solo.util.Comments.java

Source

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