org.craftercms.social.services.notification.impl.NotificationServiceImpl.java Source code

Java tutorial

Introduction

Here is the source code for org.craftercms.social.services.notification.impl.NotificationServiceImpl.java

Source

/*
 * Copyright (C) 2007-2014 Crafter Software Corporation.
 *
 *     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.craftercms.social.services.notification.impl;

import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.craftercms.commons.i10n.I10nLogger;
import org.craftercms.commons.mongo.MongoDataException;
import org.craftercms.commons.security.permissions.annotations.HasPermission;
import org.craftercms.profile.api.Profile;
import org.craftercms.security.exception.AuthenticationRequiredException;
import org.craftercms.social.domain.notifications.ThreadsToNotify;
import org.craftercms.social.domain.notifications.WatchedThread;
import org.craftercms.social.exceptions.NotificationException;
import org.craftercms.social.exceptions.SocialException;
import org.craftercms.social.repositories.system.AuditRepository;
import org.craftercms.social.repositories.system.impl.AuditRepositoryImpl;
import org.craftercms.social.repositories.system.notifications.WatchedThreadsRepository;
import org.craftercms.social.repositories.system.notifications.impl.WatchedThreadsRepositoryImpl;
import org.craftercms.social.security.SocialPermission;
import org.craftercms.social.security.SocialSecurityUtils;
import org.craftercms.social.services.notification.NotificationDigestService;
import org.craftercms.social.services.notification.NotificationService;
import org.craftercms.social.util.LoggerFactory;
import org.craftercms.social.util.profile.ProfileAggregator;
import org.quartz.SimpleTrigger;
import org.slf4j.Logger;

import static org.craftercms.social.security.SecurityActionNames.UGC_READ;

/**
 *
 */
public class NotificationServiceImpl implements NotificationService {

    private AuditRepository auditRepository;
    private WatchedThreadsRepository watchedThreadsRepository;
    private I10nLogger log = LoggerFactory.getLogger(NotificationServiceImpl.class);
    private SimpleTrigger instantTrigger;
    private ProfileAggregator profileAggregator;
    private NotificationDigestService notificationDigestService;
    private Date lastInstantFire;
    private Logger logger = org.slf4j.LoggerFactory.getLogger(NotificationDigestServiceImpl.class);
    private boolean disableNotifications;

    public NotificationServiceImpl() {
        lastInstantFire = new Date();
    }

    @Override
    @HasPermission(action = UGC_READ, type = SocialPermission.class)
    public void subscribeUser(final Profile profile, final String threadId, final String frequency)
            throws NotificationException {
        String frequencyToUse = frequency;
        try {
            WatchedThread thread = watchedThreadsRepository.findByStringId(threadId);
            if (thread == null) {
                log.debug("logging.system.notification.creatingSubscription", threadId);
                thread = new WatchedThread();
                thread.setThreadId(threadId);
                watchedThreadsRepository.save(thread);
            }
            log.debug("logging.system.notification.adding", profile, threadId, frequency);
            if (StringUtils.isBlank(frequency)) {
                if (profile.getAttributes().containsKey("defaultFrequency")) {
                    frequencyToUse = profile.getAttribute("defaultFrequency");
                    if (StringUtils.isBlank(frequencyToUse)) {
                        throw new IllegalArgumentException("Profile defaultFrequency can't be empty");
                    }
                } else {
                    throw new IllegalArgumentException(
                            "Profile defaultFrequency must be set or send a valid " + "frequency");
                }
            }
            watchedThreadsRepository.addWatcher(thread.getThreadId(), profile.getId().toString(), frequencyToUse);
        } catch (MongoDataException e) {
            throw new NotificationException("Unable to subscribe User", e);
        }
    }

    @Override
    @HasPermission(action = UGC_READ, type = SocialPermission.class)
    public void unSubscribeUser(final String userId, final String threadId) throws NotificationException {
        try {
            WatchedThread thread = watchedThreadsRepository.findByStringId(threadId);
            if (thread != null) {
                watchedThreadsRepository.removeWatcher(thread.getThreadId(), userId);
            }
            log.debug("logging.system.notification.remove", userId, threadId);
        } catch (MongoDataException e) {
            throw new NotificationException("Unable to subscribe User", e);
        }
    }

    @Override
    public boolean isBeenWatch(final String threadId, final String profileId) throws NotificationException {
        try {
            WatchedThread thread = watchedThreadsRepository.isUserSubscribe(threadId, profileId);
            return thread != null;
        } catch (MongoDataException e) {
            throw new NotificationException("Unable to Check if user is subscribe", e);
        }
    }

    @Override
    public void notify(final String type) {
        if (!disableNotifications) {
            Date from = getStartDateByType(type);
            lastInstantFire = new Date();
            final Date to = new Date();
            try {
                final List<ThreadsToNotify> toBeSend = watchedThreadsRepository.findProfilesToSend(type);
                for (ThreadsToNotify threadsToNotify : toBeSend) {

                    logger.info("Notifying {} users for {} from {} until {} ", threadsToNotify.getProfiles().size(),
                            type, from, to);

                    for (String profileId : threadsToNotify.getProfiles()) {
                        final List<HashMap> auditDigest = auditRepository.getNotificationDigest(
                                threadsToNotify.getThreadId(), from, to, Arrays.asList(profileId));
                        logger.info("Notifying {} sending {} ugs {}", profileId, threadsToNotify.getThreadId(),
                                auditDigest.size());
                        notificationDigestService.digest(auditDigest, profileId, type);
                    }
                }

            } catch (SocialException ex) {
                logger.error("Unable to send notifications", ex);
            }
        }
    }

    @Override
    public List<Map> getUserSubscriptions() throws SocialException {
        final Profile p = SocialSecurityUtils.getCurrentProfile();
        if (p != null && !p.getUsername().equalsIgnoreCase(SocialSecurityUtils.ANONYMOUS)) {
            return watchedThreadsRepository.findUserWatchedThreads(p.getId().toString());
        } else {
            throw new AuthenticationRequiredException("User is not authenticated");
        }
    }

    @Override
    public void changeSubscription(final Profile p, final String threadId, final String frequency)
            throws NotificationException {
        if (isBeenWatch(threadId, p.getId().toString())) {
            String frequencyToUse = frequency;
            if (StringUtils.isBlank(frequencyToUse)) {
                if (p.getAttributes().containsKey("defaultFrequency")) {
                    frequencyToUse = p.getAttribute("defaultFrequency");
                    if (StringUtils.isBlank(frequencyToUse)) {
                        throw new IllegalArgumentException("Profile defaultFrequency can't be empty");
                    }
                } else {
                    throw new IllegalArgumentException(
                            "Profile defaultFrequency must be set or send a valid " + "frequency");
                }
            }
            watchedThreadsRepository.removeWatcher(threadId, p.getId().toString());
            watchedThreadsRepository.addWatcher(threadId, p.getId().toString(), frequencyToUse);
        }
    }

    protected Date getStartDateByType(final String type) {
        Calendar cal = Calendar.getInstance();

        if (type.equalsIgnoreCase(NotificationService.WEEKLY)) {
            cal.add(Calendar.WEEK_OF_YEAR, -1);
            return cal.getTime();
        } else if (type.equalsIgnoreCase(NotificationService.DAILY)) {
            cal.add(Calendar.DAY_OF_MONTH, -1);
            return cal.getTime();
        } else if (type.equalsIgnoreCase(NotificationService.INSTANT)) {
            return lastInstantFire;
        } else {
            return null;
        }
    }

    public void setInstantTrigger(final SimpleTrigger instantTrigger) {
        this.instantTrigger = instantTrigger;
    }

    public void setAuditRepository(AuditRepositoryImpl auditRepository) {
        this.auditRepository = auditRepository;
    }

    public void setWatchedThreadsRepository(WatchedThreadsRepositoryImpl watchedThreadsRepository) {
        this.watchedThreadsRepository = watchedThreadsRepository;
    }

    public void setProfileAggregatorImpl(ProfileAggregator profileAggregator) {
        this.profileAggregator = profileAggregator;
    }

    public void setNotificationDigestServiceImpl(NotificationDigestService notificationDigestService) {
        this.notificationDigestService = notificationDigestService;
    }

    public void setDisableNotifications(final boolean disableNotifications) {
        this.disableNotifications = disableNotifications;
    }
}