cz.muni.fi.editor.database.dao.NotificationDAOImpl.java Source code

Java tutorial

Introduction

Here is the source code for cz.muni.fi.editor.database.dao.NotificationDAOImpl.java

Source

/*
*Copyright  2016 Dominik Szalai (emptulik@gmail.com)
*
*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.
*/
/*
 * Copyright  2016 Dominik Szalai (emptulik@gmail.com)
 *
 * 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 cz.muni.fi.editor.database.dao;

import cz.muni.fi.editor.database.domain.Notification;
import cz.muni.fi.editor.database.domain.user.User;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Repository;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Created by Dominik Szalai - emptulik at gmail.com on 7/20/16.
 */
@Repository
@Log4j2
public class NotificationDAOImpl extends AbstractDAO<Notification, Long> implements NotificationDAO {
    private final String USER_PARAMETER = "user";
    @Value("${database.notification.latestsize}")
    private Integer latestSize;

    private final Notification latestNotification;

    public NotificationDAOImpl() {
        latestNotification = new Notification();
        latestNotification.setId(Long.valueOf(0L));
    }

    @Override
    public Class<Notification> getClassType() {
        return Notification.class;
    }

    @Override
    public List<Notification> getNotifications(int start, int pageSize, User user, boolean includeSeen) {
        if (includeSeen) {
            return getEntityManager()
                    .createQuery("SELECT n FROM notification n WHERE n.notified = :user ORDER BY n.id DESC",
                            getClassType())
                    .setParameter(USER_PARAMETER, user).setFirstResult(start).setMaxResults(pageSize)
                    .getResultList();
        } else {
            return getEntityManager().createQuery(
                    "SELECT n FROM notification n WHERE n.notified = :user AND n.seenDate IS NULL ORDER BY n.id DESC",
                    getClassType()).setParameter(USER_PARAMETER, user).setFirstResult(start).setMaxResults(pageSize)
                    .getResultList();
        }
    }

    @Override
    public List<Notification> getLatestNotifications(User user, Notification latestSeen) {
        if (latestNotification.equals(latestSeen)) {
            return getEntityManager()
                    .createQuery("SELECT n FROM notification n WHERE n.notified = :user ORDER BY n.id DESC",
                            getClassType())
                    .setParameter(USER_PARAMETER, user).setFirstResult(0).setMaxResults(latestSize).getResultList();
        } else {
            return getEntityManager().createQuery(
                    "SELECT n FROM notification n WHERE n.notified = :user AND n.id > :latestID ORDER BY n.id DESC",
                    getClassType()).setParameter(USER_PARAMETER, user).setParameter("latestID", latestSeen.getId())
                    .setFirstResult(0).setMaxResults(latestSize).getResultList();
        }
    }

    @Override
    public int numberOfUnseen(User user) {
        return getEntityManager().createQuery(
                "SELECT COUNT(n.id) FROM notification n WHERE n.notified = :user AND n.seenDate IS NULL",
                Long.class).setParameter(USER_PARAMETER, user).getSingleResult().intValue();
    }

    @Override
    public void markSeen(List<Notification> notifications) {
        if (notifications.size() > 100) {
            log.warn("Marking too many notifications: {}.", notifications.size());
        }

        LocalDateTime now = LocalDateTime.now();

        getEntityManager().createQuery("UPDATE notification n SET n.seenDate = :now WHERE n.id IN :notifications")
                .setParameter("now", now).setParameter("notifications",
                        notifications.stream().map(n -> n.getId()).collect(Collectors.toList()))
                .executeUpdate();

        // direct update bypasses jpa context
        // hibernate does not know about entities being updated in the background
        // following cycle makes sure hibernate WILL refresh new values from database
        notifications.stream().filter(n -> getEntityManager().contains(n))
                .forEach(n -> getEntityManager().refresh(n));
    }
}