package org.oddjob.persist;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.Logger;
import org.oddjob.arooa.ArooaSession;
import org.oddjob.arooa.life.ComponentPersistException;
import org.oddjob.arooa.life.ComponentPersister;
import org.oddjob.arooa.registry.Path;
import org.oddjob.framework.OptionallyTransient;
import org.oddjob.framework.Transient;
/**
* @oddjob.description This provides common implementation for
* persisting job state.
*
* @author Rob Gordon
*/
abstract public class PersisterBase
implements OddjobPersister {
private static final Logger logger = Logger.getLogger(PersisterBase.class);
/** List of ids to include. */
private List<String> include;
/** List of ids to exclude. */
private List<String> exclude;
/**
* @oddjob.property path
* @oddjob.description A '/' delimited path to the location for the
* persister. Normally this is set by nested persisters to be the id
* of the Oddjob that created them.
* @oddjob.required No.
*/
private Path ourPath;
/**
* Constructor.
*/
public PersisterBase() {
}
/**
* Constructor used for nested persisters.
*
* @param path The path.
*/
protected PersisterBase(Path path) {
this.ourPath = path;
}
public void setPath(String path) {
ourPath = new Path(path);
}
public ComponentPersister persisterFor(String id) {
Path path;
if (ourPath == null) {
path = new Path(id);
}
else {
path = ourPath.addId(id);
}
logger.info("Created persister for id [" + id + "]");
return new InnerPersister(path);
}
private class InnerPersister
implements OddjobPersister, ComponentPersister {
private final Path path;
private boolean closed;
private List<InnerPersister> children =
new ArrayList<InnerPersister>();
public InnerPersister(Path path) {
this.path = path;
}
@Override
public ComponentPersister persisterFor(String id) {
if (id == null) {
throw new NullPointerException("No path.");
}
InnerPersister child = new InnerPersister(
this.path.addId(id)) {
public void close() {
super.close();
children.remove(this);
}
};
children.add(child);
return child;
}
@Override
public void persist(String id, Object proxy, ArooaSession session)
throws ComponentPersistException {
if (closed) {
return;
}
if (!(proxy instanceof Serializable)) {
logger.debug("[" + proxy + "] not Serializable - will not persist.");
return;
}
if (proxy instanceof Transient) {
logger.debug("[" + proxy + "] is Transient - will not persist.");
return;
}
if (proxy instanceof OptionallyTransient &&
((OptionallyTransient) proxy).isTransient()) {
logger.debug("[" + proxy + "] is OptionallyTransient - will not persist.");
return;
}
if (include != null && !include.contains(id)) {
logger.debug("[" + proxy + "], id [" + id
+ "] not in include list - will not persist.");
return;
}
if (exclude != null && exclude.contains(id)) {
logger.debug("[" + proxy + "], id [" + id
+ "] in exclude list - will not persist.");
return;
}
PersisterBase.this.persist(path, id, proxy);
}
@Override
public Object restore(String id, ClassLoader classLoader,
ArooaSession session)
throws ComponentPersistException {
if (closed) {
return null;
}
return PersisterBase.this.restore(path, id, classLoader);
}
@Override
public void remove(String id, ArooaSession session)
throws ComponentPersistException {
if (closed) {
return;
}
PersisterBase.this.remove(path, id);
}
@Override
public String[] list()
throws ComponentPersistException {
return PersisterBase.this.list(path);
}
@Override
public void clear() throws ComponentPersistException {
if (closed) {
return;
}
List<ComponentPersister> copy =
new ArrayList<ComponentPersister>(children);
for (ComponentPersister child : copy) {
child.clear();
}
logger.debug("Clearing persister for path [" + path + "]");
PersisterBase.this.clear(path);
}
@Override
public void close() {
closed = true;
}
@Override
public String toString() {
return PersisterBase.this.toString() + ", path=" + path;
}
}
/**
* Provided by subclasses to do the persisting.
*
* @param path The path as a string. Never null.
* @param id The id. Never Null.
* @param component The component or it's proxy.
*/
abstract protected void persist(Path path, String id, Object component)
throws ComponentPersistException;
/**
* Restore a previously persisted Component or it's Proxy.
*
* @param path The path. Never Null.
* @param id The id. Never Null.
* @param classLoader The classLoader.
*
* @return The component or it's proxy. Null if nothing had previously been
* persisted for this path and id.
*/
abstract protected Object restore(Path path, String id, ClassLoader classLoader)
throws ComponentPersistException;
abstract protected String[] list(Path path)
throws ComponentPersistException;
/**
* Remove a possibly previously persisted object.
*
* @param path The path.
* @param id The id.
*/
abstract protected void remove(Path path, String id)
throws ComponentPersistException;
/**
* Remove a possibly previously persisted object.
*
* @param path The path.
* @param id The id.
*/
abstract protected void clear(Path path)
throws ComponentPersistException ;
}