/* * Symphony - A modern community (forum/SNS/blog) platform written in Java. * Copyright (C) 2012-2017, b3log.org & hacpai.com * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU 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.b3log.symphony.processor; import org.b3log.latke.Keys; import org.b3log.latke.Latkes; import org.b3log.latke.ioc.inject.Inject; import org.b3log.latke.logging.Logger; import org.b3log.latke.model.Pagination; import org.b3log.latke.model.User; import org.b3log.latke.servlet.HTTPRequestContext; import org.b3log.latke.servlet.HTTPRequestMethod; import org.b3log.latke.servlet.annotation.After; import org.b3log.latke.servlet.annotation.Before; import org.b3log.latke.servlet.annotation.RequestProcessing; import org.b3log.latke.servlet.annotation.RequestProcessor; import org.b3log.latke.servlet.renderer.freemarker.AbstractFreeMarkerRenderer; import org.b3log.latke.util.Paginator; import org.b3log.latke.util.Requests; import org.b3log.latke.util.Strings; import org.b3log.symphony.model.*; import org.b3log.symphony.processor.advice.LoginCheck; import org.b3log.symphony.processor.advice.PermissionGrant; import org.b3log.symphony.processor.advice.stopwatch.StopwatchEndAdvice; import org.b3log.symphony.processor.advice.stopwatch.StopwatchStartAdvice; import org.b3log.symphony.service.DataModelService; import org.b3log.symphony.service.NotificationMgmtService; import org.b3log.symphony.service.NotificationQueryService; import org.b3log.symphony.service.UserQueryService; import org.b3log.symphony.util.Symphonys; import org.json.JSONObject; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.*; /** * Notification processor. * <p> * <ul> * <li>Displays comments of my articles (/notifications/commented), GET</li> * <li>Displays replies of my comments (/notifications/reply), GET</li> * <li>Displays at me (/notifications/at), GET</li> * <li>Displays following user's articles (/notifications/following-user), * GET</li> * <li>Makes article/comment read (/notification/read), GET</li> * </ul> * </p> * * @author <a href="http://88250.b3log.org">Liang Ding</a> * @author <a href="http://vanessa.b3log.org">Liyuan Lo</a> * @version 1.10.1.9, Mar 12, 2017 * @since 0.2.5 */ @RequestProcessor public class NotificationProcessor { /** * Logger. */ private static final Logger LOGGER = Logger.getLogger(NotificationProcessor.class); /** * User query service. */ @Inject private UserQueryService userQueryService; /** * Notification query service. */ @Inject private NotificationQueryService notificationQueryService; /** * Notification management service. */ @Inject private NotificationMgmtService notificationMgmtService; /** * Data model service. */ @Inject private DataModelService dataModelService; /** * Shows [sysAnnounce] notifications. * * @param context the specified context * @param request the specified request * @param response the specified response * @throws Exception exception */ @RequestProcessing(value = "/notifications/sys-announce", method = HTTPRequestMethod.GET) @Before(adviceClass = {StopwatchStartAdvice.class, LoginCheck.class}) @After(adviceClass = {PermissionGrant.class, StopwatchEndAdvice.class}) public void showSysAnnounceNotifications(final HTTPRequestContext context, final HttpServletRequest request, final HttpServletResponse response) throws Exception { final JSONObject currentUser = (JSONObject) request.getAttribute(User.USER); final AbstractFreeMarkerRenderer renderer = new SkinRenderer(request); context.setRenderer(renderer); renderer.setTemplateName("/home/notifications/sys-announce.ftl"); final Map<String, Object> dataModel = renderer.getDataModel(); final String userId = currentUser.optString(Keys.OBJECT_ID); String pageNumStr = request.getParameter("p"); if (Strings.isEmptyOrNull(pageNumStr) || !Strings.isNumeric(pageNumStr)) { pageNumStr = "1"; } final int pageNum = Integer.valueOf(pageNumStr); final int pageSize = Symphonys.getInt("sysAnnounceNotificationsCnt"); final int windowSize = Symphonys.getInt("sysAnnounceNotificationsWindowSize"); final int avatarViewMode = (int) request.getAttribute(UserExt.USER_AVATAR_VIEW_MODE); final JSONObject result = notificationQueryService.getSysAnnounceNotifications( avatarViewMode, userId, pageNum, pageSize); final List<JSONObject> notifications = (List<JSONObject>) result.get(Keys.RESULTS); dataModel.put(Common.SYS_ANNOUNCE_NOTIFICATIONS, notifications); fillNotificationCount(userId, dataModel); notificationMgmtService.makeRead(notifications); final int recordCnt = result.getInt(Pagination.PAGINATION_RECORD_COUNT); final int pageCount = (int) Math.ceil((double) recordCnt / (double) pageSize); final List<Integer> pageNums = Paginator.paginate(pageNum, pageSize, pageCount, windowSize); if (!pageNums.isEmpty()) { dataModel.put(Pagination.PAGINATION_FIRST_PAGE_NUM, pageNums.get(0)); dataModel.put(Pagination.PAGINATION_LAST_PAGE_NUM, pageNums.get(pageNums.size() - 1)); } dataModel.put(Pagination.PAGINATION_CURRENT_PAGE_NUM, pageNum); dataModel.put(Pagination.PAGINATION_PAGE_COUNT, pageCount); dataModel.put(Pagination.PAGINATION_PAGE_NUMS, pageNums); dataModelService.fillHeaderAndFooter(request, response, dataModel); } /** * Makes all notifications as read. * * @param context the specified context * @param request the specified request * @param response the specified response * @throws Exception exception */ @RequestProcessing(value = "/notification/all-read", method = HTTPRequestMethod.GET) @Before(adviceClass = {StopwatchStartAdvice.class, LoginCheck.class}) @After(adviceClass = StopwatchEndAdvice.class) public void makeAllNotificationsRead(final HTTPRequestContext context, final HttpServletRequest request, final HttpServletResponse response) throws Exception { final JSONObject currentUser = userQueryService.getCurrentUser(request); if (null == currentUser) { response.sendError(HttpServletResponse.SC_FORBIDDEN); return; } final String userId = currentUser.optString(Keys.OBJECT_ID); notificationMgmtService.makeAllRead(userId); context.renderJSON(true); } /** * Makes the specified type notifications as read. * * @param context the specified context * @param request the specified request * @param response the specified response * @param type the specified type: "commented"/"at"/"following" * @throws Exception exception */ @RequestProcessing(value = "/notification/read/{type}", method = HTTPRequestMethod.GET) @Before(adviceClass = {StopwatchStartAdvice.class, LoginCheck.class}) @After(adviceClass = StopwatchEndAdvice.class) public void makeNotificationRead(final HTTPRequestContext context, final HttpServletRequest request, final HttpServletResponse response, final String type) throws Exception { final JSONObject currentUser = userQueryService.getCurrentUser(request); if (null == currentUser) { response.sendError(HttpServletResponse.SC_FORBIDDEN); return; } final String userId = currentUser.optString(Keys.OBJECT_ID); switch (type) { case "commented": notificationMgmtService.makeRead(userId, Notification.DATA_TYPE_C_COMMENTED); break; case "reply": notificationMgmtService.makeRead(userId, Notification.DATA_TYPE_C_REPLY); break; case "at": notificationMgmtService.makeRead(userId, Notification.DATA_TYPE_C_AT); notificationMgmtService.makeRead(userId, Notification.DATA_TYPE_C_ARTICLE_NEW_FOLLOWER); notificationMgmtService.makeRead(userId, Notification.DATA_TYPE_C_ARTICLE_NEW_WATCHER); notificationMgmtService.makeRead(userId, Notification.DATA_TYPE_C_COMMENT_VOTE_UP); notificationMgmtService.makeRead(userId, Notification.DATA_TYPE_C_COMMENT_VOTE_DOWN); notificationMgmtService.makeRead(userId, Notification.DATA_TYPE_C_ARTICLE_VOTE_UP); notificationMgmtService.makeRead(userId, Notification.DATA_TYPE_C_ARTICLE_VOTE_DOWN); break; case "following": notificationMgmtService.makeRead(userId, Notification.DATA_TYPE_C_FOLLOWING_USER); notificationMgmtService.makeRead(userId, Notification.DATA_TYPE_C_FOLLOWING_ARTICLE_UPDATE); notificationMgmtService.makeRead(userId, Notification.DATA_TYPE_C_FOLLOWING_ARTICLE_COMMENT); break; default: context.renderJSON(false); return; } context.renderJSON(true); } /** * Makes article/comment read. * * @param context the specified context * @param request the specified request * @param response the specified response * @throws Exception exception */ @RequestProcessing(value = "/notification/read", method = HTTPRequestMethod.POST) @Before(adviceClass = {StopwatchStartAdvice.class, LoginCheck.class}) @After(adviceClass = StopwatchEndAdvice.class) public void makeNotificationRead(final HTTPRequestContext context, final HttpServletRequest request, final HttpServletResponse response) throws Exception { final JSONObject currentUser = userQueryService.getCurrentUser(request); if (null == currentUser) { response.sendError(HttpServletResponse.SC_FORBIDDEN); return; } JSONObject requestJSONObject; try { requestJSONObject = Requests.parseRequestJSONObject(request, response); } catch (final IOException | ServletException e) { LOGGER.error(e.getMessage()); context.renderJSON(false); return; } final String userId = currentUser.optString(Keys.OBJECT_ID); final String articleId = requestJSONObject.optString(Article.ARTICLE_T_ID); final List<String> commentIds = Arrays.asList(requestJSONObject.optString(Comment.COMMENT_T_IDS).split(",")); notificationMgmtService.makeRead(userId, articleId, commentIds); context.renderJSON(true); } /** * Navigates notifications. * * @param context the specified context * @param request the specified request * @param response the specified response * @throws Exception exception */ @RequestProcessing(value = "/notifications", method = HTTPRequestMethod.GET) @Before(adviceClass = {StopwatchStartAdvice.class, LoginCheck.class}) @After(adviceClass = StopwatchEndAdvice.class) public void navigateNotifications(final HTTPRequestContext context, final HttpServletRequest request, final HttpServletResponse response) throws Exception { final JSONObject currentUser = userQueryService.getCurrentUser(request); if (null == currentUser) { response.sendError(HttpServletResponse.SC_FORBIDDEN); return; } final String userId = currentUser.optString(Keys.OBJECT_ID); final int unreadCommentedNotificationCnt = notificationQueryService.getUnreadNotificationCountByType(userId, Notification.DATA_TYPE_C_COMMENTED); if (unreadCommentedNotificationCnt > 0) { response.sendRedirect(Latkes.getServePath() + "/notifications/commented"); return; } final int unreadReplyNotificationCnt = notificationQueryService.getUnreadNotificationCountByType(userId, Notification.DATA_TYPE_C_REPLY); if (unreadReplyNotificationCnt > 0) { response.sendRedirect(Latkes.getServePath() + "/notifications/reply"); return; } final int unreadAtNotificationCnt = notificationQueryService.getUnreadNotificationCountByType(userId, Notification.DATA_TYPE_C_AT) + notificationQueryService.getUnreadNotificationCountByType(userId, Notification.DATA_TYPE_C_ARTICLE_NEW_FOLLOWER) + notificationQueryService.getUnreadNotificationCountByType(userId, Notification.DATA_TYPE_C_ARTICLE_NEW_WATCHER) + notificationQueryService.getUnreadNotificationCountByType(userId, Notification.DATA_TYPE_C_COMMENT_VOTE_UP) + notificationQueryService.getUnreadNotificationCountByType(userId, Notification.DATA_TYPE_C_COMMENT_VOTE_DOWN) + notificationQueryService.getUnreadNotificationCountByType(userId, Notification.DATA_TYPE_C_ARTICLE_VOTE_UP) + notificationQueryService.getUnreadNotificationCountByType(userId, Notification.DATA_TYPE_C_ARTICLE_VOTE_DOWN); if (unreadAtNotificationCnt > 0) { response.sendRedirect(Latkes.getServePath() + "/notifications/at"); return; } final int unreadPointNotificationCnt = notificationQueryService.getUnreadPointNotificationCount(userId); if (unreadPointNotificationCnt > 0) { response.sendRedirect(Latkes.getServePath() + "/notifications/point"); return; } final int unreadFollowingNotificationCnt = notificationQueryService.getUnreadFollowingNotificationCount(userId); if (unreadFollowingNotificationCnt > 0) { response.sendRedirect(Latkes.getServePath() + "/notifications/following"); return; } final int unreadBroadcastCnt = notificationQueryService.getUnreadNotificationCountByType(userId, Notification.DATA_TYPE_C_BROADCAST); if (unreadBroadcastCnt > 0) { response.sendRedirect(Latkes.getServePath() + "/notifications/broadcast"); return; } final int unreadSysAnnounceCnt = notificationQueryService.getUnreadSysAnnounceNotificationCount(userId); if (unreadSysAnnounceCnt > 0) { response.sendRedirect(Latkes.getServePath() + "/notifications/sys-announce"); return; } response.sendRedirect(Latkes.getServePath() + "/notifications/commented"); } /** * Shows [point] notifications. * * @param context the specified context * @param request the specified request * @param response the specified response * @throws Exception exception */ @RequestProcessing(value = "/notifications/point", method = HTTPRequestMethod.GET) @Before(adviceClass = {StopwatchStartAdvice.class, LoginCheck.class}) @After(adviceClass = {PermissionGrant.class, StopwatchEndAdvice.class}) public void showPointNotifications(final HTTPRequestContext context, final HttpServletRequest request, final HttpServletResponse response) throws Exception { final JSONObject currentUser = userQueryService.getCurrentUser(request); if (null == currentUser) { response.sendError(HttpServletResponse.SC_FORBIDDEN); return; } final AbstractFreeMarkerRenderer renderer = new SkinRenderer(request); context.setRenderer(renderer); renderer.setTemplateName("/home/notifications/point.ftl"); final Map<String, Object> dataModel = renderer.getDataModel(); final String userId = currentUser.optString(Keys.OBJECT_ID); String pageNumStr = request.getParameter("p"); if (Strings.isEmptyOrNull(pageNumStr) || !Strings.isNumeric(pageNumStr)) { pageNumStr = "1"; } final int pageNum = Integer.valueOf(pageNumStr); final int pageSize = Symphonys.getInt("pointNotificationsCnt"); final int windowSize = Symphonys.getInt("pointNotificationsWindowSize"); final JSONObject result = notificationQueryService.getPointNotifications(userId, pageNum, pageSize); final List<JSONObject> pointNotifications = (List<JSONObject>) result.get(Keys.RESULTS); dataModel.put(Common.POINT_NOTIFICATIONS, pointNotifications); fillNotificationCount(userId, dataModel); notificationMgmtService.makeRead(pointNotifications); final int recordCnt = result.getInt(Pagination.PAGINATION_RECORD_COUNT); final int pageCount = (int) Math.ceil((double) recordCnt / (double) pageSize); final List<Integer> pageNums = Paginator.paginate(pageNum, pageSize, pageCount, windowSize); if (!pageNums.isEmpty()) { dataModel.put(Pagination.PAGINATION_FIRST_PAGE_NUM, pageNums.get(0)); dataModel.put(Pagination.PAGINATION_LAST_PAGE_NUM, pageNums.get(pageNums.size() - 1)); } dataModel.put(Pagination.PAGINATION_CURRENT_PAGE_NUM, pageNum); dataModel.put(Pagination.PAGINATION_PAGE_COUNT, pageCount); dataModel.put(Pagination.PAGINATION_PAGE_NUMS, pageNums); dataModelService.fillHeaderAndFooter(request, response, dataModel); } /** * Fills notification count. * * @param userId the specified user id * @param dataModel the specified data model */ private void fillNotificationCount(final String userId, final Map<String, Object> dataModel) { final int unreadCommentedNotificationCnt = notificationQueryService.getUnreadNotificationCountByType(userId, Notification.DATA_TYPE_C_COMMENTED); dataModel.put(Common.UNREAD_COMMENTED_NOTIFICATION_CNT, unreadCommentedNotificationCnt); final int unreadReplyNotificationCnt = notificationQueryService.getUnreadNotificationCountByType(userId, Notification.DATA_TYPE_C_REPLY); dataModel.put(Common.UNREAD_REPLY_NOTIFICATION_CNT, unreadReplyNotificationCnt); final int unreadAtNotificationCnt = notificationQueryService.getUnreadNotificationCountByType(userId, Notification.DATA_TYPE_C_AT) + notificationQueryService.getUnreadNotificationCountByType(userId, Notification.DATA_TYPE_C_ARTICLE_NEW_FOLLOWER) + notificationQueryService.getUnreadNotificationCountByType(userId, Notification.DATA_TYPE_C_ARTICLE_NEW_WATCHER) + notificationQueryService.getUnreadNotificationCountByType(userId, Notification.DATA_TYPE_C_COMMENT_VOTE_UP) + notificationQueryService.getUnreadNotificationCountByType(userId, Notification.DATA_TYPE_C_COMMENT_VOTE_DOWN) + notificationQueryService.getUnreadNotificationCountByType(userId, Notification.DATA_TYPE_C_ARTICLE_VOTE_UP) + notificationQueryService.getUnreadNotificationCountByType(userId, Notification.DATA_TYPE_C_ARTICLE_VOTE_DOWN); dataModel.put(Common.UNREAD_AT_NOTIFICATION_CNT, unreadAtNotificationCnt); final int unreadFollowingNotificationCnt = notificationQueryService.getUnreadFollowingNotificationCount(userId); dataModel.put(Common.UNREAD_FOLLOWING_NOTIFICATION_CNT, unreadFollowingNotificationCnt); final int unreadPointNotificationCnt = notificationQueryService.getUnreadPointNotificationCount(userId); dataModel.put(Common.UNREAD_POINT_NOTIFICATION_CNT, unreadPointNotificationCnt); final int unreadBroadcastNotificationCnt = notificationQueryService.getUnreadNotificationCountByType(userId, Notification.DATA_TYPE_C_BROADCAST); dataModel.put(Common.UNREAD_BROADCAST_NOTIFICATION_CNT, unreadBroadcastNotificationCnt); final int unreadSysAnnounceNotificationCnt = notificationQueryService.getUnreadSysAnnounceNotificationCount(userId); dataModel.put(Common.UNREAD_SYS_ANNOUNCE_NOTIFICATION_CNT, unreadSysAnnounceNotificationCnt); final int unreadNewFollowerNotificationCnt = notificationQueryService.getUnreadNotificationCountByType( userId, Notification.DATA_TYPE_C_NEW_FOLLOWER); dataModel.put(Common.UNREAD_NEW_FOLLOWER_NOTIFICATION_CNT, unreadNewFollowerNotificationCnt); dataModel.put(Common.UNREAD_NOTIFICATION_CNT, unreadAtNotificationCnt + unreadBroadcastNotificationCnt + unreadCommentedNotificationCnt + unreadFollowingNotificationCnt + unreadPointNotificationCnt + unreadReplyNotificationCnt + unreadSysAnnounceNotificationCnt + unreadNewFollowerNotificationCnt); } /** * Shows [commented] notifications. * * @param context the specified context * @param request the specified request * @param response the specified response * @throws Exception exception */ @RequestProcessing(value = "/notifications/commented", method = HTTPRequestMethod.GET) @Before(adviceClass = {StopwatchStartAdvice.class, LoginCheck.class}) @After(adviceClass = {PermissionGrant.class, StopwatchEndAdvice.class}) public void showCommentedNotifications(final HTTPRequestContext context, final HttpServletRequest request, final HttpServletResponse response) throws Exception { final JSONObject currentUser = userQueryService.getCurrentUser(request); if (null == currentUser) { response.sendError(HttpServletResponse.SC_FORBIDDEN); return; } final AbstractFreeMarkerRenderer renderer = new SkinRenderer(request); context.setRenderer(renderer); renderer.setTemplateName("/home/notifications/commented.ftl"); final Map<String, Object> dataModel = renderer.getDataModel(); final String userId = currentUser.optString(Keys.OBJECT_ID); String pageNumStr = request.getParameter("p"); if (Strings.isEmptyOrNull(pageNumStr) || !Strings.isNumeric(pageNumStr)) { pageNumStr = "1"; } final int pageNum = Integer.valueOf(pageNumStr); final int pageSize = Symphonys.getInt("commentedNotificationsCnt"); final int windowSize = Symphonys.getInt("commentedNotificationsWindowSize"); final int avatarViewMode = (int) request.getAttribute(UserExt.USER_AVATAR_VIEW_MODE); final JSONObject result = notificationQueryService.getCommentedNotifications( avatarViewMode, userId, pageNum, pageSize); final List<JSONObject> commentedNotifications = (List<JSONObject>) result.get(Keys.RESULTS); dataModel.put(Common.COMMENTED_NOTIFICATIONS, commentedNotifications); fillNotificationCount(userId, dataModel); final int recordCnt = result.getInt(Pagination.PAGINATION_RECORD_COUNT); final int pageCount = (int) Math.ceil((double) recordCnt / (double) pageSize); final List<Integer> pageNums = Paginator.paginate(pageNum, pageSize, pageCount, windowSize); if (!pageNums.isEmpty()) { dataModel.put(Pagination.PAGINATION_FIRST_PAGE_NUM, pageNums.get(0)); dataModel.put(Pagination.PAGINATION_LAST_PAGE_NUM, pageNums.get(pageNums.size() - 1)); } dataModel.put(Pagination.PAGINATION_CURRENT_PAGE_NUM, pageNum); dataModel.put(Pagination.PAGINATION_PAGE_COUNT, pageCount); dataModel.put(Pagination.PAGINATION_PAGE_NUMS, pageNums); dataModelService.fillHeaderAndFooter(request, response, dataModel); } /** * Shows [reply] notifications. * * @param context the specified context * @param request the specified request * @param response the specified response * @throws Exception exception */ @RequestProcessing(value = "/notifications/reply", method = HTTPRequestMethod.GET) @Before(adviceClass = {StopwatchStartAdvice.class, LoginCheck.class}) @After(adviceClass = {PermissionGrant.class, StopwatchEndAdvice.class}) public void showReplyNotifications(final HTTPRequestContext context, final HttpServletRequest request, final HttpServletResponse response) throws Exception { final JSONObject currentUser = userQueryService.getCurrentUser(request); if (null == currentUser) { response.sendError(HttpServletResponse.SC_FORBIDDEN); return; } final AbstractFreeMarkerRenderer renderer = new SkinRenderer(request); context.setRenderer(renderer); renderer.setTemplateName("/home/notifications/reply.ftl"); final Map<String, Object> dataModel = renderer.getDataModel(); final String userId = currentUser.optString(Keys.OBJECT_ID); String pageNumStr = request.getParameter("p"); if (Strings.isEmptyOrNull(pageNumStr) || !Strings.isNumeric(pageNumStr)) { pageNumStr = "1"; } final int pageNum = Integer.valueOf(pageNumStr); final int pageSize = Symphonys.getInt("replyNotificationsCnt"); final int windowSize = Symphonys.getInt("replyNotificationsWindowSize"); final int avatarViewMode = (int) request.getAttribute(UserExt.USER_AVATAR_VIEW_MODE); final JSONObject result = notificationQueryService.getReplyNotifications( avatarViewMode, userId, pageNum, pageSize); final List<JSONObject> replyNotifications = (List<JSONObject>) result.get(Keys.RESULTS); dataModel.put(Common.REPLY_NOTIFICATIONS, replyNotifications); fillNotificationCount(userId, dataModel); final int recordCnt = result.getInt(Pagination.PAGINATION_RECORD_COUNT); final int pageCount = (int) Math.ceil((double) recordCnt / (double) pageSize); final List<Integer> pageNums = Paginator.paginate(pageNum, pageSize, pageCount, windowSize); if (!pageNums.isEmpty()) { dataModel.put(Pagination.PAGINATION_FIRST_PAGE_NUM, pageNums.get(0)); dataModel.put(Pagination.PAGINATION_LAST_PAGE_NUM, pageNums.get(pageNums.size() - 1)); } dataModel.put(Pagination.PAGINATION_CURRENT_PAGE_NUM, pageNum); dataModel.put(Pagination.PAGINATION_PAGE_COUNT, pageCount); dataModel.put(Pagination.PAGINATION_PAGE_NUMS, pageNums); dataModelService.fillHeaderAndFooter(request, response, dataModel); } /** * Shows [at] notifications. * * @param context the specified context * @param request the specified request * @param response the specified response * @throws Exception exception */ @RequestProcessing(value = "/notifications/at", method = HTTPRequestMethod.GET) @Before(adviceClass = {StopwatchStartAdvice.class, LoginCheck.class}) @After(adviceClass = {PermissionGrant.class, StopwatchEndAdvice.class}) public void showAtNotifications(final HTTPRequestContext context, final HttpServletRequest request, final HttpServletResponse response) throws Exception { final JSONObject currentUser = userQueryService.getCurrentUser(request); if (null == currentUser) { response.sendError(HttpServletResponse.SC_FORBIDDEN); return; } final AbstractFreeMarkerRenderer renderer = new SkinRenderer(request); context.setRenderer(renderer); renderer.setTemplateName("/home/notifications/at.ftl"); final Map<String, Object> dataModel = renderer.getDataModel(); final String userId = currentUser.optString(Keys.OBJECT_ID); String pageNumStr = request.getParameter("p"); if (Strings.isEmptyOrNull(pageNumStr) || !Strings.isNumeric(pageNumStr)) { pageNumStr = "1"; } final int pageNum = Integer.valueOf(pageNumStr); final int pageSize = Symphonys.getInt("atNotificationsCnt"); final int windowSize = Symphonys.getInt("atNotificationsWindowSize"); final int avatarViewMode = (int) request.getAttribute(UserExt.USER_AVATAR_VIEW_MODE); final JSONObject result = notificationQueryService.getAtNotifications(avatarViewMode, userId, pageNum, pageSize); final List<JSONObject> atNotifications = (List<JSONObject>) result.get(Keys.RESULTS); dataModel.put(Common.AT_NOTIFICATIONS, atNotifications); final List<JSONObject> articleFollowAndWatchNotifications = new ArrayList<>(); for (final JSONObject notification : atNotifications) { if (Notification.DATA_TYPE_C_AT != notification.optInt(Notification.NOTIFICATION_DATA_TYPE)) { articleFollowAndWatchNotifications.add(notification); } } notificationMgmtService.makeRead(articleFollowAndWatchNotifications); fillNotificationCount(userId, dataModel); final int recordCnt = result.getInt(Pagination.PAGINATION_RECORD_COUNT); final int pageCount = (int) Math.ceil((double) recordCnt / (double) pageSize); final List<Integer> pageNums = Paginator.paginate(pageNum, pageSize, pageCount, windowSize); if (!pageNums.isEmpty()) { dataModel.put(Pagination.PAGINATION_FIRST_PAGE_NUM, pageNums.get(0)); dataModel.put(Pagination.PAGINATION_LAST_PAGE_NUM, pageNums.get(pageNums.size() - 1)); } dataModel.put(Pagination.PAGINATION_CURRENT_PAGE_NUM, pageNum); dataModel.put(Pagination.PAGINATION_PAGE_COUNT, pageCount); dataModel.put(Pagination.PAGINATION_PAGE_NUMS, pageNums); dataModelService.fillHeaderAndFooter(request, response, dataModel); } /** * Shows [following] notifications. * * @param context the specified context * @param request the specified request * @param response the specified response * @throws Exception exception */ @RequestProcessing(value = "/notifications/following", method = HTTPRequestMethod.GET) @Before(adviceClass = {StopwatchStartAdvice.class, LoginCheck.class}) @After(adviceClass = {PermissionGrant.class, StopwatchEndAdvice.class}) public void showFollowingNotifications(final HTTPRequestContext context, final HttpServletRequest request, final HttpServletResponse response) throws Exception { final JSONObject currentUser = userQueryService.getCurrentUser(request); if (null == currentUser) { response.sendError(HttpServletResponse.SC_FORBIDDEN); return; } final AbstractFreeMarkerRenderer renderer = new SkinRenderer(request); context.setRenderer(renderer); renderer.setTemplateName("/home/notifications/following.ftl"); final Map<String, Object> dataModel = renderer.getDataModel(); final String userId = currentUser.optString(Keys.OBJECT_ID); String pageNumStr = request.getParameter("p"); if (Strings.isEmptyOrNull(pageNumStr) || !Strings.isNumeric(pageNumStr)) { pageNumStr = "1"; } final int pageNum = Integer.valueOf(pageNumStr); final int pageSize = Symphonys.getInt("followingNotificationsCnt"); final int windowSize = Symphonys.getInt("followingNotificationsWindowSize"); final int avatarViewMode = (int) request.getAttribute(UserExt.USER_AVATAR_VIEW_MODE); final JSONObject result = notificationQueryService.getFollowingNotifications( avatarViewMode, userId, pageNum, pageSize); final List<JSONObject> followingNotifications = (List<JSONObject>) result.get(Keys.RESULTS); dataModel.put(Common.FOLLOWING_NOTIFICATIONS, followingNotifications); fillNotificationCount(userId, dataModel); final int recordCnt = result.getInt(Pagination.PAGINATION_RECORD_COUNT); final int pageCount = (int) Math.ceil((double) recordCnt / (double) pageSize); final List<Integer> pageNums = Paginator.paginate(pageNum, pageSize, pageCount, windowSize); if (!pageNums.isEmpty()) { dataModel.put(Pagination.PAGINATION_FIRST_PAGE_NUM, pageNums.get(0)); dataModel.put(Pagination.PAGINATION_LAST_PAGE_NUM, pageNums.get(pageNums.size() - 1)); } dataModel.put(Pagination.PAGINATION_CURRENT_PAGE_NUM, pageNum); dataModel.put(Pagination.PAGINATION_PAGE_COUNT, pageCount); dataModel.put(Pagination.PAGINATION_PAGE_NUMS, pageNums); dataModelService.fillHeaderAndFooter(request, response, dataModel); } /** * Shows [broadcast] notifications. * * @param context the specified context * @param request the specified request * @param response the specified response * @throws Exception exception */ @RequestProcessing(value = "/notifications/broadcast", method = HTTPRequestMethod.GET) @Before(adviceClass = {StopwatchStartAdvice.class, LoginCheck.class}) @After(adviceClass = {PermissionGrant.class, StopwatchEndAdvice.class}) public void showBroadcastNotifications(final HTTPRequestContext context, final HttpServletRequest request, final HttpServletResponse response) throws Exception { final JSONObject currentUser = userQueryService.getCurrentUser(request); if (null == currentUser) { response.sendError(HttpServletResponse.SC_FORBIDDEN); return; } final AbstractFreeMarkerRenderer renderer = new SkinRenderer(request); context.setRenderer(renderer); renderer.setTemplateName("/home/notifications/broadcast.ftl"); final Map<String, Object> dataModel = renderer.getDataModel(); final String userId = currentUser.optString(Keys.OBJECT_ID); String pageNumStr = request.getParameter("p"); if (Strings.isEmptyOrNull(pageNumStr) || !Strings.isNumeric(pageNumStr)) { pageNumStr = "1"; } final int pageNum = Integer.valueOf(pageNumStr); final int pageSize = Symphonys.getInt("broadcastNotificationsCnt"); final int windowSize = Symphonys.getInt("broadcastNotificationsWindowSize"); final int avatarViewMode = (int) request.getAttribute(UserExt.USER_AVATAR_VIEW_MODE); final JSONObject result = notificationQueryService.getBroadcastNotifications( avatarViewMode, userId, pageNum, pageSize); final List<JSONObject> broadcastNotifications = (List<JSONObject>) result.get(Keys.RESULTS); dataModel.put(Common.BROADCAST_NOTIFICATIONS, broadcastNotifications); fillNotificationCount(userId, dataModel); final int recordCnt = result.getInt(Pagination.PAGINATION_RECORD_COUNT); final int pageCount = (int) Math.ceil((double) recordCnt / (double) pageSize); final List<Integer> pageNums = Paginator.paginate(pageNum, pageSize, pageCount, windowSize); if (!pageNums.isEmpty()) { dataModel.put(Pagination.PAGINATION_FIRST_PAGE_NUM, pageNums.get(0)); dataModel.put(Pagination.PAGINATION_LAST_PAGE_NUM, pageNums.get(pageNums.size() - 1)); } dataModel.put(Pagination.PAGINATION_CURRENT_PAGE_NUM, pageNum); dataModel.put(Pagination.PAGINATION_PAGE_COUNT, pageCount); dataModel.put(Pagination.PAGINATION_PAGE_NUMS, pageNums); dataModelService.fillHeaderAndFooter(request, response, dataModel); } /** * Gets unread count of notifications. * * @param context the specified context * @param request the specified request * @param response the specified response * @throws Exception exception */ @RequestProcessing(value = "/notification/unread/count", method = HTTPRequestMethod.GET) public void getUnreadNotificationCount(final HTTPRequestContext context, final HttpServletRequest request, final HttpServletResponse response) throws Exception { final JSONObject currentUser = userQueryService.getCurrentUser(request); if (null == currentUser) { response.sendError(HttpServletResponse.SC_FORBIDDEN); return; } final String userId = currentUser.optString(Keys.OBJECT_ID); final Map<String, Object> dataModel = new HashMap<>(); fillNotificationCount(userId, dataModel); context.renderJSON(new JSONObject(dataModel)).renderTrueResult(). renderJSONValue(UserExt.USER_NOTIFY_STATUS, currentUser.optInt(UserExt.USER_NOTIFY_STATUS)); } }