package eu.semberal.reminders.service;
import eu.semberal.reminders.entity.Note;
import eu.semberal.reminders.entity.User;
import org.quartz.CronTrigger;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import java.text.ParseException;
import java.util.List;
import java.util.Locale;
@Transactional
public class NotesServiceImpl implements NotesService {
@PersistenceContext
private EntityManager entityManager;
private Scheduler scheduler;
private Logger log = LoggerFactory.getLogger(NotesServiceImpl.class);
private MailService mailService;
public void setMailService(MailService mailService) {
this.mailService = mailService;
}
public void setScheduler(Scheduler scheduler) {
this.scheduler = scheduler;
}
@Override
public void activateNote(Long id, boolean activate, boolean sendNotification) {
Note n = entityManager.find(Note.class, id);
if (n == null) throw new IllegalArgumentException("Note has not been found.");
boolean oldActivated = n.isActivated();
n.setActivated(activate);
if (activate && !oldActivated && n.isSendActivationNotifications() && sendNotification) {
mailService.sendNoteActivationNotification(n);
}
}
@Override
@SuppressWarnings("unchecked")
public List<Note> getAllScheduledNotes() {
Query q = entityManager.createQuery("select n from Note n where n.schedulingExpression is not null");
return q.getResultList();
}
@Override
public Note saveNote(Note n) throws ParseException, SchedulerException {
Note savedNote = entityManager.merge(n);
if (n.getId() == null && n.getSchedulingExpression() != null) {
Trigger trigger = new CronTrigger("triggerId" + savedNote.getId(), null, n.getSchedulingExpression()); //create trigger for note
trigger.setJobName("activateNoteJob"); //set it should trigger the job which activates the note (job in singleton spring bean)
trigger.getJobDataMap().putAsString("noteId", savedNote.getId()); //set id to the jobDataMap, so job can get the node to activate
scheduler.scheduleJob(trigger); //schedule
} else if (n.getId() != null) { // old note being updated
if (scheduler.getTrigger("triggerId" + n.getId(), null) != null) { //if was scheduled, unschedule
scheduler.unscheduleJob("triggerId" + n.getId(), null);
}
if (n.getSchedulingExpression() != null) { //if updated note is set to be scheduled, schedule...
Trigger trigger = new CronTrigger("triggerId" + n.getId(), null, n.getSchedulingExpression()); //create trigger for note
trigger.setJobName("activateNoteJob"); //set it should trigger the job which activates the note (job in singleton spring bean)
trigger.getJobDataMap().putAsString("noteId", n.getId()); //set id to the jobDataMap, so job can get the node to activate
scheduler.scheduleJob(trigger); //schedule
}
}
return savedNote;
}
@Override
@SuppressWarnings("unchecked")
public List<Note> getNotesForUser(User u, boolean activatedOnly) {
Query q;
if (activatedOnly)
q = entityManager.createQuery("select n from Note n where n.user=:user and n.activated=true order by n.dateAdded");
else
q = entityManager.createQuery("select n from Note n where n.user=:user order by n.dateAdded");
q.setParameter("user", u);
return q.getResultList();
}
@Override
public void deleteNote(Long id) {
Note n = entityManager.find(Note.class, id);
if (n != null) {
entityManager.remove(n);
if (n.getSchedulingExpression() != null) {
try {
scheduler.unscheduleJob("triggerId" + id, null);
} catch (SchedulerException e) {
log.error("Not possible to unschedule note after deletion. Error message: \n {}", e);
}
}
}
}
@Override
public Note getNote(Long id) {
return entityManager.find(Note.class, id);
}
}