Mercurial > dive4elements > framework
view artifact-database/src/main/java/de/intevation/artifactdatabase/Backend.java @ 83:8c4638abd518
Installed a SLF4J bridge to route incoming jul logs (used by restlet) to log4j.
artifacts/trunk@820 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author | Ingo Weinzierl <ingo.weinzierl@intevation.de> |
---|---|
date | Mon, 22 Mar 2010 15:54:06 +0000 |
parents | 8447467cef86 |
children | 72e2dd4feb31 |
line wrap: on
line source
package de.intevation.artifactdatabase; import java.sql.Connection; import java.sql.SQLException; import java.sql.PreparedStatement; import java.sql.Types; import java.sql.ResultSet; import javax.sql.DataSource; import de.intevation.artifacts.Artifact; import de.intevation.artifacts.ArtifactFactory; import de.intevation.artifacts.ArtifactSerializer; import org.apache.log4j.Logger; /** * @author <a href="mailto:sascha.teichmann@intevation.de">Sascha L. Teichmann</a> */ public class Backend implements DatabaseCleaner.ArtifactReviver { private static Logger logger = Logger.getLogger(Backend.class); public static final String SQL_NEXT_ID = SQL.get("artifacts.id.nextval"); public static final String SQL_INSERT = SQL.get("artifacts.insert"); public static final String SQL_UPDATE = SQL.get("artifacts.update"); public static final String SQL_TOUCH = SQL.get("artifacts.touch"); public static final String SQL_LOAD_BY_GID = SQL.get("artifacts.select.gid"); public static final String SQL_GET_ID = SQL.get("artifacts.get.id"); public static final String SQL_REPLACE = SQL.get("artifacts.replace"); protected DatabaseCleaner cleaner; protected FactoryLookup factoryLookup; public interface FactoryLookup { ArtifactFactory getArtifactFactory(String factoryName); } // interface FactoryLookup public final class PersistentArtifact extends Id { private Artifact artifact; private ArtifactSerializer serializer; public PersistentArtifact( Artifact artifact, ArtifactSerializer serializer, int id ) { super(id); this.artifact = artifact; this.serializer = serializer; } public Artifact getArtifact() { return artifact; } public ArtifactSerializer getSerializer() { return serializer; } public void store() { if (logger.isDebugEnabled()) { logger.debug("storing artifact id = " + getId()); } Backend.this.store(this); } public void touch() { if (logger.isDebugEnabled()) { logger.debug("touching artifact id = " + getId()); } Backend.this.touch(this); } } // class ArtifactWithId public Backend() { } public Backend(DatabaseCleaner cleaner) { this.cleaner = cleaner; } public void setFactoryLookup(FactoryLookup factoryLookup) { this.factoryLookup = factoryLookup; } public void setCleaner(DatabaseCleaner cleaner) { this.cleaner = cleaner; } public String newIdentifier() { // TODO: check database for collisions. return StringUtils.newUUID(); } public PersistentArtifact storeInitially( Artifact artifact, ArtifactFactory factory, Long ttl ) throws Exception { return new PersistentArtifact( artifact, factory.getSerializer(), insertDatabase(artifact, factory, ttl)); } public PersistentArtifact storeOrReplace( Artifact artifact, ArtifactFactory factory, Long ttl ) throws Exception { return new PersistentArtifact( artifact, factory.getSerializer(), storeOrReplaceDatabase(artifact, factory, ttl)); } public interface ArtifactLoader { Object load(ArtifactFactory factory, byte [] bytes, int id); } // interface ArtifactLoader public PersistentArtifact getArtifact(String identifer) { return (PersistentArtifact)loadArtifact( identifer, new ArtifactLoader() { public Object load( ArtifactFactory factory, byte [] bytes, int id ) { ArtifactSerializer serializer = factory.getSerializer(); Artifact artifact = serializer.fromBytes(bytes); return artifact == null ? null : new PersistentArtifact(artifact, serializer, id); } }); } public Object loadArtifact(String identifer, ArtifactLoader loader) { if (!StringUtils.checkUUID(identifer)) { return null; } Connection connection = null; PreparedStatement stmnt_load = null; ResultSet load_result = null; DataSource dataSource = DBConnection.getDataSource(); try { connection = dataSource.getConnection(); stmnt_load = connection.prepareStatement(SQL_LOAD_BY_GID); stmnt_load.setString(1, identifer); load_result = stmnt_load.executeQuery(); if (!load_result.next()) { return null; } int id = load_result.getInt(1); long ttl = load_result.getLong(3); if (!load_result.wasNull()) { // real time to life long last_access = load_result.getTimestamp(2).getTime(); if (last_access + ttl < System.currentTimeMillis()) { artifactOutdated(id); return null; } } String factoryName = load_result.getString(4); if (factoryLookup == null) { logger.error("factory lookup == null"); return null; } ArtifactFactory factory = factoryLookup .getArtifactFactory(factoryName); if (factory == null) { logger.error("factory '" + factoryName + "' not found"); return null; } byte [] bytes = load_result.getBytes(5); return loader.load(factory, bytes, id); } catch (SQLException sqle) { logger.error(sqle.getLocalizedMessage(), sqle); } finally { if (load_result != null) { try { load_result.close(); } catch (SQLException sqle) {} } if (stmnt_load != null) { try { load_result.close(); } catch (SQLException sqle) {} } if (connection != null) { try { connection.close(); } catch (SQLException sqle) {} } } return null; } protected void artifactOutdated(int id) { if (logger.isDebugEnabled()) { logger.info("artifactOutdated: id = " + id); } if (cleaner != null) { cleaner.wakeup(); } } public Artifact reviveArtifact(String factoryName, byte [] bytes) { if (factoryLookup == null) { logger.error("reviveArtifact: factory lookup == null"); return null; } ArtifactFactory factory = factoryLookup .getArtifactFactory(factoryName); if (factory == null) { logger.error("reviveArtifact: no factory '" + factoryName + "' found"); return null; } ArtifactSerializer serializer = factory.getSerializer(); return serializer.fromBytes(bytes); } protected int storeOrReplaceDatabase( Artifact artifact, ArtifactFactory factory, Long ttl ) { String uuid = artifact.identifier(); if (!StringUtils.checkUUID(uuid)) { throw new RuntimeException("No valid UUID"); } Connection connection = null; PreparedStatement stmnt = null; ResultSet result = null; DataSource dataSource = DBConnection.getDataSource(); try { connection = dataSource.getConnection(); try { connection.setAutoCommit(false); stmnt = connection.prepareStatement(SQL_GET_ID); stmnt.setString(1, uuid); result = stmnt.executeQuery(); Integer ID = result.next() ? Integer.valueOf(result.getInt(1)) : null; result.close(); result = null; stmnt.close(); stmnt = null; if (ID != null) { // already in database int id = ID.intValue(); stmnt = connection.prepareStatement(SQL_REPLACE); if (ttl == null) { stmnt.setNull(1, Types.BIGINT); } else { stmnt.setLong(1, ttl.longValue()); } stmnt.setString(2, factory.getName()); stmnt.setBytes( 3, factory.getSerializer().toBytes(artifact)); stmnt.setInt(4, id); stmnt.execute(); connection.commit(); return id; } stmnt = connection.prepareStatement(SQL_NEXT_ID); result = stmnt.executeQuery(); if (!result.next()) { throw new RuntimeException("No id generated"); } int id = result.getInt(1); result.close(); result = null; stmnt.close(); stmnt = null; stmnt = connection.prepareStatement(SQL_INSERT); stmnt.setInt(1, id); stmnt.setString(2, uuid); if (ttl == null) { stmnt.setNull(3, Types.BIGINT); } else { stmnt.setLong(3, ttl.longValue()); } stmnt.setString(4, factory.getName()); stmnt.setBytes( 5, factory.getSerializer().toBytes(artifact)); stmnt.execute(); connection.commit(); return id; } catch (SQLException sqle) { connection.rollback(); throw sqle; } } catch (SQLException sqle) { logger.error(sqle.getLocalizedMessage(), sqle); } finally { if (result != null) { try { result.close(); } catch (SQLException sqle) {} } if (stmnt != null) { try { stmnt.close(); } catch (SQLException sqle) {} } if (connection != null) { try { connection.close(); } catch (SQLException sqle) {} } } throw new RuntimeException("failed insert artifact into database"); } protected int insertDatabase( Artifact artifact, ArtifactFactory factory, Long ttl ) { String uuid = artifact.identifier(); Connection connection = null; PreparedStatement stmnt_next_id = null; PreparedStatement stmnt_insert = null; ResultSet res_id = null; DataSource dataSource = DBConnection.getDataSource(); try { connection = dataSource.getConnection(); try { connection.setAutoCommit(false); stmnt_next_id = connection.prepareStatement(SQL_NEXT_ID); stmnt_insert = connection.prepareStatement(SQL_INSERT); res_id = stmnt_next_id.executeQuery(); if (!res_id.next()) { throw new RuntimeException("No id generated"); } int id = res_id.getInt(1); stmnt_insert.setInt(1, id); stmnt_insert.setString(2, uuid); if (ttl == null) { stmnt_insert.setNull(3, Types.BIGINT); } else { stmnt_insert.setLong(3, ttl.longValue()); } stmnt_insert.setString(4, factory.getName()); stmnt_insert.setBytes( 5, factory.getSerializer().toBytes(artifact)); stmnt_insert.execute(); connection.commit(); return id; } catch (SQLException sqle) { connection.rollback(); throw sqle; } } catch (SQLException sqle) { logger.error(sqle.getLocalizedMessage(), sqle); } finally { if (res_id != null) { try { res_id.close(); } catch (SQLException sqle) {} } if (stmnt_insert != null) { try { stmnt_insert.close(); } catch (SQLException sqle) {} } if (stmnt_next_id != null) { try { stmnt_next_id.close(); } catch (SQLException sqle) {} } if (connection != null) { try { connection.close(); } catch (SQLException sqle) {} } } throw new RuntimeException("failed insert artifact into database"); } public void touch(PersistentArtifact artifact) { try { Connection connection = null; PreparedStatement stmnt_touch = null; DataSource dataSource = DBConnection.getDataSource(); try { connection = dataSource.getConnection(); try { connection.setAutoCommit(false); stmnt_touch = connection.prepareStatement(SQL_TOUCH); stmnt_touch.setInt(1, artifact.getId()); stmnt_touch.execute(); connection.commit(); } catch (SQLException sqle) { connection.rollback(); } } catch (SQLException sqle) { logger.error(sqle.getLocalizedMessage(), sqle); } finally { if (stmnt_touch != null) { try { stmnt_touch.close(); } catch (SQLException sqle) {} } if (connection != null) { try { connection.close(); } catch (SQLException sqle) {} } } } catch (Exception e) { logger.error(e.getLocalizedMessage(), e); } } public void store(PersistentArtifact artifact) { try { Connection connection = null; PreparedStatement stmnt_update = null; DataSource dataSource = DBConnection.getDataSource(); try { connection = dataSource.getConnection(); try { connection.setAutoCommit(false); stmnt_update = connection.prepareStatement(SQL_UPDATE); stmnt_update.setInt(2, artifact.getId()); byte [] bytes = artifact .getSerializer() .toBytes(artifact.getArtifact()); stmnt_update.setBytes(1, bytes); stmnt_update.execute(); connection.commit(); } catch (SQLException sqle) { connection.rollback(); } } catch (SQLException sqle) { logger.error(sqle.getLocalizedMessage(), sqle); } finally { if (stmnt_update != null) { try { stmnt_update.close(); } catch (SQLException sqle) {} } if (connection != null) { try { connection.close(); } catch (SQLException sqle) {} } } } catch (Exception e) { logger.error(e.getLocalizedMessage(), e); } } } // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :