All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.deepsymmetry.beatlink.LifecycleParticipant Maven / Gradle / Ivy

There is a newer version: 7.4.0
Show newest version
package org.deepsymmetry.beatlink;

import org.slf4j.Logger;

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Provides the abstract skeleton for all the classes that can be started and stopped in Beat Link, and for which
 * other classes may have a need to know when they start or stop.
 */
public abstract class LifecycleParticipant {

    /**
     * Keeps track of the registered device announcement listeners.
     */
    private final Set lifecycleListeners =
            Collections.newSetFromMap(new ConcurrentHashMap());

    /**
     * 

Adds the specified life cycle listener to receive announcements when the component starts and stops. * If {@code listener} is {@code null} or already present in the list * of registered listeners, no exception is thrown and no action is performed.

* *

Lifecycle announcements are delivered to listeners on a separate thread to avoid worries about deadlock in * synchronized start and stop methods. The called function should still be fast, or delegate long operations to * its own separate thread.

* * @param listener the device announcement listener to add */ public void addLifecycleListener(LifecycleListener listener) { if (listener != null) { lifecycleListeners.add(listener); } } /** * Removes the specified life cycle listener so that it no longer receives announcements when * the component starts or stops. If {@code listener} is {@code null} or not present * in the list of registered listeners, no exception is thrown and no action is performed. * * @param listener the life cycle listener to remove */ public void removeLifecycleListener(LifecycleListener listener) { if (listener != null) { lifecycleListeners.remove(listener); } } /** * Get the set of lifecycle listeners that are currently registered. * * @return the currently registered lifecycle listeners */ @SuppressWarnings("WeakerAccess") public Set getLifecycleListeners() { // Make a copy so the caller gets an immutable snapshot of the current moment in time. return Collections.unmodifiableSet(new HashSet(lifecycleListeners)); } /** * Send a lifecycle announcement to all registered listeners. * * @param logger the logger to use, so the log entry shows as belonging to the proper subclass. * @param starting will be {@code true} if the DeviceFinder is starting, {@code false} if it is stopping. */ protected void deliverLifecycleAnnouncement(final Logger logger, final boolean starting) { new Thread(new Runnable() { @Override public void run() { for (final LifecycleListener listener : getLifecycleListeners()) { try { if (starting) { listener.started(LifecycleParticipant.this); } else { listener.stopped(LifecycleParticipant.this); } } catch (Throwable t) { logger.warn("Problem delivering lifecycle announcement to listener", t); } } } }, "Lifecycle announcement delivery").start(); } /** * Check whether this component has been started. * * @return the component has started successfully and is ready to perform any service it offers. */ @SuppressWarnings("WeakerAccess") abstract public boolean isRunning(); /** * Helper method to throw an {@link IllegalStateException} if we are not currently running. * * @throws IllegalStateException if the component is not running */ protected void ensureRunning() { if (!isRunning()) { throw new IllegalStateException(this.getClass().getName() + " is not running"); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy