rmblworx.tools.timey.AlarmRunnable.java Source code

Java tutorial

Introduction

Here is the source code for rmblworx.tools.timey.AlarmRunnable.java

Source

package rmblworx.tools.timey;

import java.util.List;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import rmblworx.tools.timey.event.AlarmExpiredEvent;
import rmblworx.tools.timey.event.AlarmsModifiedEvent;
import rmblworx.tools.timey.event.TimeyEvent;
import rmblworx.tools.timey.event.TimeyEventDispatcher;
import rmblworx.tools.timey.event.TimeyEventListener;
import rmblworx.tools.timey.persistence.service.IAlarmService;
import rmblworx.tools.timey.vo.AlarmDescriptor;

/*
 * Copyright 2014-2015 Christian Raue
 * MIT License http://opensource.org/licenses/mit-license.php
 */
/**
 * Diese Thread-sichere Implementierung setzt einen Countdown-Zhler um. Zeitnahme findet in Millisekunden statt.
 *
 * @author mmatthies
 */
class AlarmRunnable implements Runnable, ApplicationContextAware, TimeyEventListener {
    /**
     * Referenz auf die AlarmClient-Implementierung.
     */
    private AlarmClient alarmClient;
    /**
     * Referenz auf den Alarmservice.
     */
    private IAlarmService alarmService;
    /**
     * Liste mit allen Alarmzeitpunkten.
     */
    private List<AlarmDescriptor> allAlarms;
    /**
     * Referenz auf die Events-verteilende Implementierung.
     */
    private TimeyEventDispatcher eventDispatcher;
    /**
     * Von dieser Timerimplementierung verwendete Lock-Mechanismus.
     */
    private final Lock lock = new ReentrantLock();
    /**
     * Merker. Kennzeichnet ob es neue oder modifizierte Alarme gibt. Beeinflusst das DB-Abfrageverhalten.
     */
    private boolean newOrModifiedAlarmsAvailable = false;
    /**
     * Spring-Anwendungskontext.
     */
    private ApplicationContext springContext;

    /**
     */
    public AlarmRunnable() {
    }

    /**
     * Prueft ob ein Alarm zeitlich eingetreten ist.
     *
     * @return das den Alarm beschreibende Werteobjekt.
     */
    private AlarmDescriptor detectAlarm() {
        final long currentTimeMillis = System.currentTimeMillis();
        AlarmDescriptor result = null;
        for (final AlarmDescriptor alarm : this.allAlarms) {
            if (alarm.getIsActive()) {
                if (alarm.getAlarmtime().getMilliSeconds() <= currentTimeMillis) {
                    result = alarm;
                    break;
                }
            }
        }
        return result;
    }

    @Override
    public void handleEvent(final TimeyEvent timeyEvent) {
        if (timeyEvent instanceof AlarmsModifiedEvent) {
            this.newOrModifiedAlarmsAvailable = true;
        }
    }

    @Override
    public void run() {
        Thread.currentThread().setName("timey-Alarm");
        this.lock.lock();
        try {
            // alarme aus der db
            if (this.allAlarms == null || this.newOrModifiedAlarmsAvailable) {
                this.allAlarms = this.alarmService.getAll();
                this.newOrModifiedAlarmsAvailable = false;
            }
            // alarme abgleichen mit aktueller Systemzeit
            final AlarmDescriptor result = this.detectAlarm();
            if (result != null) {
                // wenn erreicht event feuern sonst weiter abgleichen
                this.alarmClient.initAlarmSetStateOfAlarmCommand(result, false);
                this.alarmClient.initAlarmSetStateInAlarmDescriptorCommand(result, false);

                this.eventDispatcher.dispatchEvent(new AlarmExpiredEvent(result));
            }
        } finally {
            this.lock.unlock();
        }
    }

    @Override
    public void setApplicationContext(final ApplicationContext applicationContext) throws BeansException {
        this.springContext = applicationContext;
        this.eventDispatcher = (TimeyEventDispatcher) this.springContext.getBean("timeyEventDispatcher");
        this.eventDispatcher.addEventListener(this);
        this.alarmService = (IAlarmService) this.springContext.getBean("alarmService");
        this.alarmClient = (AlarmClient) this.springContext.getBean("alarmClient");
    }
}