Mercurial > dive4elements > framework
diff artifact-database/src/main/java/de/intevation/artifactdatabase/Backend.java @ 90:68285f7bc476
More javadoc.
artifacts/trunk@846 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Fri, 26 Mar 2010 17:59:50 +0000 |
parents | b2e0cb83631c |
children | e27cf9c84eb8 |
line wrap: on
line diff
--- a/artifact-database/src/main/java/de/intevation/artifactdatabase/Backend.java Fri Mar 26 16:16:32 2010 +0000 +++ b/artifact-database/src/main/java/de/intevation/artifactdatabase/Backend.java Fri Mar 26 17:59:50 2010 +0000 @@ -15,6 +15,9 @@ import org.apache.log4j.Logger; /** + * The backend implements the low level layer used to store artifacts + * in a SQL database. + * * @author <a href="mailto:sascha.teichmann@intevation.de">Sascha L. Teichmann</a> */ public class Backend @@ -22,37 +25,92 @@ { private static Logger logger = Logger.getLogger(Backend.class); + /** + * The SQL statement to create new artifact id inside the database. + */ public static final String SQL_NEXT_ID = SQL.get("artifacts.id.nextval"); + /** + * The SQL statement to insert an artifact into the database. + */ public static final String SQL_INSERT = SQL.get("artifacts.insert"); + /** + * The SQL statement to update some columns of an existing + * artifact in the database. + */ public static final String SQL_UPDATE = SQL.get("artifacts.update"); + /** + * The SQL statement to touch the access time of an + * artifact inside the database. + */ public static final String SQL_TOUCH = SQL.get("artifacts.touch"); + /** + * The SQL statement to load an artifact by a given + * identifier from the database. + */ public static final String SQL_LOAD_BY_GID = SQL.get("artifacts.select.gid"); + /** + * The SQL statement to get the database id of an artifact + * identified by the identifier. + */ public static final String SQL_GET_ID = SQL.get("artifacts.get.id"); + /** + * The SQL statement to replace the content of an + * existing artifact inside the database. + */ public static final String SQL_REPLACE = SQL.get("artifacts.replace"); + /** + * The database cleaner. Reference is stored here because + * the cleaner is woken up if the backend finds an outdated + * artifact. This artifact should be removed as soon as + * possible. + */ protected DatabaseCleaner cleaner; + /** + * To revive an artifact from the bytes coming from the database + * we need the artifact factory which references the artifact + * serializer which is able to do the reviving job. + */ protected FactoryLookup factoryLookup; + /** + * Little helper interface to decouple the ArtifactDatabase + * from the Backend. A ArtifactDatabase should depend on a + * Backend but a Backend not from an ArtifactDatabase. + */ public interface FactoryLookup { + /** + * Returns an ArtifactFactory which is bound to a given name. + * @param factoryName The name of the artifact factory. + * @return The ArtifactFactory bound to the factory name or + * null if not matching factory is found. + */ ArtifactFactory getArtifactFactory(String factoryName); } // interface FactoryLookup + /** + * Inner class that brigdes between the persisten form of the + * artifact and the living one inside the artifact database. + * After the describe(), feed(), advance() and out() operations + * of the artifact it must be possible to write to modified artifact + * back into the database. + */ public final class PersistentArtifact extends Id { @@ -60,6 +118,14 @@ private ArtifactSerializer serializer; private Long ttl; + /** + * Cronstructor to create a persistent artifact. + * @param artifact The living artifact. + * @param serializer The serializer to store the artifact + * after the operations. + * @param ttl The time to life of the artifact. + * @param id The database id of the artifact. + */ public PersistentArtifact( Artifact artifact, ArtifactSerializer serializer, @@ -72,18 +138,34 @@ this.ttl = ttl; } + /** + * Returns the wrapped living artifact. + * @return the living artifact. + */ public Artifact getArtifact() { return artifact; } + /** + * Returns the serialized which is able to write a + * modified artifact back into the database. + * @return The serializer. + */ public ArtifactSerializer getSerializer() { return serializer; } + /** + * The time to life of the artifact. + * @return The time to live. + */ public Long getTTL() { return ttl; } + /** + * Stores the living artifact back into the database. + */ public void store() { if (logger.isDebugEnabled()) { logger.debug("storing artifact id = " + getId()); @@ -91,6 +173,9 @@ Backend.this.store(this); } + /** + * Only touches the access time of the artifact. + */ public void touch() { if (logger.isDebugEnabled()) { logger.debug("touching artifact id = " + getId()); @@ -99,26 +184,59 @@ } } // class ArtifactWithId + /** + * Default constructor + */ public Backend() { } + /** + * Constructor to create a backend with a link to the database cleaner. + * @param cleaner The clean which periodically removes outdated + * artifacts from the database. + */ public Backend(DatabaseCleaner cleaner) { this.cleaner = cleaner; } + /** + * Sets the factory lookup mechanism to decouple ArtifactDatabase + * and Backend. + * @param factoryLookup + */ public void setFactoryLookup(FactoryLookup factoryLookup) { this.factoryLookup = factoryLookup; } + /** + * Sets the database cleaner explicitly. + * @param cleaner The database cleaner + */ public void setCleaner(DatabaseCleaner cleaner) { this.cleaner = cleaner; } + /** + * Returns a new unique identifier to external identify + * the artifact across the system. This implementation + * uses random UUIDs v4 to achieve this target. + * @return the new identifier + */ public String newIdentifier() { // TODO: check database for collisions. return StringUtils.newUUID(); } + /** + * Stores a new artifact into the database. + * @param artifact The artifact to be stored + * @param factory The factory which build the artifact + * @param ttl The initial time to life of the artifact. + * @return A persistent wrapper around the living + * artifact to be able to write modification later. + * @throws Exception Thrown if something went wrong with the + * storage process. + */ public PersistentArtifact storeInitially( Artifact artifact, ArtifactFactory factory, @@ -133,6 +251,17 @@ insertDatabase(artifact, factory, ttl)); } + /** + * Stores an artifact into database if it does not exist there. + * If it exists there it is only updated. + * @param artifact The artifact to store/update. + * @param factory The factory which created the artifact. + * @param ttl The initial time to live of the artifact. + * @return A persistent version of the artifact to be able + * to store a modification later. + * @throws Exception Thrown if something went wrong during + * storing/updating. + */ public PersistentArtifact storeOrReplace( Artifact artifact, ArtifactFactory factory, @@ -147,12 +276,32 @@ storeOrReplaceDatabase(artifact, factory, ttl)); } + /** + * Implementors of this interface are able to process the raw + * artifact data from the database for loading. + */ public interface ArtifactLoader { + /** + * Creates a custom object from the raw artifact database data. + * @param factory The factory that created this artifact. + * @param ttl The current time to life of the artifact. + * @param bytes The raw artifact bytes from the database. + * @param id The database id of the artifact. + * @return The custom object created by the implementation. + */ Object load(ArtifactFactory factory, Long ttl, byte [] bytes, int id); } // interface ArtifactLoader + /** + * Fetches an artifact from the database identified by the + * given identifier. + * @param identifer The identifier of the artifact. + * @return A persistent wrapper around the found artifact + * to be able to write back a modifaction later or null + * if no artifact is found for this identifier. + */ public PersistentArtifact getArtifact(String identifer) { return (PersistentArtifact)loadArtifact( @@ -176,6 +325,13 @@ }); } + /** + * More general loading mechanism for artifacts. The concrete + * load processing is delegated to the given loader. + * @param identifer The identifier of the artifact. + * @param loader The loader which processes the raw database data. + * @return The object created by the loader. + */ public Object loadArtifact(String identifer, ArtifactLoader loader) { if (!StringUtils.checkUUID(identifer)) { @@ -250,6 +406,11 @@ return null; } + /** + * Called if the load mechanism found an outdated artifact. + * It wakes up the database cleaner. + * @param id The id of the outdated artifact. + */ protected void artifactOutdated(int id) { if (logger.isDebugEnabled()) { logger.info("artifactOutdated: id = " + id); @@ -268,7 +429,8 @@ .getArtifactFactory(factoryName); if (factory == null) { - logger.error("reviveArtifact: no factory '" + factoryName + "' found"); + logger.error( + "reviveArtifact: no factory '" + factoryName + "' found"); return null; } @@ -277,6 +439,15 @@ return serializer.fromBytes(bytes); } + /** + * Internal method to store/replace an artifact inside the database. + * If an artifact with the given identifier does not exists it is + * created else only the content data is updated. + * @param artifact The artifact to be store/update inside the database. + * @param factory The factory that created the artifact. + * @param ttl The initial time to life of the artifact. + * @return The database id of the stored/updated artifact. + */ protected int storeOrReplaceDatabase( Artifact artifact, ArtifactFactory factory, @@ -391,6 +562,13 @@ throw new RuntimeException("failed insert artifact into database"); } + /** + * Internal method to store an artifact inside the database. + * @param artifact The artifact to be stored. + * @param factory The factory which created the artifact. + * @param ttl The initial time to live of the artifact. + * @return The database id of the stored artifact. + */ protected int insertDatabase( Artifact artifact, ArtifactFactory factory, @@ -470,6 +648,11 @@ throw new RuntimeException("failed insert artifact into database"); } + /** + * Touches the access timestamp of a given artifact to prevent + * that it will be removed from the database by the database cleaner. + * @param artifact The persistent wrapper around the living artifact. + */ public void touch(PersistentArtifact artifact) { try { @@ -508,6 +691,11 @@ } } + /** + * Writes modification of an artifact back to the database. + * @param artifact The persistent wrapper around a living + * artifact. + */ public void store(PersistentArtifact artifact) { try {