package org.azeckoski.reflectutils;
import java.util.List;
import java.util.ArrayList;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* Simple LifecycleManager for the reflection utilities. This is provided to allow
* cleanup under certain conditions (ie. the background thread that is run by the ReferenceMap)
*
* Initially, the LifecycleManager is not active, and the reflection utilities will attempt
* to clean themselves up. To use an explicit lifecycle, first call setActive() to start the manager
* (before anything uses the reflection utilities - ie. in the context initiliser of a web application!),
* and then call 'shutdown()' during termination.
*/
public class LifecycleManager
{
private static boolean isActive = false;
private static List<Lifecycle> managedObjects = new ArrayList<Lifecycle>();
private static Lock moLock = new ReentrantLock();
/**
* Test to see if the manager is active
* @return true if active
*/
public static boolean isActive() {
return isActive;
}
/**
* Activate the lifecycle manager
* @param active
*/
public static void setActive(boolean active) {
isActive = active;
}
/**
* Register an object to receive lifecycle events
* @param object
*/
public static void register(Lifecycle object) {
if (isActive) {
moLock.lock();
try {
if (managedObjects == null) {
throw new RuntimeException("Unable to register - manager already shut down");
}
managedObjects.add(object);
} finally {
moLock.unlock();
}
}
}
/**
* Request shutdown for any objects registered with the lifecycle manager
*/
public synchronized static void shutdown() {
moLock.lock();
try {
if (managedObjects != null) {
while (managedObjects.size() > 0) {
Lifecycle obj = managedObjects.remove(managedObjects.size() - 1);
obj.shutdown();
}
managedObjects = null;
}
} finally {
moLock.unlock();
}
}
}