/* * 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.service; import org.b3log.latke.Keys; import org.b3log.latke.ioc.inject.Inject; import org.b3log.latke.logging.Level; import org.b3log.latke.logging.Logger; import org.b3log.latke.repository.*; import org.b3log.latke.repository.annotation.Transactional; import org.b3log.latke.service.ServiceException; import org.b3log.latke.service.annotation.Service; import org.b3log.latke.util.CollectionUtils; import org.b3log.symphony.model.Common; import org.b3log.symphony.model.Notification; import org.b3log.symphony.processor.channel.UserChannel; import org.b3log.symphony.repository.NotificationRepository; import org.b3log.symphony.util.Symphonys; import org.json.JSONObject; import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Set; /** * Notification management service. * * @author <a href="http://88250.b3log.org">Liang Ding</a> * @version 1.15.1.3, Mar 12, 2017 * @since 0.2.5 */ @Service public class NotificationMgmtService { /** * Logger. */ private static final Logger LOGGER = Logger.getLogger(NotificationMgmtService.class.getName()); /** * Notification repository. */ @Inject private NotificationRepository notificationRepository; /** * Add a 'article vote down' type notification with the specified request json object. * * @param requestJSONObject the specified request json object, for example, * "userId": "", * "dataId": "" // article id-vote user id * @throws ServiceException service exception */ @Transactional public void addArticleVoteDownNotification(final JSONObject requestJSONObject) throws ServiceException { try { requestJSONObject.put(Notification.NOTIFICATION_DATA_TYPE, Notification.DATA_TYPE_C_ARTICLE_VOTE_DOWN); addNotification(requestJSONObject); } catch (final RepositoryException e) { final String msg = "Adds notification [type=article_vote_down] failed"; LOGGER.log(Level.ERROR, msg, e); throw new ServiceException(msg); } } /** * Add a 'article vote up' type notification with the specified request json object. * * @param requestJSONObject the specified request json object, for example, * "userId": "", * "dataId": "" // article id-vote user id * @throws ServiceException service exception */ @Transactional public void addArticleVoteUpNotification(final JSONObject requestJSONObject) throws ServiceException { try { requestJSONObject.put(Notification.NOTIFICATION_DATA_TYPE, Notification.DATA_TYPE_C_ARTICLE_VOTE_UP); addNotification(requestJSONObject); } catch (final RepositoryException e) { final String msg = "Adds notification [type=article_vote_up] failed"; LOGGER.log(Level.ERROR, msg, e); throw new ServiceException(msg); } } /** * Add a 'comment vote down' type notification with the specified request json object. * * @param requestJSONObject the specified request json object, for example, * "userId": "", * "dataId": "" // comment id-vote user id * @throws ServiceException service exception */ @Transactional public void addCommentVoteDownNotification(final JSONObject requestJSONObject) throws ServiceException { try { requestJSONObject.put(Notification.NOTIFICATION_DATA_TYPE, Notification.DATA_TYPE_C_COMMENT_VOTE_DOWN); addNotification(requestJSONObject); } catch (final RepositoryException e) { final String msg = "Adds notification [type=comment_vote_down] failed"; LOGGER.log(Level.ERROR, msg, e); throw new ServiceException(msg); } } /** * Add a 'comment vote up' type notification with the specified request json object. * * @param requestJSONObject the specified request json object, for example, * "userId": "", * "dataId": "" // comment id-vote user id * @throws ServiceException service exception */ @Transactional public void addCommentVoteUpNotification(final JSONObject requestJSONObject) throws ServiceException { try { requestJSONObject.put(Notification.NOTIFICATION_DATA_TYPE, Notification.DATA_TYPE_C_COMMENT_VOTE_UP); addNotification(requestJSONObject); } catch (final RepositoryException e) { final String msg = "Adds notification [type=comment_vote_up] failed"; LOGGER.log(Level.ERROR, msg, e); throw new ServiceException(msg); } } /** * Add a 'article new watcher' type notification with the specified request json object. * * @param requestJSONObject the specified request json object, for example, * "userId": "", * "dataId": "" // article id-follower user id * @throws ServiceException service exception */ @Transactional public void addArticleNewWatcherNotification(final JSONObject requestJSONObject) throws ServiceException { try { requestJSONObject.put(Notification.NOTIFICATION_DATA_TYPE, Notification.DATA_TYPE_C_ARTICLE_NEW_WATCHER); addNotification(requestJSONObject); } catch (final RepositoryException e) { final String msg = "Adds notification [type=article_new_watcher] failed"; LOGGER.log(Level.ERROR, msg, e); throw new ServiceException(msg); } } /** * Add a 'article new follower' type notification with the specified request json object. * * @param requestJSONObject the specified request json object, for example, * "userId": "", * "dataId": "" // article id-follower user id * @throws ServiceException service exception */ @Transactional public void addArticleNewFollowerNotification(final JSONObject requestJSONObject) throws ServiceException { try { requestJSONObject.put(Notification.NOTIFICATION_DATA_TYPE, Notification.DATA_TYPE_C_ARTICLE_NEW_FOLLOWER); addNotification(requestJSONObject); } catch (final RepositoryException e) { final String msg = "Adds notification [type=article_new_follower] failed"; LOGGER.log(Level.ERROR, msg, e); throw new ServiceException(msg); } } /** * Add a 'point - perfect article' type notification with the specified request json object. * * @param requestJSONObject the specified request json object, for example, * "userId": "", * "dataId": "" // article id * @throws ServiceException service exception */ @Transactional public void addPerfectArticleNotification(final JSONObject requestJSONObject) throws ServiceException { try { requestJSONObject.put(Notification.NOTIFICATION_DATA_TYPE, Notification.DATA_TYPE_C_POINT_PERFECT_ARTICLE); addNotification(requestJSONObject); } catch (final RepositoryException e) { final String msg = "Adds notification [type=perfect_article] failed"; LOGGER.log(Level.ERROR, msg, e); throw new ServiceException(msg); } } /** * Adds a 'following - article comment' type notification with the specified request json object. * * @param requestJSONObject the specified request json object, for example, * "userId"; "", * "dataId": "" // comment id * @throws ServiceException service exception */ @Transactional public void addFollowingArticleCommentNotification(final JSONObject requestJSONObject) throws ServiceException { try { requestJSONObject.put(Notification.NOTIFICATION_DATA_TYPE, Notification.DATA_TYPE_C_FOLLOWING_ARTICLE_COMMENT); addNotification(requestJSONObject); } catch (final RepositoryException e) { final String msg = "Adds notification [type=following_article_comment] failed"; LOGGER.log(Level.ERROR, msg, e); throw new ServiceException(msg); } } /** * Adds a 'following - article update' type notification with the specified request json object. * * @param requestJSONObject the specified request json object, for example, * "userId"; "", * "dataId": "" // article id * @throws ServiceException service exception */ @Transactional public void addFollowingArticleUpdateNotification(final JSONObject requestJSONObject) throws ServiceException { try { requestJSONObject.put(Notification.NOTIFICATION_DATA_TYPE, Notification.DATA_TYPE_C_FOLLOWING_ARTICLE_UPDATE); addNotification(requestJSONObject); } catch (final RepositoryException e) { final String msg = "Adds notification [type=following_article_update] failed"; LOGGER.log(Level.ERROR, msg, e); throw new ServiceException(msg); } } /** * Adds a 'sys announce - role changed' type notification with the specified request json object. * * @param requestJSONObject the specified request json object, for example, * "userId"; "", * "dataId": "" // oldRoleId-newRoleId * @throws ServiceException service exception */ @Transactional public void addSysAnnounceRoleChangedNotification(final JSONObject requestJSONObject) throws ServiceException { try { requestJSONObject.put(Notification.NOTIFICATION_DATA_TYPE, Notification.DATA_TYPE_C_SYS_ANNOUNCE_ROLE_CHANGED); addNotification(requestJSONObject); } catch (final RepositoryException e) { final String msg = "Adds notification [type=sys_announce_role_changed] failed"; LOGGER.log(Level.ERROR, msg, e); throw new ServiceException(msg); } } /** * Adds a 'invitation link used' type notification with the specified request json object. * * @param requestJSONObject the specified request json object, for example, * "userId"; "", * "dataId": "" // invited user id * @throws ServiceException service exception */ @Transactional public void addInvitationLinkUsedNotification(final JSONObject requestJSONObject) throws ServiceException { try { requestJSONObject.put(Notification.NOTIFICATION_DATA_TYPE, Notification.DATA_TYPE_C_INVITATION_LINK_USED); addNotification(requestJSONObject); } catch (final RepositoryException e) { final String msg = "Adds notification [type=invitation_link_used] failed"; LOGGER.log(Level.ERROR, msg, e); throw new ServiceException(msg); } } /** * Adds a 'new follower' type notification with the specified request json object. * * @param requestJSONObject the specified request json object, for example, * "userId": "", * "dataId": "" // new follower id * @throws ServiceException service exception */ @Transactional public void addNewFollowerNotification(final JSONObject requestJSONObject) throws ServiceException { try { requestJSONObject.put(Notification.NOTIFICATION_DATA_TYPE, Notification.DATA_TYPE_C_NEW_FOLLOWER); addNotification(requestJSONObject); } catch (final RepositoryException e) { final String msg = "Adds notification [type=new_follower] failed"; LOGGER.log(Level.ERROR, msg, e); throw new ServiceException(msg); } } /** * Adds a 'sys announce - article' type notification with the specified request json object. * * @param requestJSONObject the specified request json object, for example, * "userId"; "", * "dataId": "" // article id * @throws ServiceException service exception */ @Transactional public void addSysAnnounceArticleNotification(final JSONObject requestJSONObject) throws ServiceException { try { requestJSONObject.put(Notification.NOTIFICATION_DATA_TYPE, Notification.DATA_TYPE_C_SYS_ANNOUNCE_ARTICLE); addNotification(requestJSONObject); } catch (final RepositoryException e) { final String msg = "Adds notification [type=sys_announce_article] failed"; LOGGER.log(Level.ERROR, msg, e); throw new ServiceException(msg); } } /** * Adds a 'sys announce - new user' type notification with the specified request json object. * * @param requestJSONObject the specified request json object, for example, * "userId"; "", * "dataId": "" // article id * @throws ServiceException service exception */ @Transactional public void addSysAnnounceNewUserNotification(final JSONObject requestJSONObject) throws ServiceException { try { requestJSONObject.put(Notification.NOTIFICATION_DATA_TYPE, Notification.DATA_TYPE_C_SYS_ANNOUNCE_NEW_USER); addNotification(requestJSONObject); } catch (final RepositoryException e) { final String msg = "Adds notification [type=sys_announce_new_user] failed"; LOGGER.log(Level.ERROR, msg, e); throw new ServiceException(msg); } } /** * Adds a 'invitecode used' type notification with the specified request json object. * * @param requestJSONObject the specified request json object, for example, * "userId"; "", * "dataId": "" // invited user id * @throws ServiceException service exception */ @Transactional public void addInvitecodeUsedNotification(final JSONObject requestJSONObject) throws ServiceException { try { requestJSONObject.put(Notification.NOTIFICATION_DATA_TYPE, Notification.DATA_TYPE_C_INVITECODE_USED); addNotification(requestJSONObject); } catch (final RepositoryException e) { final String msg = "Adds notification [type=invitecode_used] failed"; LOGGER.log(Level.ERROR, msg, e); throw new ServiceException(msg); } } /** * Makes the specified user's notifications of the specified type as read. * * @param userId the specified user id * @param type the specified notification type */ public void makeRead(final String userId, final int type) { final Query query = new Query().setFilter( CompositeFilterOperator.and( new PropertyFilter(Notification.NOTIFICATION_USER_ID, FilterOperator.EQUAL, userId), new PropertyFilter(Notification.NOTIFICATION_HAS_READ, FilterOperator.EQUAL, false), new PropertyFilter(Notification.NOTIFICATION_DATA_TYPE, FilterOperator.EQUAL, type))); try { final Set<JSONObject> notifications = CollectionUtils.jsonArrayToSet(notificationRepository.get(query). optJSONArray(Keys.RESULTS)); makeRead(notifications); } catch (final Exception e) { LOGGER.log(Level.ERROR, "Makes read failed", e); } } /** * Makes the specified user's all notifications as read. * * @param userId the specified user id */ public void makeAllRead(final String userId) { final Query query = new Query().setFilter( CompositeFilterOperator.and( new PropertyFilter(Notification.NOTIFICATION_USER_ID, FilterOperator.EQUAL, userId), new PropertyFilter(Notification.NOTIFICATION_HAS_READ, FilterOperator.EQUAL, false))); try { final Set<JSONObject> notifications = CollectionUtils.jsonArrayToSet(notificationRepository.get(query). optJSONArray(Keys.RESULTS)); makeRead(notifications); } catch (final Exception e) { LOGGER.log(Level.ERROR, "Makes read failed", e); } } /** * Makes the specified user to article, comments notifications as read. * * @param userId the specified user id * @param articleId the specified article id * @param commentIds the specified comment ids */ public void makeRead(final String userId, final String articleId, final List<String> commentIds) { final Set<String> dataIds = new HashSet<String>(commentIds); dataIds.add(articleId); final Query query = new Query().setFilter( CompositeFilterOperator.and( new PropertyFilter(Notification.NOTIFICATION_USER_ID, FilterOperator.EQUAL, userId), new PropertyFilter(Notification.NOTIFICATION_HAS_READ, FilterOperator.EQUAL, false), new PropertyFilter(Notification.NOTIFICATION_DATA_ID, FilterOperator.IN, dataIds))); try { final Set<JSONObject> notifications = CollectionUtils.jsonArrayToSet(notificationRepository.get(query). optJSONArray(Keys.RESULTS)); makeRead(notifications); } catch (final Exception e) { LOGGER.log(Level.ERROR, "Makes read failed", e); } } /** * Makes the specified notifications have been read. * * @param notifications the specified notifications * @throws ServiceException service exception */ @Transactional public void makeRead(final Collection<JSONObject> notifications) throws ServiceException { for (final JSONObject notification : notifications) { makeRead(notification); } } /** * Makes the specified notification have been read. * * @param notification the specified notification, return directly if this notification has been read * (notification.hasRead equals to {@code true}) * @throws ServiceException service exception */ @Transactional public void makeRead(final JSONObject notification) throws ServiceException { if (notification.optBoolean(Notification.NOTIFICATION_HAS_READ)) { return; } final String id = notification.optString(Keys.OBJECT_ID); try { final JSONObject record = notificationRepository.get(id); record.put(Notification.NOTIFICATION_HAS_READ, true); notificationRepository.update(id, record); } catch (final RepositoryException e) { final String msg = "Makes notification as read failed"; LOGGER.log(Level.ERROR, msg, e); throw new ServiceException(msg); } } /** * Adds a 'broadcast' type notification with the specified request json object. * * @param requestJSONObject the specified request json object, for example, * "userId"; "", * "dataId": "" // article id * @throws ServiceException service exception */ @Transactional public void addBroadcastNotification(final JSONObject requestJSONObject) throws ServiceException { try { requestJSONObject.put(Notification.NOTIFICATION_DATA_TYPE, Notification.DATA_TYPE_C_BROADCAST); addNotification(requestJSONObject); } catch (final RepositoryException e) { final String msg = "Adds notification [type=broadcast] failed"; LOGGER.log(Level.ERROR, msg, e); throw new ServiceException(msg); } } /** * Adds a 'point charge' type notification with the specified request json object. * * @param requestJSONObject the specified request json object, for example, * "userId"; "", * "dataId": "" // transfer record id * @throws ServiceException service exception */ @Transactional public void addPointChargeNotification(final JSONObject requestJSONObject) throws ServiceException { try { requestJSONObject.put(Notification.NOTIFICATION_DATA_TYPE, Notification.DATA_TYPE_C_POINT_CHARGE); addNotification(requestJSONObject); } catch (final RepositoryException e) { final String msg = "Adds notification [type=point_charge] failed"; LOGGER.log(Level.ERROR, msg, e); throw new ServiceException(msg); } } /** * Adds a 'abuse point deduct' type notification with the specified request json object. * * @param requestJSONObject the specified request json object, for example, * "userId"; "", * "dataId": "" // transfer record id * @throws ServiceException service exception */ @Transactional public void addAbusePointDeductNotification(final JSONObject requestJSONObject) throws ServiceException { try { requestJSONObject.put(Notification.NOTIFICATION_DATA_TYPE, Notification.DATA_TYPE_C_ABUSE_POINT_DEDUCT); addNotification(requestJSONObject); } catch (final RepositoryException e) { final String msg = "Adds notification [type=abuse_point_deduct] failed"; LOGGER.log(Level.ERROR, msg, e); throw new ServiceException(msg); } } /** * Adds a 'point exchange' type notification with the specified request json object. * * @param requestJSONObject the specified request json object, for example, * "userId"; "", * "dataId": "" // transfer record id * @throws ServiceException service exception */ @Transactional public void addPointExchangeNotification(final JSONObject requestJSONObject) throws ServiceException { try { requestJSONObject.put(Notification.NOTIFICATION_DATA_TYPE, Notification.DATA_TYPE_C_POINT_EXCHANGE); addNotification(requestJSONObject); } catch (final RepositoryException e) { final String msg = "Adds notification [type=point_exchange] failed"; LOGGER.log(Level.ERROR, msg, e); throw new ServiceException(msg); } } /** * Adds a 'point transfer' type notification with the specified request json object. * * @param requestJSONObject the specified request json object, for example, * "userId"; "", * "dataId": "" // transfer record id * @throws ServiceException service exception */ @Transactional public void addPointTransferNotification(final JSONObject requestJSONObject) throws ServiceException { try { requestJSONObject.put(Notification.NOTIFICATION_DATA_TYPE, Notification.DATA_TYPE_C_POINT_TRANSFER); addNotification(requestJSONObject); } catch (final RepositoryException e) { final String msg = "Adds notification [type=point_transfer] failed"; LOGGER.log(Level.ERROR, msg, e); throw new ServiceException(msg); } } /** * Adds a 'article reward' type notification with the specified request json object. * * @param requestJSONObject the specified request json object, for example, * "userId"; "", * "dataId": "" // reward id * @throws ServiceException service exception */ @Transactional public void addArticleRewardNotification(final JSONObject requestJSONObject) throws ServiceException { try { requestJSONObject.put(Notification.NOTIFICATION_DATA_TYPE, Notification.DATA_TYPE_C_POINT_ARTICLE_REWARD); addNotification(requestJSONObject); } catch (final RepositoryException e) { final String msg = "Adds notification [type=article_reward] failed"; LOGGER.log(Level.ERROR, msg, e); throw new ServiceException(msg); } } /** * Adds a 'article thank' type notification with the specified request json object. * * @param requestJSONObject the specified request json object, for example, * "userId"; "", * "dataId": "" // thank id * @throws ServiceException service exception */ @Transactional public void addArticleThankNotification(final JSONObject requestJSONObject) throws ServiceException { try { requestJSONObject.put(Notification.NOTIFICATION_DATA_TYPE, Notification.DATA_TYPE_C_POINT_ARTICLE_THANK); addNotification(requestJSONObject); } catch (final RepositoryException e) { final String msg = "Adds notification [type=article_thank] failed"; LOGGER.log(Level.ERROR, msg, e); throw new ServiceException(msg); } } /** * Adds a 'comment thank' type notification with the specified request json object. * * @param requestJSONObject the specified request json object, for example, * "userId"; "", * "dataId": "" // reward id * @throws ServiceException service exception */ @Transactional public void addCommentThankNotification(final JSONObject requestJSONObject) throws ServiceException { try { requestJSONObject.put(Notification.NOTIFICATION_DATA_TYPE, Notification.DATA_TYPE_C_POINT_COMMENT_THANK); addNotification(requestJSONObject); } catch (final RepositoryException e) { final String msg = "Adds notification [type=comment_thank] failed"; LOGGER.log(Level.ERROR, msg, e); throw new ServiceException(msg); } } /** * Adds a 'comment' type notification with the specified request json object. * * @param requestJSONObject the specified request json object, for example, * "userId"; "", * "dataId": "" * @throws ServiceException service exception */ // XXX: Unused @Transactional public void addCommentNotification(final JSONObject requestJSONObject) throws ServiceException { try { requestJSONObject.put(Notification.NOTIFICATION_DATA_TYPE, Notification.DATA_TYPE_C_COMMENT); addNotification(requestJSONObject); } catch (final RepositoryException e) { final String msg = "Adds notification [type=comment] failed"; LOGGER.log(Level.ERROR, msg, e); throw new ServiceException(msg); } } /** * Adds a 'at' type notification with the specified request json object. * * @param requestJSONObject the specified request json object, for example, * "userId"; "", * "dataId": "" * @throws ServiceException service exception */ @Transactional public void addAtNotification(final JSONObject requestJSONObject) throws ServiceException { try { requestJSONObject.put(Notification.NOTIFICATION_DATA_TYPE, Notification.DATA_TYPE_C_AT); addNotification(requestJSONObject); } catch (final RepositoryException e) { final String msg = "Adds notification [type=at] failed"; LOGGER.log(Level.ERROR, msg, e); throw new ServiceException(msg); } } /** * Adds a 'article' type notification with the specified request json object. * * @param requestJSONObject the specified request json object, for example, * "userId"; "", * "dataId": "" * @throws ServiceException service exception */ // XXX: Unused @Transactional public void addArticleNotification(final JSONObject requestJSONObject) throws ServiceException { try { requestJSONObject.put(Notification.NOTIFICATION_DATA_TYPE, Notification.DATA_TYPE_C_ARTICLE); addNotification(requestJSONObject); } catch (final RepositoryException e) { final String msg = "Adds notification [type=article] failed"; LOGGER.log(Level.ERROR, msg, e); throw new ServiceException(msg); } } /** * Adds a 'following - user' type notification with the specified request json object. * * @param requestJSONObject the specified request json object, for example, * "userId"; "", * "dataId": "" // article id * @throws ServiceException service exception */ @Transactional public void addFollowingUserNotification(final JSONObject requestJSONObject) throws ServiceException { try { requestJSONObject.put(Notification.NOTIFICATION_DATA_TYPE, Notification.DATA_TYPE_C_FOLLOWING_USER); addNotification(requestJSONObject); } catch (final RepositoryException e) { final String msg = "Adds notification [type=following_user] failed"; LOGGER.log(Level.ERROR, msg, e); throw new ServiceException(msg); } } /** * Adds a 'commented' type notification with the specified request json object. * * @param requestJSONObject the specified request json object, for example, * "userId"; "", * "dataId": "" * @throws ServiceException service exception */ @Transactional public void addCommentedNotification(final JSONObject requestJSONObject) throws ServiceException { try { requestJSONObject.put(Notification.NOTIFICATION_DATA_TYPE, Notification.DATA_TYPE_C_COMMENTED); addNotification(requestJSONObject); } catch (final RepositoryException e) { final String msg = "Adds notification [type=commented] failed"; LOGGER.log(Level.ERROR, msg, e); throw new ServiceException(msg); } } /** * Adds a 'reply' type notification with the specified request json object. * * @param requestJSONObject the specified request json object, for example, * "userId"; "", * "dataId": "" * @throws ServiceException service exception */ @Transactional public void addReplyNotification(final JSONObject requestJSONObject) throws ServiceException { try { requestJSONObject.put(Notification.NOTIFICATION_DATA_TYPE, Notification.DATA_TYPE_C_REPLY); addNotification(requestJSONObject); } catch (final RepositoryException e) { final String msg = "Adds notification [type=reply] failed"; LOGGER.log(Level.ERROR, msg, e); throw new ServiceException(msg); } } /** * Adds a notification with the specified request json object. * * @param requestJSONObject the specified request json object, for example, * "userId"; "", * "dataId": "", * "dataType": int * @throws RepositoryException repository exception */ private void addNotification(final JSONObject requestJSONObject) throws RepositoryException { final JSONObject notification = new JSONObject(); notification.put(Notification.NOTIFICATION_HAS_READ, false); notification.put(Notification.NOTIFICATION_USER_ID, requestJSONObject.optString(Notification.NOTIFICATION_USER_ID)); notification.put(Notification.NOTIFICATION_DATA_ID, requestJSONObject.optString(Notification.NOTIFICATION_DATA_ID)); notification.put(Notification.NOTIFICATION_DATA_TYPE, requestJSONObject.optInt(Notification.NOTIFICATION_DATA_TYPE)); notificationRepository.add(notification); Symphonys.EXECUTOR_SERVICE.submit(new Runnable() { @Override public void run() { final JSONObject cmd = new JSONObject(); cmd.put(Common.USER_ID, requestJSONObject.optString(Notification.NOTIFICATION_USER_ID)); cmd.put(Common.COMMAND, "refreshNotification"); UserChannel.sendCmd(cmd); } }); } }