Mercurial > dive4elements > framework
view artifact-database/src/main/java/de/intevation/artifactdatabase/Backend.java @ 17:5a6b6a3debc7
Integrated logging into artifact database.
artifacts/trunk@33 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Tue, 08 Sep 2009 06:29:52 +0000 |
parents | 9ad6ec2d09c3 |
children | 72abee95fd64 |
line wrap: on
line source
package de.intevation.artifactdatabase; import org.w3c.dom.Document; import java.util.UUID; import java.sql.Connection; import java.sql.SQLException; import java.sql.PreparedStatement; import java.sql.Types; import java.sql.ResultSet; import java.sql.Timestamp; import javax.sql.DataSource; import java.io.IOException; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectOutputStream; import java.io.ObjectInputStream; import java.util.zip.GZIPOutputStream; import java.util.zip.GZIPInputStream; import de.intevation.artifacts.ArtifactFactory; import de.intevation.artifacts.Artifact; import org.apache.log4j.Logger; /** * @author Sascha L. Teichmann */ public class Backend { 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"); /** * Used to wrap the calls to invole database actions. */ public class ArtifactProxy implements Artifact { protected Artifact original; protected int id; protected boolean unwritten; public ArtifactProxy() { } public ArtifactProxy(Artifact original, int id, boolean unwritten) { this.original = original; this.id = id; this.unwritten = unwritten; } public Artifact getOriginal() { return original; } public int getId() { return id; } public boolean isUnwritten() { return unwritten; } public String identifier() { return original.identifier(); } public String hash() { return original.hash(); } public Document describe(Object context) { try { return original.describe(context); } finally { touch(this); } } public Document advance(Document target, Object context) { try { return original.advance(target, context); } finally { store(this); } } public Document feed(Document data, Object context) { try { return original.feed(data, context); } finally { store(this); } } public byte [] out(Document format, Object context) { try { return original.out(format, context); } finally { touch(this); } } public void setup(String identifier, Object context) { original.setup(identifier, context); } public void endOfLife(Object context) { original.endOfLife(context); } public byte [] toBytes() { try { ByteArrayOutputStream bos = new ByteArrayOutputStream(); GZIPOutputStream gos = new GZIPOutputStream(bos); ObjectOutputStream oos = new ObjectOutputStream(gos); oos.writeObject(original); oos.flush(); return bos.toByteArray(); } catch (IOException ioe) { logger.error(ioe.getLocalizedMessage(), ioe); throw new RuntimeException(ioe); } } } // class ArtifactProxy public Backend() { } public Artifact getArtifact(String idenitfier) { UUID uuid; try { uuid = UUID.fromString(idenitfier); } catch (IllegalArgumentException iae) { logger.warn(iae.getLocalizedMessage()); return null; } return getArtifactByUUID(uuid); } public Artifact createArtifactWithFactory( ArtifactFactory factory, Object context ) { UUID uuid = UUID.randomUUID(); Artifact artifact = factory.createArtifact( uuid.toString(), context); Long ttl = factory.timeToLiveUntouched( artifact, context); int id = insertDatabase(uuid, ttl); return new ArtifactProxy(artifact, id, true); } protected Artifact getArtifactByUUID(UUID uuid) { 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, uuid.toString()); 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; } } byte [] bytes = load_result.getBytes(4); if (bytes == null) { return null; } Artifact original = restoreArtifact(bytes); if (original == null) { return null; } return new ArtifactProxy(original, id, false); } 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; } public static Artifact restoreArtifact(byte [] bytes) { ObjectInputStream ois = null; try { ByteArrayInputStream bis = new ByteArrayInputStream(bytes); GZIPInputStream gis = new GZIPInputStream(bis); ois = new ObjectInputStream(gis); return (Artifact)ois.readObject(); } catch (IOException ioe) { logger.error(ioe.getLocalizedMessage(), ioe); } catch (ClassNotFoundException cnfe) { logger.error(cnfe.getLocalizedMessage(), cnfe); } catch (ClassCastException cce) { logger.error(cce.getLocalizedMessage(), cce); } finally { if (ois != null) { try { ois.close(); } catch (IOException ioe) { } } } return null; } protected void artifactOutdated(int id) { logger.info("artifactOutdated: id = " + id); } protected int insertDatabase(UUID uuid, Long ttl) { 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.toString()); if (ttl == null) { stmnt_insert.setNull(3, Types.BIGINT); } else { stmnt_insert.setLong(3, ttl.longValue()); } 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(ArtifactProxy proxy) { logger.info("touch: " + proxy); if (proxy.isUnwritten()) { store(proxy); return; } Connection connection = null; PreparedStatement stmnt_touch = null; DataSource dataSource = DBConnection.getDataSource(); try { connection = dataSource.getConnection(); try { connection.setAutoCommit(false); stmnt_touch = connection.prepareStatement(SQL_UPDATE); stmnt_touch.setInt(1, proxy.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) {} } } } public void store(ArtifactProxy proxy) { logger.info("store: " + proxy); 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(1, proxy.getId()); stmnt_update.setBytes(2, proxy.toBytes()); 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) {} } } } } // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8: