/*
* Copyright � 2004, Rob Gordon.
*/
package org.oddjob.sql;
import java.sql.Connection;
import java.sql.SQLException;
import org.apache.log4j.Logger;
import org.oddjob.arooa.life.ComponentPersistException;
import org.oddjob.arooa.registry.Path;
import org.oddjob.persist.OddjobPersister;
import org.oddjob.persist.PersisterBase;
/**
* @oddjob.description Persists job state to a database. The database must
* have a table which can be created with the following sql.
* <pre><code>
* CREATE TABLE oddjob(
* path VARCHAR(128),
* id VARCHAR(32),
* job BLOB,
* CONSTRAINT oddjob_pk PRIMARY KEY (path, id))
* </pre></code>
*
* @oddjob.example
*
* Using a SQL Persister.
*
* {@oddjob.xml.resource org/oddjob/sql/SqlPersisterTest.xml}
*
* Note that because this is a service, it must be stopped once the inner Oddjob
* has completed it's work. In an Oddjob that was running continually this would
* not be necessary.
*
* @author Rob Gordon.
*/
public class SQLPersisterService {
private static final Logger logger = Logger.getLogger(SQLPersisterService.class);
/**
* @oddjob.property
* @oddjob.description The {@link ConnectionType} to use.
* @oddjob.required Yes.
*/
private Connection connection;
/**
* @oddjob.property
* @oddjob.description The name.
* @oddjob.required No.
*/
private String name;
/**
* @oddjob.property
* @oddjob.description A plugin for providers of the serialization.
* The default is for HSQL.
* @oddjob.required No.
*/
private SQLSerializationFactory serializationFactory;
/** The actual serialization. */
private volatile SQLSerialization serialization;
public void start() throws SQLException {
if (serializationFactory == null) {
serializationFactory = new HSQLSerializationFactory();
}
serialization = serializationFactory.createSerialization(connection);
}
public void stop() throws SQLException {
if (serialization != null) {
serialization.close();
serialization = null;
}
}
/**
* Set the connection.
*
* @param connection The connection.
*/
public void setConnection(Connection connection) throws SQLException {
this.connection = connection;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public SQLSerializationFactory getSerializationFactory() {
return serializationFactory;
}
public void setSerializationFactory(SQLSerializationFactory serializationFactory) {
this.serializationFactory = serializationFactory;
}
/**
* @oddjob.property persister
* @oddjob.description The persister.
* @oddjob.required R/O.
*/
public OddjobPersister getPersister(String path) {
return new SQLPersister(path);
}
@Override
public String toString() {
if (name == null) {
return getClass().getSimpleName();
}
else {
return name;
}
}
class SQLPersister extends PersisterBase {
public SQLPersister(String path) {
super(path == null ? null : new Path(path));
}
@Override
protected void persist(Path path, String id, Object o)
throws ComponentPersistException {
if (serialization == null) {
throw new IllegalStateException("Persister Service Not Started.");
}
try {
serialization.persist(path, id, o);
logger.debug("Saved [" + o + "], id [" + id
+ "] to database.");
}
catch (SQLException e) {
throw new ComponentPersistException("Failed saving object id ["
+ id + "], class [" + o.getClass().getName()
+ "], object [" + o + "]."
, e);
}
}
@Override
protected Object restore(Path path, String id, ClassLoader classLoader)
throws ComponentPersistException {
if (serialization == null) {
throw new IllegalStateException("Persister Service Not Started.");
}
try {
return serialization.restore(path, id, classLoader);
}
catch (SQLException e) {
throw new ComponentPersistException("Failed to restore object.", e);
}
}
@Override
protected String[] list(Path path)
throws ComponentPersistException {
if (serialization == null) {
throw new IllegalStateException("Persister Service Not Started.");
}
try {
return serialization.children(path);
}
catch (SQLException e) {
throw new ComponentPersistException("Failed to remove object.", e);
}
}
@Override
protected void remove(Path path, String id)
throws ComponentPersistException {
if (serialization == null) {
throw new IllegalStateException("Persister Service Not Started.");
}
try {
serialization.remove(path, id);
}
catch (SQLException e) {
throw new ComponentPersistException("Failed to remove object.", e);
}
}
@Override
protected void clear(Path path)
throws ComponentPersistException {
if (serialization == null) {
throw new IllegalStateException("Persister Service Not Started.");
}
try {
serialization.clear(path);
}
catch (SQLException e) {
throw new ComponentPersistException("Failed to clear.", e);
}
}
@Override
public String toString() {
return getClass().getSimpleName();
}
}
}