DisposeHelper.java
package emissary.util;
import emissary.core.IBaseDataObject;
import org.apache.commons.lang3.Validate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
/**
* Helper methods to ease handling of Dispose objects
*
* Dispose objects are added to BDOs to handle clean-up after a
* {@link emissary.core.channels.SeekableByteChannelFactory} is finished with
*/
public final class DisposeHelper {
private DisposeHelper() {}
/** Metadata key to use to store runnables in on a BDO. */
public static final String KEY = "DISPOSE_RUNNABLES";
private static final String VALIDATION_MSG_IBDO = "Cannot be null: ibdo";
private static final String VALIDATION_MSG_RUNNABLE = "Cannot be null: Runnable";
private static final Logger LOGGER = LoggerFactory.getLogger(DisposeHelper.class);
/**
* Add a Dispose object to a BDO
*
* @param ibdo to add the Runnable to
* @param newRunnable to handle disposing of the referenced object
*/
public static void add(final IBaseDataObject ibdo, final Runnable newRunnable) {
Validate.notNull(ibdo, VALIDATION_MSG_IBDO);
Validate.notNull(newRunnable, VALIDATION_MSG_RUNNABLE);
if (ibdo.hasParameter(KEY)) {
final List<Object> existingRunnables = new ArrayList<>(ibdo.getParameter(KEY));
existingRunnables.add(newRunnable);
ibdo.putParameter(KEY, existingRunnables);
} else {
ibdo.putParameter(KEY, newRunnable);
}
}
/**
* Add a list of Dispose objects to a BDO (additive to existing Dispose objects)
*
* @param ibdo to add the Runnables to
* @param newRunnables list of Runnables to add
*/
public static void add(final IBaseDataObject ibdo, final List<Runnable> newRunnables) {
Validate.notNull(ibdo, VALIDATION_MSG_IBDO);
Validate.notNull(newRunnables, VALIDATION_MSG_RUNNABLE);
if (ibdo.hasParameter(KEY)) {
final List<Object> existingRunnables = new ArrayList<>(ibdo.getParameter(KEY));
existingRunnables.addAll(newRunnables);
ibdo.putParameter(KEY, existingRunnables);
} else {
ibdo.putParameter(KEY, newRunnables);
}
}
/**
* Set a single Dispose object to a BDO (overwrites any existing Dispose objects)
*
* @param ibdo to add the Runnable to
* @param newRunnable to handle disposing of the referenced object
*/
public static void set(final IBaseDataObject ibdo, final Runnable newRunnable) {
Validate.notNull(ibdo, VALIDATION_MSG_IBDO);
Validate.notNull(newRunnable, VALIDATION_MSG_RUNNABLE);
ibdo.setParameter(KEY, newRunnable);
}
/**
* Get the list of Runnables for an object. If an object provided by the key is not a valid Runnable, it will be
* ignored.
*
* @param ibdo to get Runnables from
* @return the list of Runnables
*/
public static List<Runnable> get(final IBaseDataObject ibdo) {
Validate.notNull(ibdo, VALIDATION_MSG_IBDO);
if (!ibdo.hasParameter(KEY)) {
return List.of();
}
final List<Runnable> validatedAsRunnables = new ArrayList<>();
final List<Object> existingRunnables = ibdo.getParameter(KEY);
for (final Object possibleRunnable : existingRunnables) {
if (possibleRunnable instanceof Runnable) {
validatedAsRunnables.add((Runnable) possibleRunnable);
} else if (LOGGER.isWarnEnabled()) {
LOGGER.warn("Not a valid Runnable on object {}", ibdo.shortName());
}
}
return validatedAsRunnables;
}
/**
* Execute Runnables on provided objects. Execution will be for each object in the order provided.
*
* @param ibdos to execute runnables from
*/
public static void execute(final List<IBaseDataObject> ibdos) {
Validate.notNull(ibdos, "Cannot be null: %s", "ibdos");
ibdos.forEach(DisposeHelper::execute);
}
/**
* Execute Runnables for the specified object.
*
* @param ibdo to execute Runnables on
*/
public static void execute(final IBaseDataObject ibdo) {
Validate.notNull(ibdo, VALIDATION_MSG_IBDO);
// Can't be refactored to method::reference as we need to ensure exceptions are not swallowed
for (final Runnable runnable : DisposeHelper.get(ibdo)) {
try {
runnable.run();
} catch (final RuntimeException e) {
LOGGER.warn("Exception while executing Runnable for {}", ibdo.shortName(), e);
}
}
}
}