/*
* Created on Mar 22, 2003
*/
package net.sf.jportlet.impl;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import net.sf.jportlet.portlet.PortletException;
import net.sf.jportlet.portlet.application.PortletProxy;
import net.sf.jportlet.service.PortletServiceFactory;
import net.sf.jportlet.service.jdbc.JDBCService;
/**
* Base class of all classes that contains persistent attributes
*
* @author <a href="mailto:tchbansi@sourceforge.net">Herve Tchepannou</a>
*/
public abstract class PersistentAttributes
{
//~ Static fields/initializers ---------------------------------------------
private static final Log __log = LogFactory.getLog( PersistentAttributes.class );
//~ Instance fields --------------------------------------------------------
private HashMap _data = new HashMap( );
private HashSet _dirty = new HashSet( );
private boolean _init;
private HashSet _new = new HashSet( );
private PortletProxy _proxy;
private HashSet _removed = new HashSet( );
private PortletServiceFactory _serviceFactory;
//~ Constructors -----------------------------------------------------------
public PersistentAttributes( PortletProxy proxy,
PortletServiceFactory serviceFactory )
{
_proxy = proxy;
_serviceFactory = serviceFactory;
}
//~ Methods ----------------------------------------------------------------
private void close( ResultSet rs,
PreparedStatement stmt,
Connection cnn )
throws SQLException
{
if ( rs != null )
{
rs.close( );
}
if ( stmt != null )
{
stmt.close( );
}
if ( cnn != null )
{
cnn.close( );
}
}
public String getAttribute( String name )
{
init( );
return ( String ) _data.get( name );
}
public String getAttribute( String name,
String defaultValue )
{
String value = getAttribute( name );
return ( value != null )
? value
: defaultValue;
}
public Enumeration getAttributeNames( )
{
init( );
return Collections.enumeration( _data.keySet( ) );
}
private Connection getConnection( )
throws Exception
{
JDBCService srv = ( JDBCService ) _serviceFactory.getPortletService( JDBCService.NAME );
return srv.getConnection( );
}
protected abstract String getDeleteSQL( );
protected abstract String getInsertSQL( );
protected String getPortletName( )
{
return _proxy.getDescriptor( ).getName( );
}
protected abstract String getSelectSQL( );
protected abstract String getUpdateSQL( );
private void init( )
{
if ( _init )
{
return;
}
boolean debug = __log.isDebugEnabled( );
if ( debug )
{
__log.debug( "Initializing" );
}
Connection cnn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try
{
cnn = getConnection( );
stmt = cnn.prepareStatement( getSelectSQL( ) );
prepareSelect( stmt );
rs = stmt.executeQuery( );
while ( rs.next( ) )
{
String name = rs.getString( 1 );
String value = rs.getString( 2 );
if ( debug )
{
__log.debug( "...Adding: " + name + "=" + value );
}
_data.put( name, value );
}
/* Initialized */
_init = true;
}
catch ( Exception e )
{
__log.warn( "Error while loading data", e );
}
finally
{
try
{
close( rs, stmt, cnn );
}
catch ( Exception e )
{
__log.warn( "Error while closing the connection", e );
}
}
}
protected abstract void prepareDelete( String name,
PreparedStatement stmt )
throws SQLException;
protected abstract void prepareInsert( String name,
String value,
PreparedStatement stmt )
throws SQLException;
protected abstract void prepareSelect( PreparedStatement stmt )
throws SQLException;
protected abstract void prepareUpdate( String name,
String value,
PreparedStatement stmt )
throws SQLException;
public void removeAttribute( String name )
{
init( );
_data.remove( name );
_dirty.remove( name );
_removed.add( name );
_new.remove( name );
}
public void setAttribute( String name,
String value )
{
init( );
if ( _data.containsKey( name ) )
{
_dirty.add( name );
}
else
{
_new.add( name );
}
_data.put( name, value );
_removed.remove( name );
}
public void store( )
throws PortletException
{
boolean debug = __log.isDebugEnabled( );
if ( debug )
{
__log.debug( "Storing data" );
}
Connection cnn = null;
PreparedStatement stmt = null;
try
{
cnn = getConnection( );
cnn.setAutoCommit( true );
/* Remove */
stmt = cnn.prepareStatement( getDeleteSQL( ) );
Iterator it = _removed.iterator( );
while ( it.hasNext( ) )
{
String name = it.next( ).toString( );
if ( debug )
{
__log.debug( "...Deleting: " + name );
}
prepareDelete( name, stmt );
stmt.execute( );
}
/* Update */
stmt = cnn.prepareStatement( getUpdateSQL( ) );
it = _dirty.iterator( );
while ( it.hasNext( ) )
{
String name = ( String ) it.next( );
String value = ( String ) _data.get( name );
if ( debug )
{
__log.debug( "...Updating: " + name + "=" + value );
}
prepareUpdate( name, value, stmt );
stmt.execute( );
}
/* Insert */
stmt = cnn.prepareStatement( getInsertSQL( ) );
it = _new.iterator( );
while ( it.hasNext( ) )
{
String name = ( String ) it.next( );
String value = ( String ) _data.get( name );
if ( debug )
{
__log.debug( "...Inserting: " + name + "=" + value );
}
prepareInsert( name, value, stmt );
stmt.execute( );
}
}
catch ( Exception e )
{
throw new PortletException( e );
}
finally
{
try
{
close( null, stmt, cnn );
}
catch ( Exception e )
{
throw new PortletException( e );
}
}
}
}