/* * Copyright 2000-2013 Enonic AS * http://www.enonic.com/license */ package com.enonic.cms.store.hibernate.cache.invalidation; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import com.enonic.cms.framework.jdbc.ConnectionDecorator; import com.enonic.cms.framework.jdbc.wrapper.ConnectionWrapper; import com.enonic.cms.framework.jdbc.wrapper.PreparedStatementWrapper; import com.enonic.cms.framework.jdbc.wrapper.StatementWrapper; /** * This class implements a connection decorator based on the auto cache invalidator. */ public final class InvalidatorConnectionDecorator implements ConnectionDecorator { private final CacheInvalidator invalidator; public InvalidatorConnectionDecorator( final CacheInvalidator invalidator ) { this.invalidator = invalidator; } @Override public Connection decorate( final Connection connection ) throws SQLException { return new ConnectionImpl( connection ); } private final class ConnectionImpl extends ConnectionWrapper { public ConnectionImpl( final Connection conn ) { super( conn ); } @Override protected Statement createWrappedStatement( final Statement stmt ) { return new StatementImpl( stmt, this ); } @Override protected PreparedStatement createWrappedPreparedStatement( final PreparedStatement stmt, final String sql ) { return new PreparedStatementImpl( sql, stmt, this ); } } private final class StatementImpl extends StatementWrapper { public StatementImpl( final Statement stmt, final Connection conn ) { super( stmt, conn ); } @Override public int executeUpdate( final String sql ) throws SQLException { invalidator.invalidateSql( sql ); return super.executeUpdate( sql ); } @Override public boolean execute( final String sql ) throws SQLException { invalidator.invalidateSql( sql ); return super.execute( sql ); } @Override protected ResultSet createWrappedResultSet( final ResultSet result ) throws SQLException { return result; } } private final class PreparedStatementImpl extends PreparedStatementWrapper { private final String sql; private final ArrayList<Object> paramList; public PreparedStatementImpl( final String sql, final PreparedStatement stmt, final Connection conn ) { super( stmt, conn ); this.sql = sql; this.paramList = new ArrayList<Object>(); } @Override public boolean execute() throws SQLException { invalidator.invalidateSql( this.sql, this.paramList ); return super.execute(); } @Override public int executeUpdate() throws SQLException { invalidator.invalidateSql( this.sql, this.paramList ); return super.executeUpdate(); } @Override public int executeUpdate( String sql ) throws SQLException { invalidator.invalidateSql( sql ); return super.executeUpdate( sql ); } @Override public boolean execute( String sql ) throws SQLException { invalidator.invalidateSql( sql ); return super.execute( sql ); } @Override public void setObject( int parameterIndex, Object x ) throws SQLException { super.setObject( parameterIndex, x ); setParam( parameterIndex, x ); } @Override public void setObject( int parameterIndex, Object x, int targetSqlType ) throws SQLException { super.setObject( parameterIndex, x, targetSqlType ); setParam( parameterIndex, x ); } @Override public void setObject( int parameterIndex, Object x, int targetSqlType, int scale ) throws SQLException { super.setObject( parameterIndex, x, targetSqlType, scale ); setParam( parameterIndex, x ); } @Override public void setString( int parameterIndex, String x ) throws SQLException { super.setString( parameterIndex, x ); setParam( parameterIndex, x ); } @Override public void setInt( int parameterIndex, int x ) throws SQLException { super.setInt( parameterIndex, x ); setParam( parameterIndex, x ); } private void setParam( int index, Object value ) { while ( this.paramList.size() < index ) { this.paramList.add( null ); } this.paramList.set( index - 1, value ); } @Override protected ResultSet createWrappedResultSet( final ResultSet result ) throws SQLException { return result; } } }