org.deepsymmetry.beatlink.LifecycleParticipant Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of beat-link Show documentation
Show all versions of beat-link Show documentation
A Java library for communicating with Pioneer DJ Link equipment.
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