CleanableRegistry.java
package fr.sii.ogham.core.builder.registry;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.List;
import fr.sii.ogham.core.clean.Cleanable;
import fr.sii.ogham.core.exception.clean.CleanException;
import fr.sii.ogham.core.exception.clean.CleanableException;
import fr.sii.ogham.core.exception.clean.MultipleCleanException;
/**
* Registry that tracks instances that implements {@link Cleanable}. Other
* instances are skipped.
*
* <p>
* The registry is also a {@link Cleanable} to relay cleanup request to
* registered instances when calling {@link #clean()} method.
*
* If an instance failed during its cleanup (exception is thrown), the failure
* is registered. The next {@link Cleanable} instance is tried and so on until
* all registered instances are cleaned. At the end a
* {@link MultipleCleanException} is thrown with all registered failures.
*
* @author Aurélien Baudet
*
*/
public class CleanableRegistry implements Registry<Object>, Cleanable {
private final Deque<Cleanable> cleanables;
/**
* Initializes an empty registry
*/
public CleanableRegistry() {
super();
this.cleanables = new ArrayDeque<>();
}
@Override
public void register(Object obj) {
if (obj instanceof Cleanable) {
cleanables.add((Cleanable) obj);
}
}
@Override
public void clean() throws CleanException {
List<CleanException> failures = new ArrayList<>();
while (!cleanables.isEmpty()) {
clean(cleanables.pop(), failures);
}
if (!failures.isEmpty()) {
throw new MultipleCleanException("Failed to cleanup several resources", failures);
}
}
private static void clean(Cleanable cleanable, List<CleanException> failures) {
try {
cleanable.clean();
} catch (CleanException e) {
failures.add(new CleanableException(e, cleanable));
}
}
}