package net.sf.cotta.io;
import net.sf.cotta.TIoException;
import net.sf.cotta.TPath;
import java.io.Closeable;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* resource manager that handles the resource management. This class is to
* be used through its sub-classes
*
* @param <P> The processor to be used for call back
*/
abstract public class ResourceManager<P> {
private List<Closeable> resourceList;
public ResourceManager() {
this(new ArrayList<Closeable>());
}
public ResourceManager(List<Closeable> resourceList) {
this.resourceList = resourceList;
}
public void registerResource(Closeable resource) {
resourceList.add(resource);
}
protected void open(P processor) throws TIoException {
boolean errorOccurred = true;
try {
process(processor);
errorOccurred = false;
} catch (TIoException e) {
throw e;
} catch (IOException e) {
throw new TIoException(path(), "IO Error", e);
} finally {
safeClose(errorOccurred);
}
}
abstract protected void process(P processor) throws IOException;
abstract protected TPath path();
private void safeClose(boolean errorOccurred) throws TIoException {
try {
close();
} catch (IOException e) {
if (!errorOccurred) {
throw new TIoException(path(), "closing resource", e);
}
}
}
private void close() throws IOException {
Collections.reverse(resourceList);
for (Closeable Closeable : resourceList) {
Closeable.close();
}
}
}