Java tutorial
/* * Solo - A small and beautiful blogging system written in Java. * Copyright (c) 2010-2018, b3log.org & hacpai.com * * 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 <https://www.gnu.org/licenses/>. */ package org.b3log.solo.processor.api; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.time.DateFormatUtils; import org.b3log.latke.Keys; import org.b3log.latke.event.Event; import org.b3log.latke.event.EventManager; import org.b3log.latke.ioc.Inject; import org.b3log.latke.logging.Level; import org.b3log.latke.logging.Logger; import org.b3log.latke.repository.Transaction; import org.b3log.latke.servlet.HttpMethod; import org.b3log.latke.servlet.RequestContext; import org.b3log.latke.servlet.annotation.RequestProcessing; import org.b3log.latke.servlet.annotation.RequestProcessor; import org.b3log.latke.servlet.renderer.JsonRenderer; import org.b3log.solo.event.EventTypes; import org.b3log.solo.model.Article; import org.b3log.solo.model.Comment; import org.b3log.solo.model.Option; import org.b3log.solo.repository.ArticleRepository; import org.b3log.solo.repository.CommentRepository; import org.b3log.solo.service.ArticleMgmtService; import org.b3log.solo.service.CommentMgmtService; import org.b3log.solo.service.PreferenceQueryService; import org.b3log.solo.service.StatisticMgmtService; import org.json.JSONObject; import javax.servlet.http.HttpServletResponse; import java.net.MalformedURLException; import java.net.URL; import java.util.Date; /** * Receiving comments from B3log community. Visits <a href="https://hacpai.com/b3log">B3log ?</a> for more details. * * @author <a href="http://88250.b3log.org">Liang Ding</a> * @version 1.1.1.19, Nov 6, 2018 * @since 0.5.5 */ @RequestProcessor public class B3CommentReceiver { /** * Logger. */ private static final Logger LOGGER = Logger.getLogger(B3CommentReceiver.class); /** * Comment management service. */ @Inject private CommentMgmtService commentMgmtService; /** * Comment repository. */ @Inject private static CommentRepository commentRepository; /** * Preference query service. */ @Inject private PreferenceQueryService preferenceQueryService; /** * Article management service. */ @Inject private ArticleMgmtService articleMgmtService; /** * Article repository. */ @Inject private ArticleRepository articleRepository; /** * Event manager. */ @Inject private static EventManager eventManager; /** * Statistic management service. */ @Inject private StatisticMgmtService statisticMgmtService; /** * Adds a comment with the specified request. * <p> * Request json: * <pre> * { * "comment": { * "userB3Key": "", * "oId": "", * "commentSymphonyArticleId": "", * "commentOnArticleId": "", * "commentAuthorName": "", * "commentAuthorEmail": "", * "commentAuthorURL": "", * "commentAuthorThumbnailURL": "", * "commentContent": "", * "commentOriginalCommentId": "" // optional, if exists this key, the comment is an reply * } * } * </pre> * </p> * <p> * Renders the response with a json object, for example, * <pre> * { * "sc": true * } * </pre> * </p> * * @param context the specified http request context */ @RequestProcessing(value = "/apis/symphony/comment", method = HttpMethod.PUT) public void addComment(final RequestContext context) { final JsonRenderer renderer = new JsonRenderer(); context.setRenderer(renderer); final JSONObject ret = new JSONObject(); renderer.setJSONObject(ret); final JSONObject requestJSONObject = context.requestJSON(); final Transaction transaction = commentRepository.beginTransaction(); try { final JSONObject symphonyCmt = requestJSONObject.optJSONObject(Comment.COMMENT); final JSONObject preference = preferenceQueryService.getPreference(); final String keyOfSolo = preference.optString(Option.ID_C_KEY_OF_SOLO); final String key = symphonyCmt.optString("userB3Key"); if (StringUtils.isBlank(keyOfSolo) || !keyOfSolo.equals(key)) { ret.put(Keys.STATUS_CODE, HttpServletResponse.SC_FORBIDDEN); ret.put(Keys.MSG, "Wrong key"); return; } final String articleId = symphonyCmt.getString("commentOnArticleId"); final JSONObject article = articleRepository.get(articleId); if (null == article) { ret.put(Keys.STATUS_CODE, HttpServletResponse.SC_NOT_FOUND); ret.put(Keys.MSG, "Not found the specified article[id=" + articleId + "]"); return; } final String commentName = symphonyCmt.getString("commentAuthorName"); final String commentEmail = symphonyCmt.getString("commentAuthorEmail").trim().toLowerCase(); String commentURL = symphonyCmt.optString("commentAuthorURL"); if (!commentURL.contains("://")) { commentURL = "http://" + commentURL; } try { new URL(commentURL); } catch (final MalformedURLException e) { LOGGER.log(Level.WARN, "The comment URL is invalid [{0}]", commentURL); commentURL = ""; } final String commentThumbnailURL = symphonyCmt.getString("commentAuthorThumbnailURL"); final String commentId = symphonyCmt.optString(Keys.OBJECT_ID); String commentContent = symphonyCmt.getString(Comment.COMMENT_CONTENT); // commentContent += "<p class='cmtFromSym'><i>? <a href='" + SoloServletListener.B3LOG_SYMPHONY_SERVE_PATH // + "/article/" + symphonyCmt.optString("commentSymphonyArticleId") + "#" + commentId // + "' target='_blank'></a></i></p>"; final String originalCommentId = symphonyCmt.optString(Comment.COMMENT_ORIGINAL_COMMENT_ID); // Step 1: Add comment final JSONObject comment = new JSONObject(); JSONObject originalComment = null; comment.put(Keys.OBJECT_ID, commentId); comment.put(Comment.COMMENT_NAME, commentName); comment.put(Comment.COMMENT_EMAIL, commentEmail); comment.put(Comment.COMMENT_URL, commentURL); comment.put(Comment.COMMENT_THUMBNAIL_URL, commentThumbnailURL); comment.put(Comment.COMMENT_CONTENT, commentContent); final Date date = new Date(); comment.put(Comment.COMMENT_CREATED, date.getTime()); ret.put(Comment.COMMENT_T_DATE, DateFormatUtils.format(date, "yyyy-MM-dd HH:mm:ss")); if (StringUtils.isNotBlank(originalCommentId)) { originalComment = commentRepository.get(originalCommentId); if (null != originalComment) { comment.put(Comment.COMMENT_ORIGINAL_COMMENT_ID, originalCommentId); final String originalCommentName = originalComment.getString(Comment.COMMENT_NAME); comment.put(Comment.COMMENT_ORIGINAL_COMMENT_NAME, originalCommentName); ret.put(Comment.COMMENT_ORIGINAL_COMMENT_NAME, originalCommentName); } else { comment.put(Comment.COMMENT_ORIGINAL_COMMENT_ID, ""); comment.put(Comment.COMMENT_ORIGINAL_COMMENT_NAME, ""); LOGGER.log(Level.WARN, "Not found orginal comment[id={0}] of reply[name={1}, content={2}]", originalCommentId, commentName, commentContent); } } else { comment.put(Comment.COMMENT_ORIGINAL_COMMENT_ID, ""); comment.put(Comment.COMMENT_ORIGINAL_COMMENT_NAME, ""); } ret.put(Comment.COMMENT_THUMBNAIL_URL, comment.getString(Comment.COMMENT_THUMBNAIL_URL)); // Sets comment on article.... comment.put(Comment.COMMENT_ON_ID, articleId); comment.put(Comment.COMMENT_ON_TYPE, Article.ARTICLE); final String commentSharpURL = Comment.getCommentSharpURLForArticle(article, commentId); comment.put(Comment.COMMENT_SHARP_URL, commentSharpURL); commentRepository.add(comment); // Step 2: Update article comment count articleMgmtService.incArticleCommentCount(articleId); // Step 3: Update blog statistic comment count statisticMgmtService.incBlogCommentCount(); statisticMgmtService.incPublishedBlogCommentCount(); // Step 4: Send an email to admin try { commentMgmtService.sendNotificationMail(article, comment, originalComment, preference); } catch (final Exception e) { LOGGER.log(Level.WARN, "Send mail failed", e); } // Step 5: Fire add comment event final JSONObject eventData = new JSONObject(); eventData.put(Comment.COMMENT, comment); eventData.put(Article.ARTICLE, article); eventManager.fireEventSynchronously( new Event<>(EventTypes.ADD_COMMENT_TO_ARTICLE_FROM_SYMPHONY, eventData)); transaction.commit(); ret.put(Keys.STATUS_CODE, true); ret.put(Keys.OBJECT_ID, commentId); ret.put(Keys.OBJECT_ID, articleId); ret.put(Keys.MSG, "add a comment to an article from symphony succ"); ret.put(Keys.STATUS_CODE, true); renderer.setJSONObject(ret); } catch (final Exception e) { LOGGER.log(Level.ERROR, e.getMessage(), e); final JSONObject jsonObject = new JSONObject().put(Keys.STATUS_CODE, false); renderer.setJSONObject(jsonObject); jsonObject.put(Keys.MSG, e.getMessage()); } } }