User: forder
Date: 00/08/05 19:03:54
Added: src/main/org/jboss/ejb/plugins/jaws/jdbc
JDBCActivateEntityCommand.java
JDBCBeanExistsCommand.java JDBCCommand.java
JDBCCommandFactory.java
JDBCCreateEntityCommand.java
JDBCDefinedFinderCommand.java
JDBCDestroyCommand.java JDBCFindAllCommand.java
JDBCFindByCommand.java JDBCFindEntitiesCommand.java
JDBCFindEntityCommand.java JDBCFinderCommand.java
JDBCInitCommand.java JDBCLoadEntityCommand.java
JDBCPassivateEntityCommand.java
JDBCQueryCommand.java JDBCRemoveEntityCommand.java
JDBCStartCommand.java JDBCStopCommand.java
JDBCStoreEntityCommand.java JDBCUpdateCommand.java
Log:
Commands version of JAWS
Revision Changes Path
1.1
jboss/src/main/org/jboss/ejb/plugins/jaws/jdbc/JDBCActivateEntityCommand.java
Index: JDBCActivateEntityCommand.java
===================================================================
/*
* jBoss, the OpenSource EJB server
*
* Distributable under GPL license.
* See terms of license at gnu.org.
*/
package org.jboss.ejb.plugins.jaws.jdbc;
import java.rmi.RemoteException;
import java.rmi.ServerException;
import javax.ejb.EntityBean;
import org.jboss.ejb.EntityEnterpriseContext;
import org.jboss.ejb.plugins.jaws.JAWSPersistenceManager;
import org.jboss.ejb.plugins.jaws.JPMActivateEntityCommand;
/**
* JAWSPersistenceManager JDBCActivateEntityCommand
*
* @see <related>
* @author <a href="mailto:[EMAIL PROTECTED]">Rickard �berg</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Justin Forder</a>
* @version $Revision: 1.1 $
*/
public class JDBCActivateEntityCommand implements JPMActivateEntityCommand
{
// Constructors --------------------------------------------------
public JDBCActivateEntityCommand(JDBCCommandFactory factory)
{
}
// JPMActivateEntityCommand implementation -----------------------
public void execute(EntityEnterpriseContext ctx)
throws RemoteException
{
// Set new persistence context
// JF: Passivation/Activation is losing persistence context!!!
ctx.setPersistenceContext(new JAWSPersistenceManager.PersistenceContext());
}
}
1.1
jboss/src/main/org/jboss/ejb/plugins/jaws/jdbc/JDBCBeanExistsCommand.java
Index: JDBCBeanExistsCommand.java
===================================================================
/*
* jBoss, the OpenSource EJB server
*
* Distributable under GPL license.
* See terms of license at gnu.org.
*/
package org.jboss.ejb.plugins.jaws.jdbc;
import java.util.Iterator;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.jboss.ejb.EntityEnterpriseContext;
import org.jboss.ejb.plugins.jaws.MetaInfo;
import org.jboss.ejb.plugins.jaws.PkFieldInfo;
import org.jboss.logging.Log;
/**
* JDBCBeanExistsCommand
*
* @see <related>
* @author <a href="mailto:[EMAIL PROTECTED]">Marc Fleury</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Justin Forder</a>
* @version $Revision: 1.1 $
*/
public class JDBCBeanExistsCommand extends JDBCQueryCommand
{
// Attributes ----------------------------------------------------
private Object idArgument; // the id given to execute()
private boolean result; // the result to be returned by execute()
// Constructors --------------------------------------------------
public JDBCBeanExistsCommand(JDBCCommandFactory factory)
{
super(factory, "Exists");
String sql = "SELECT COUNT(*) AS Total FROM " + metaInfo.getTableName() +
" WHERE " + getPkColumnWhereList();
setSQL(sql);
}
// Public --------------------------------------------------------
// Checks whether the database already holds the entity
public boolean execute(Object id)
{
// Save argument so setParameters() can access it
idArgument = id;
// Assume bean doesn't exist; handleResult() can change this
result = false;
try
{
jdbcExecute();
} catch (Exception e)
{
log.exception(e);
}
return result;
}
// JDBCQueryCommand overrides ------------------------------------
protected void setParameters(PreparedStatement stmt)
throws Exception
{
// Primary key in WHERE-clause
Iterator it = metaInfo.getPkFieldInfos();
int i = 1; // parameter index
if (metaInfo.hasCompositeKey())
{
// Compound key
while (it.hasNext())
{
PkFieldInfo pkFieldInfo = (PkFieldInfo)it.next();
int jdbcType = pkFieldInfo.getJDBCType();
Object value = getPkFieldValue(idArgument, pkFieldInfo);
// Set this field of the key
setParameter(stmt, i++, jdbcType, value);
}
} else
{
// We have a Field key
// So just set that field
PkFieldInfo pkFieldInfo = (PkFieldInfo)it.next();
int jdbcType = pkFieldInfo.getJDBCType();
setParameter(stmt, i, jdbcType, idArgument);
}
}
protected void handleResult(ResultSet rs) throws Exception
{
if ( !rs.next() )
{
throw new SQLException("Unable to check for EJB in database");
}
int total = rs.getInt("Total");
result = (total >= 1);
}
}
1.1 jboss/src/main/org/jboss/ejb/plugins/jaws/jdbc/JDBCCommand.java
Index: JDBCCommand.java
===================================================================
/*
* jBoss, the OpenSource EJB server
*
* Distributable under GPL license.
* See terms of license at gnu.org.
*/
package org.jboss.ejb.plugins.jaws.jdbc;
import java.lang.reflect.Field;
import java.util.Iterator;
import java.util.Map;
import java.util.HashMap;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Types;
import java.rmi.RemoteException;
import javax.ejb.EJBObject;
import javax.sql.DataSource;
import org.jboss.ejb.EntityEnterpriseContext;
import org.jboss.ejb.plugins.jaws.CMPFieldInfo;
import org.jboss.ejb.plugins.jaws.MetaInfo;
import org.jboss.ejb.plugins.jaws.PkFieldInfo;
import org.jboss.ejb.plugins.jaws.deployment.JawsEntity;
import org.jboss.ejb.plugins.jaws.deployment.JawsCMPField;
import org.jboss.logging.Log;
/**
* Abstract superclass for all JAWS Commands that use JDBC directly.
* Provides a Template Method for jdbcExecute(), default implementations
* for some of the methods called by this template, and a bunch of
* utility methods that database commands may need to call.
*
* @see <related>
* @author <a href="mailto:[EMAIL PROTECTED]">Justin Forder</a>
* @version $Revision: 1.1 $
*/
public abstract class JDBCCommand
{
// Attributes ----------------------------------------------------
protected JDBCCommandFactory factory;
protected MetaInfo metaInfo;
protected Log log;
protected String name; // Command name, used for debug trace
private String sql;
private static Map jdbcTypeNames;
// Constructors --------------------------------------------------
protected JDBCCommand(JDBCCommandFactory factory, String name)
{
this.factory = factory;
this.metaInfo = factory.getMetaInfo();
this.log = factory.getLog();
this.name = name;
}
// Protected -----------------------------------------------------
/**
* Template method handling the mundane business of opening
* a database connection, preparing a statement, setting its parameters,
* executing the prepared statement, handling the result,
* and cleaning up.
*/
protected void jdbcExecute() throws Exception
{
Connection con = null;
PreparedStatement stmt = null;
try
{
con = getConnection();
String theSQL = getSQL();
if (factory.debug)
{
log.debug(name + " command executing: " + theSQL);
}
stmt = con.prepareStatement(theSQL);
setParameters(stmt);
executeStatementAndHandleResult(stmt);
} finally
{
if (stmt != null)
{
try
{
stmt.close();
} catch (SQLException e)
{
e.printStackTrace();
}
}
if (con != null)
{
try
{
con.close();
} catch (SQLException e)
{
e.printStackTrace();
}
}
}
}
/**
* Used to set static SQL in subclass constructors.
*/
protected void setSQL(String sql)
{
if (factory.debug)
{
log.debug(name + " SQL: " + sql);
}
this.sql = sql;
}
/**
* Default implementation returns <code>sql</code> field value.
* This is appropriate in all cases where static SQL can be
* constructed in the Command constructor.
* Override if dynamically-generated SQL, based on the arguments
* given to execute(), is needed.
*/
protected String getSQL() throws Exception
{
return sql;
}
/**
* Default implementation does nothing.
* Override if parameters need to be set.
*/
protected void setParameters(PreparedStatement stmt) throws Exception
{
}
/**
* Execute the PreparedStatement and handle result of successful execution.
* This is implemented in subclasses for queries and updates.
*/
protected abstract void executeStatementAndHandleResult(
PreparedStatement stmt) throws Exception;
// ---------- Utility methods for use in subclasses ----------
protected void setParameter(PreparedStatement stmt,
int idx,
int jdbcType,
Object value)
throws SQLException
{
if (factory.debug)
{
log.debug("Set parameter: idx=" + idx +
", jdbcType=" + getJDBCTypeName(jdbcType) +
", value=" +
((value == null) ? "NULL" : value));
}
if (value == null)
{
stmt.setNull(idx, jdbcType);
} else
{
stmt.setObject(idx, value, jdbcType);
}
}
protected int setForeignKey(PreparedStatement stmt,
int idx,
CMPFieldInfo fieldInfo,
Object value)
throws SQLException
{
JawsCMPField[] pkInfo = fieldInfo.getForeignKeyCMPFields();
Object pk = null;
if (value != null)
{
try
{
pk = ((EJBObject)value).getPrimaryKey();
} catch (RemoteException e)
{
throw new SQLException("Could not extract primary key from EJB
reference:"+e);
}
}
if (!((JawsEntity)pkInfo[0].getBeanContext()).getPrimaryKeyField().equals(""))
{
// Primitive key
int jdbcType = getJawsCMPFieldJDBCType(pkInfo[0]);
Object fieldValue = (value == null) ? null : pk;
setParameter(stmt, idx, jdbcType, fieldValue);
return idx+1;
} else
{
// Compound key
Field[] fields = (value == null) ? null : pk.getClass().getFields();
try
{
for (int i = 0; i < pkInfo.length; i++)
{
int jdbcType = getJawsCMPFieldJDBCType(pkInfo[i]);
Object fieldValue = (value == null) ? null : fields[i].get(pk);
setParameter(stmt, idx+i, jdbcType, fieldValue);
}
} catch (IllegalAccessException e)
{
throw new SQLException("Could not extract fields from primary key:"+e);
}
return idx+pkInfo.length;
}
}
protected final int getJDBCType(String name)
{
try
{
Integer constant = (Integer)Types.class.getField(name).get(null);
return constant.intValue();
} catch (Exception e)
{
// JF: Dubious - better to throw a meaningful exception
e.printStackTrace();
return Types.OTHER;
}
}
protected final String getJDBCTypeName(int jdbcType)
{
if (jdbcTypeNames == null)
{
setUpJDBCTypeNames();
}
return (String)jdbcTypeNames.get(new Integer(jdbcType));
}
protected final String getPkColumnList()
{
StringBuffer sb = new StringBuffer();
Iterator it = metaInfo.getPkFieldInfos();
while (it.hasNext())
{
PkFieldInfo pkFieldInfo = (PkFieldInfo)it.next();
sb.append(pkFieldInfo.getColumnName());
if (it.hasNext())
{
sb.append(",");
}
}
return sb.toString();
}
protected final String getPkColumnWhereList()
{
StringBuffer sb = new StringBuffer();
Iterator it = metaInfo.getPkFieldInfos();
while (it.hasNext())
{
PkFieldInfo pkFieldInfo = (PkFieldInfo)it.next();
sb.append(pkFieldInfo.getColumnName());
sb.append("=?");
if (it.hasNext())
{
sb.append(" AND ");
}
}
return sb.toString();
}
// MF: PERF!!!!!!!
protected Object[] getState(EntityEnterpriseContext ctx)
{
Object[] state = new Object[metaInfo.getNumberOfCMPFields()];
Iterator iter = metaInfo.getCMPFieldInfos();
int i = 0;
while (iter.hasNext())
{
CMPFieldInfo fieldInfo = (CMPFieldInfo)iter.next();
try
{
// JF: Should clone
state[i++] = getCMPFieldValue(ctx.getInstance(), fieldInfo);
} catch (Exception e)
{
return null;
}
}
return state;
}
protected Object getCMPFieldValue(Object instance, CMPFieldInfo fieldInfo)
throws IllegalAccessException
{
Field field = fieldInfo.getField();
return field.get(instance);
}
protected void setCMPFieldValue(Object instance,
CMPFieldInfo fieldInfo,
Object value)
throws IllegalAccessException
{
Field field = fieldInfo.getField();
field.set(instance, value);
}
protected Object getPkFieldValue(Object pk, PkFieldInfo pkFieldInfo)
throws IllegalAccessException
{
Field field = pkFieldInfo.getPkField();
// JF: Temp checks to narrow down bug
if (pk == null) log.debug("***** getPkFieldValue: PK is null *****");
if (field == null) log.debug("***** getPkFieldValue: Field is null *****");
return field.get(pk);
}
// This is now only used in setForeignKey
protected int getJawsCMPFieldJDBCType(JawsCMPField fieldInfo)
{
return getJDBCType(fieldInfo.getJdbcType());
}
// Private -------------------------------------------------------
/** Get a database connection */
private Connection getConnection() throws SQLException
{
DataSource ds = metaInfo.getDataSource();
if (ds != null)
{
return ds.getConnection();
} else
{
String url = metaInfo.getDbURL();
return DriverManager.getConnection(url,"sa","");
}
}
private final void setUpJDBCTypeNames()
{
jdbcTypeNames = new HashMap();
Field[] fields = Types.class.getFields();
int length = fields.length;
for (int i = 0; i < length; i++) {
Field f = fields[i];
String fieldName = f.getName();
try {
Object fieldValue = f.get(null);
jdbcTypeNames.put(fieldValue, fieldName);
} catch (IllegalAccessException e) {
// Should never happen
e.printStackTrace();
}
}
}
}
1.1
jboss/src/main/org/jboss/ejb/plugins/jaws/jdbc/JDBCCommandFactory.java
Index: JDBCCommandFactory.java
===================================================================
/*
* jBoss, the OpenSource EJB server
*
* Distributable under GPL license.
* See terms of license at gnu.org.
*/
package org.jboss.ejb.plugins.jaws.jdbc;
import java.lang.reflect.Method;
import javax.naming.Context;
import javax.naming.InitialContext;
import org.jboss.ejb.EntityContainer;
import org.jboss.ejb.plugins.jaws.MetaInfo;
import org.jboss.ejb.plugins.jaws.JPMCommandFactory;
import org.jboss.ejb.plugins.jaws.JPMInitCommand;
import org.jboss.ejb.plugins.jaws.JPMStartCommand;
import org.jboss.ejb.plugins.jaws.JPMStopCommand;
import org.jboss.ejb.plugins.jaws.JPMDestroyCommand;
import org.jboss.ejb.plugins.jaws.JPMFindEntityCommand;
import org.jboss.ejb.plugins.jaws.JPMFindEntitiesCommand;
import org.jboss.ejb.plugins.jaws.JPMCreateEntityCommand;
import org.jboss.ejb.plugins.jaws.JPMRemoveEntityCommand;
import org.jboss.ejb.plugins.jaws.JPMLoadEntityCommand;
import org.jboss.ejb.plugins.jaws.JPMStoreEntityCommand;
import org.jboss.ejb.plugins.jaws.JPMActivateEntityCommand;
import org.jboss.ejb.plugins.jaws.JPMPassivateEntityCommand;
import org.jboss.ejb.plugins.jaws.deployment.Finder;
import org.jboss.logging.Log;
/**
* JAWSPersistenceManager JDBCCommandFactory
*
* @author <a href="mailto:[EMAIL PROTECTED]">Justin Forder</a>
* @version $Revision: 1.1 $
*/
public class JDBCCommandFactory implements JPMCommandFactory
{
// Attributes ----------------------------------------------------
private EntityContainer container;
private Context javaCtx;
private MetaInfo metaInfo;
private Log log;
// These support singletons (within the scope of this factory)
private JDBCBeanExistsCommand beanExistsCommand;
private JPMFindEntitiesCommand findEntitiesCommand;
/**
* Gives compile-time control of tracing.
*/
public static boolean debug = true;
// Constructors --------------------------------------------------
public JDBCCommandFactory(EntityContainer container,
Log log)
throws Exception
{
this.container = container;
this.javaCtx = (Context)new InitialContext().lookup("java:comp/env");
this.metaInfo = new MetaInfo(container);
this.log = log;
}
// Public --------------------------------------------------------
public EntityContainer getContainer()
{
return container;
}
public Context getJavaCtx()
{
return javaCtx;
}
public MetaInfo getMetaInfo()
{
return metaInfo;
}
public Log getLog()
{
return log;
}
// Additional Command creation
/**
* Singleton: multiple callers get references to the
* same command instance.
*/
public JDBCBeanExistsCommand createBeanExistsCommand()
{
if (beanExistsCommand == null)
{
beanExistsCommand = new JDBCBeanExistsCommand(this);
}
return beanExistsCommand;
}
public JPMFindEntitiesCommand createFindAllCommand()
{
return new JDBCFindAllCommand(this);
}
public JPMFindEntitiesCommand createDefinedFinderCommand(Finder f)
{
return new JDBCDefinedFinderCommand(this, f);
}
public JPMFindEntitiesCommand createFindByCommand(Method finderMethod)
throws IllegalArgumentException
{
return new JDBCFindByCommand(this, finderMethod);
}
// JPMCommandFactory implementation ------------------------------
// lifecycle commands
public JPMInitCommand createInitCommand()
{
return new JDBCInitCommand(this);
}
public JPMStartCommand createStartCommand()
{
return new JDBCStartCommand(this);
}
public JPMStopCommand createStopCommand()
{
return new JDBCStopCommand(this);
}
public JPMDestroyCommand createDestroyCommand()
{
return new JDBCDestroyCommand(this);
}
// entity persistence-related commands
public JPMFindEntityCommand createFindEntityCommand()
{
return new JDBCFindEntityCommand(this);
}
/**
* Singleton: multiple callers get references to the
* same command instance.
*/
public JPMFindEntitiesCommand createFindEntitiesCommand()
{
if (findEntitiesCommand == null)
{
findEntitiesCommand = new JDBCFindEntitiesCommand(this);
}
return findEntitiesCommand;
}
public JPMCreateEntityCommand createCreateEntityCommand()
{
return new JDBCCreateEntityCommand(this);
}
public JPMRemoveEntityCommand createRemoveEntityCommand()
{
return new JDBCRemoveEntityCommand(this);
}
public JPMLoadEntityCommand createLoadEntityCommand()
{
return new JDBCLoadEntityCommand(this);
}
public JPMStoreEntityCommand createStoreEntityCommand()
{
return new JDBCStoreEntityCommand(this);
}
// entity activation and passivation commands
public JPMActivateEntityCommand createActivateEntityCommand()
{
return new JDBCActivateEntityCommand(this);
}
public JPMPassivateEntityCommand createPassivateEntityCommand()
{
return new JDBCPassivateEntityCommand(this);
}
}
1.1
jboss/src/main/org/jboss/ejb/plugins/jaws/jdbc/JDBCCreateEntityCommand.java
Index: JDBCCreateEntityCommand.java
===================================================================
/*
* jBoss, the OpenSource EJB server
*
* Distributable under GPL license.
* See terms of license at gnu.org.
*/
package org.jboss.ejb.plugins.jaws.jdbc;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Iterator;
import java.rmi.RemoteException;
import java.rmi.ServerException;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import javax.ejb.CreateException;
import javax.ejb.DuplicateKeyException;
import org.jboss.ejb.EntityContainer;
import org.jboss.ejb.EntityEnterpriseContext;
import org.jboss.ejb.plugins.jaws.JAWSPersistenceManager;
import org.jboss.ejb.plugins.jaws.JPMCreateEntityCommand;
import org.jboss.ejb.plugins.jaws.CMPFieldInfo;
import org.jboss.ejb.plugins.jaws.MetaInfo;
import org.jboss.ejb.plugins.jaws.PkFieldInfo;
import org.jboss.ejb.plugins.jaws.deployment.JawsCMPField;
/**
* JAWSPersistenceManager JDBCCreateEntityCommand
*
* @see <related>
* @author <a href="mailto:[EMAIL PROTECTED]">Rickard �berg</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Marc Fleury</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Joe Shevland</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Justin Forder</a>
* @version $Revision: 1.1 $
*/
public class JDBCCreateEntityCommand
extends JDBCUpdateCommand
implements JPMCreateEntityCommand
{
// Attributes ----------------------------------------------------
private JDBCBeanExistsCommand beanExistsCommand;
private EntityEnterpriseContext ctxArgument;
// Constructors --------------------------------------------------
public JDBCCreateEntityCommand(JDBCCommandFactory factory)
{
super(factory, "Create");
beanExistsCommand = factory.createBeanExistsCommand();
// Insert SQL
String sql = "INSERT INTO " + metaInfo.getTableName();
String fieldSql = "";
String valueSql = "";
Iterator it = metaInfo.getCMPFieldInfos();
boolean first = true;
while (it.hasNext())
{
CMPFieldInfo fieldInfo = (CMPFieldInfo)it.next();
if (fieldInfo.isEJBReference())
{
JawsCMPField[] pkFields = fieldInfo.getForeignKeyCMPFields();
for (int i = 0; i < pkFields.length; i++)
{
fieldSql += (first ? "" : ",") +
fieldInfo.getColumnName() + "_" +
pkFields[i].getColumnName();
valueSql += first ? "?" : ",?";
first = false;
}
} else
{
fieldSql += (first ? "" : ",") +
fieldInfo.getColumnName();
valueSql += first ? "?" : ",?";
first = false;
}
}
sql += " ("+fieldSql+") VALUES ("+valueSql+")";
setSQL(sql);
}
// JPMCreateEntityCommand implementation -------------------------
public Object execute(Method m,
Object[] args,
EntityEnterpriseContext ctx)
throws RemoteException, CreateException
{
// Save ctx for use in setParameters(), handleResult()
ctxArgument = ctx;
try
{
// Extract pk
Object id = null;
Iterator it = metaInfo.getPkFieldInfos();
if (metaInfo.hasCompositeKey())
{
try
{
id = metaInfo.getPrimaryKeyClass().newInstance();
} catch (InstantiationException e)
{
throw new ServerException("Could not create primary key",e);
}
while (it.hasNext())
{
PkFieldInfo pkFieldInfo = (PkFieldInfo)it.next();
Field from = pkFieldInfo.getCMPField();
Field to = pkFieldInfo.getPkField();
to.set(id, from.get(ctx.getInstance()));
}
} else
{
PkFieldInfo pkFieldInfo = (PkFieldInfo)it.next();
Field from = pkFieldInfo.getCMPField();
id = from.get(ctx.getInstance());
}
if (factory.debug)
{
log.debug("Create, id is "+id);
}
// Check duplicate
if (beanExistsCommand.execute(id))
{
throw new DuplicateKeyException("Entity with key "+id+" already exists");
}
// Insert in db
try
{
jdbcExecute();
} catch (Exception e)
{
log.exception(e);
throw new CreateException("Could not create entity:"+e);
}
return id;
} catch (IllegalAccessException e)
{
log.exception(e);
throw new CreateException("Could not create entity:"+e);
}
}
// JDBCUpdateCommand overrides -----------------------------------
protected void setParameters(PreparedStatement stmt) throws Exception
{
int idx = 1; // Parameter-index
Iterator iter = metaInfo.getCMPFieldInfos();
while (iter.hasNext())
{
CMPFieldInfo fieldInfo = (CMPFieldInfo)iter.next();
Object value = getCMPFieldValue(ctxArgument.getInstance(), fieldInfo);
if (fieldInfo.isEJBReference())
{
idx = setForeignKey(stmt, idx, fieldInfo, value);
} else
{
setParameter(stmt, idx++, fieldInfo.getJDBCType(), value);
}
}
}
protected void handleResult(int rowsAffected) throws Exception
{
// arguably should check one row went in!!!
// Store state to be able to do tuned updates
JAWSPersistenceManager.PersistenceContext pCtx =
new JAWSPersistenceManager.PersistenceContext();
// If read-only, set last read to now
if (metaInfo.isReadOnly()) pCtx.lastRead = System.currentTimeMillis();
// Save initial state for tuned updates
pCtx.state = getState(ctxArgument);
ctxArgument.setPersistenceContext(pCtx);
}
}
1.1
jboss/src/main/org/jboss/ejb/plugins/jaws/jdbc/JDBCDefinedFinderCommand.java
Index: JDBCDefinedFinderCommand.java
===================================================================
/*
* jBoss, the OpenSource EJB server
*
* Distributable under GPL license.
* See terms of license at gnu.org.
*/
package org.jboss.ejb.plugins.jaws.jdbc;
import java.util.ArrayList;
import java.util.StringTokenizer;
import java.sql.PreparedStatement;
import org.jboss.ejb.plugins.jaws.deployment.Finder;
/**
* JAWSPersistenceManager JDBCDefinedFinderCommand
*
* @see <related>
* @author <a href="mailto:[EMAIL PROTECTED]">Rickard �berg</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Marc Fleury</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Joe Shevland</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Justin Forder</a>
* @version $Revision: 1.1 $
*/
public class JDBCDefinedFinderCommand extends JDBCFinderCommand
{
// Attributes ----------------------------------------------------
private int[] parameterArray;
// Constructors --------------------------------------------------
public JDBCDefinedFinderCommand(JDBCCommandFactory factory, Finder f)
{
super(factory, f.getName());
// Replace placeholders with ?
String query = "";
StringTokenizer finderQuery = new StringTokenizer(f.getQuery(),"{}", true);
ArrayList parameters = new ArrayList();
while (finderQuery.hasMoreTokens())
{
String t = finderQuery.nextToken();
if (t.equals("{"))
{
query += "?";
String idx = finderQuery.nextToken(); // Remove number
parameters.add(new Integer(idx));
finderQuery.nextToken(); // Remove }
} else
query += t;
}
// Copy index numbers to parameterArray
parameterArray = new int[parameters.size()];
for (int i = 0; i < parameterArray.length; i++)
parameterArray[i] = ((Integer)parameters.get(i)).intValue();
// Construct SQL
String sql = "SELECT " + getPkColumnList() +
(f.getOrder().equals("") ? "" : ","+f.getOrder()) +
" FROM " + metaInfo.getTableName() + " WHERE " + query;
if (!f.getOrder().equals(""))
{
sql += " ORDER BY "+f.getOrder();
}
setSQL(sql);
}
// JDBCFinderCommand overrides ------------------------------------
protected void setParameters(PreparedStatement stmt) throws Exception
{
for (int i = 0; i < parameterArray.length; i++)
{
stmt.setObject(i+1, argsArgument[parameterArray[i]]);
}
}
}
1.1
jboss/src/main/org/jboss/ejb/plugins/jaws/jdbc/JDBCDestroyCommand.java
Index: JDBCDestroyCommand.java
===================================================================
/*
* jBoss, the OpenSource EJB server
*
* Distributable under GPL license.
* See terms of license at gnu.org.
*/
package org.jboss.ejb.plugins.jaws.jdbc;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import org.jboss.ejb.plugins.jaws.JPMDestroyCommand;
import org.jboss.ejb.plugins.jaws.MetaInfo;
/**
* JAWSPersistenceManager JDBCDestroyCommand
*
* @see <related>
* @author <a href="mailto:[EMAIL PROTECTED]">Rickard �berg</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Marc Fleury</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Joe Shevland</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Justin Forder</a>
* @version $Revision: 1.1 $
*/
public class JDBCDestroyCommand
extends JDBCUpdateCommand
implements JPMDestroyCommand
{
// Constructors --------------------------------------------------
public JDBCDestroyCommand(JDBCCommandFactory factory)
{
super(factory, "Destroy");
// Drop table SQL
String sql = "DROP TABLE " + metaInfo.getTableName();
setSQL(sql);
}
// JPMDestroyCommand implementation ------------------------------
public void execute()
{
if (metaInfo.getRemoveTable())
{
// Remove it!
try
{
jdbcExecute();
} catch (Exception e)
{
log.debug("Table "+metaInfo.getTableName()+" could not be removed");
}
}
}
// JDBCUpdateCommand overrides -----------------------------------
protected void handleResult(int rowsAffected) throws Exception
{
log.debug("Table "+metaInfo.getTableName()+" removed");
}
}
1.1
jboss/src/main/org/jboss/ejb/plugins/jaws/jdbc/JDBCFindAllCommand.java
Index: JDBCFindAllCommand.java
===================================================================
/*
* jBoss, the OpenSource EJB server
*
* Distributable under GPL license.
* See terms of license at gnu.org.
*/
package org.jboss.ejb.plugins.jaws.jdbc;
/**
* JAWSPersistenceManager JDBCFindAllCommand
*
* @see <related>
* @author <a href="mailto:[EMAIL PROTECTED]">Rickard �berg</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Marc Fleury</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Joe Shevland</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Justin Forder</a>
* @version $Revision: 1.1 $
*/
public class JDBCFindAllCommand extends JDBCFinderCommand
{
// Constructors --------------------------------------------------
public JDBCFindAllCommand(JDBCCommandFactory factory)
{
super(factory, "FindAll");
String sql = "SELECT " + getPkColumnList() + " FROM " +
metaInfo.getTableName();
setSQL(sql);
}
}
1.1
jboss/src/main/org/jboss/ejb/plugins/jaws/jdbc/JDBCFindByCommand.java
Index: JDBCFindByCommand.java
===================================================================
/*
* jBoss, the OpenSource EJB server
*
* Distributable under GPL license.
* See terms of license at gnu.org.
*/
package org.jboss.ejb.plugins.jaws.jdbc;
import java.lang.reflect.Method;
import java.sql.PreparedStatement;
import java.util.Iterator;
import org.jboss.ejb.plugins.jaws.deployment.Finder;
import org.jboss.ejb.plugins.jaws.CMPFieldInfo;
import org.jboss.ejb.plugins.jaws.deployment.JawsCMPField;
/**
* JAWSPersistenceManager JDBCFindByCommand
*
* @see <related>
* @author <a href="mailto:[EMAIL PROTECTED]">Rickard �berg</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Marc Fleury</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Joe Shevland</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Justin Forder</a>
* @version $Revision: 1.1 $
*/
public class JDBCFindByCommand extends JDBCFinderCommand
{
// Attributes ----------------------------------------------------
// The meta-info for the field we are finding by
private CMPFieldInfo fieldInfo;
// The arguments for this finder invocation
private Object[] argsArgument;
// Constructors --------------------------------------------------
public JDBCFindByCommand(JDBCCommandFactory factory, Method finderMethod)
throws IllegalArgumentException
{
super(factory, finderMethod.getName());
String cmpFieldName = finderMethod.getName().substring(6).toLowerCase();
System.out.println("Finder:"+cmpFieldName);
// Find the meta-info for the field we want to find by
fieldInfo = null;
Iterator iter = metaInfo.getCMPFieldInfos();
while (fieldInfo == null && iter.hasNext())
{
CMPFieldInfo fi = (CMPFieldInfo)iter.next();
if (cmpFieldName.equals(fi.getName().toLowerCase()))
{
fieldInfo = fi;
}
}
if (fieldInfo == null)
{
throw new IllegalArgumentException(
"No finder for this method: " + finderMethod.getName());
}
// Compute SQL
String sql = "SELECT " + getPkColumnList() +
" FROM "+metaInfo.getTableName()+ " WHERE ";
if (fieldInfo.isEJBReference())
{
JawsCMPField[] cmpFields = fieldInfo.getForeignKeyCMPFields();
for (int j = 0; j < cmpFields.length; j++)
{
sql += (j==0?"":" AND ") +
fieldInfo.getColumnName() + "_" + cmpFields[j].getColumnName() + "=?";
}
} else
{
sql += fieldInfo.getColumnName() + "=?";
}
setSQL(sql);
}
// JDBCFinderCommand overrides -----------------------------------
protected void setParameters(PreparedStatement stmt) throws Exception
{
if (fieldInfo != null)
{
if (fieldInfo.isEJBReference())
{
setForeignKey(stmt, 1, fieldInfo, argsArgument[0]);
} else
{
setParameter(stmt, 1, fieldInfo.getJDBCType(), argsArgument[0]);
}
}
}
}
1.1
jboss/src/main/org/jboss/ejb/plugins/jaws/jdbc/JDBCFindEntitiesCommand.java
Index: JDBCFindEntitiesCommand.java
===================================================================
/*
* jBoss, the OpenSource EJB server
*
* Distributable under GPL license.
* See terms of license at gnu.org.
*/
package org.jboss.ejb.plugins.jaws.jdbc;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.rmi.RemoteException;
import javax.ejb.FinderException;
import org.jboss.ejb.EntityEnterpriseContext;
import org.jboss.ejb.plugins.jaws.JPMFindEntitiesCommand;
import org.jboss.ejb.plugins.jaws.deployment.Finder;
/**
* Keeps a map from finder name to specific finder command, and
* delegates to the relevant specific finder command.
* The map is initially populated with the defined finders.
* It is lazily populated with commands for the magic finders (findAll and
* findByXXX) as and when they are called.
*
* @see <related>
* @author <a href="mailto:[EMAIL PROTECTED]">Rickard �berg</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Marc Fleury</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Joe Shevland</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Justin Forder</a>
* @version $Revision: 1.1 $
*/
public class JDBCFindEntitiesCommand implements JPMFindEntitiesCommand
{
// Attributes ----------------------------------------------------
private JDBCCommandFactory factory;
private HashMap knownFinderCommands = new HashMap();
// Constructors --------------------------------------------------
public JDBCFindEntitiesCommand(JDBCCommandFactory factory)
{
this.factory = factory;
// Make commands for the defined finders
Iterator definedFinders = factory.getMetaInfo().getFinders();
while(definedFinders.hasNext())
{
Finder f = (Finder)definedFinders.next();
if ( !knownFinderCommands.containsKey(f.getName()) )
{
JPMFindEntitiesCommand finderCommand =
factory.createDefinedFinderCommand(f);
knownFinderCommands.put(f.getName(), finderCommand);
}
}
}
// JPMFindEntitiesCommand implementation -------------------------
public Collection execute(Method finderMethod,
Object[] args,
EntityEnterpriseContext ctx)
throws RemoteException, FinderException
{
String finderName = finderMethod.getName();
// Do we know a finder command for this method name?
JPMFindEntitiesCommand finderCommand =
(JPMFindEntitiesCommand)knownFinderCommands.get(finderName);
// If we didn't get a finder command, see if we can make one
if (finderCommand == null)
{
try
{
if (finderName.equals("findAll"))
{
finderCommand = factory.createFindAllCommand();
} else if (finderName.startsWith("findBy"))
{
finderCommand = factory.createFindByCommand(finderMethod);
}
// Remember the new finder command
knownFinderCommands.put(finderName, finderCommand);
} catch (IllegalArgumentException e)
{
factory.getLog().warning(e.getMessage());
}
}
// If we now have a finder command, delegate to it,
// otherwise return an empty collection.
return (finderCommand != null) ?
finderCommand.execute(finderMethod, args, ctx) : new ArrayList();
}
}
1.1
jboss/src/main/org/jboss/ejb/plugins/jaws/jdbc/JDBCFindEntityCommand.java
Index: JDBCFindEntityCommand.java
===================================================================
/*
* jBoss, the OpenSource EJB server
*
* Distributable under GPL license.
* See terms of license at gnu.org.
*/
package org.jboss.ejb.plugins.jaws.jdbc;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.ArrayList;
import java.rmi.RemoteException;
import javax.ejb.FinderException;
import org.jboss.ejb.EntityEnterpriseContext;
import org.jboss.ejb.plugins.jaws.JPMFindEntityCommand;
import org.jboss.ejb.plugins.jaws.JPMFindEntitiesCommand;
/**
* JAWSPersistenceManager JDBCFindEntityCommand
*
* @see <related>
* @author <a href="mailto:[EMAIL PROTECTED]">Rickard �berg</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Marc Fleury</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Joe Shevland</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Justin Forder</a>
* @version $Revision: 1.1 $
*/
public class JDBCFindEntityCommand implements JPMFindEntityCommand
{
// Attributes ----------------------------------------------------
JDBCBeanExistsCommand beanExistsCommand;
JPMFindEntitiesCommand findEntitiesCommand;
// Constructors --------------------------------------------------
public JDBCFindEntityCommand(JDBCCommandFactory factory)
{
beanExistsCommand = factory.createBeanExistsCommand();
findEntitiesCommand = factory.createFindEntitiesCommand();
}
// JPMFindEntityCommand implementation ---------------------------
public Object execute(Method finderMethod,
Object[] args,
EntityEnterpriseContext ctx)
throws RemoteException, FinderException
{
if (finderMethod.getName().equals("findByPrimaryKey"))
{
return findByPrimaryKey(args[0]);
}
else
{
ArrayList result =
(ArrayList)findEntitiesCommand.execute(finderMethod, args, ctx);
if (result.size() == 0)
{
throw new FinderException("No such entity!");
} else
{
return result.get(0);
}
}
}
// Protected -----------------------------------------------------
protected Object findByPrimaryKey(Object id) throws FinderException
{
if (beanExistsCommand.execute(id))
{
return id;
} else
{
throw new FinderException("Object with primary key " + id +
" not found in storage");
}
}
}
1.1
jboss/src/main/org/jboss/ejb/plugins/jaws/jdbc/JDBCFinderCommand.java
Index: JDBCFinderCommand.java
===================================================================
/*
* jBoss, the OpenSource EJB server
*
* Distributable under GPL license.
* See terms of license at gnu.org.
*/
package org.jboss.ejb.plugins.jaws.jdbc;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.rmi.RemoteException;
import java.rmi.ServerException;
import java.sql.ResultSet;
import javax.ejb.FinderException;
import org.jboss.ejb.EntityEnterpriseContext;
import org.jboss.ejb.plugins.jaws.PkFieldInfo;
import org.jboss.ejb.plugins.jaws.JPMFindEntitiesCommand;
/**
* Abstract superclass of finder commands that return collections.
* Provides the handleResult() implementation that these all need.
* @see <related>
* @author <a href="mailto:[EMAIL PROTECTED]">Rickard �berg</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Marc Fleury</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Joe Shevland</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Justin Forder</a>
* @version $Revision: 1.1 $
*/
public abstract class JDBCFinderCommand
extends JDBCQueryCommand
implements JPMFindEntitiesCommand
{
// Attributes ----------------------------------------------------
protected Object[] argsArgument;
protected ArrayList result;
// Constructors --------------------------------------------------
public JDBCFinderCommand(JDBCCommandFactory factory, String name)
{
super(factory, name);
}
// JPMFindEntitiesCommand implementation -------------------------
public Collection execute(Method finderMethod,
Object[] args,
EntityEnterpriseContext ctx)
throws RemoteException, FinderException
{
argsArgument = args;
try
{
jdbcExecute();
} catch (Exception e)
{
log.exception(e);
throw new FinderException("Find failed");
}
return result;
}
// JDBCQueryCommand overrides ------------------------------------
protected void handleResult(ResultSet rs) throws Exception
{
result = new ArrayList();
int i = 1; // parameter index
if (metaInfo.hasCompositeKey())
{
// Compound key
try
{
while (rs.next())
{
Object pk = metaInfo.getPrimaryKeyClass().newInstance();
Iterator it = metaInfo.getPkFieldInfos();
while (it.hasNext())
{
PkFieldInfo pkFieldInfo = (PkFieldInfo)it.next();
Field pkField = pkFieldInfo.getPkField();
pkField.set(pk, rs.getObject(i++));
}
result.add(pk);
}
} catch (Exception e)
{
throw new ServerException("Finder failed",e);
}
} else
{
// Primitive key
while (rs.next())
{
result.add(rs.getObject(i));
}
}
}
}
1.1
jboss/src/main/org/jboss/ejb/plugins/jaws/jdbc/JDBCInitCommand.java
Index: JDBCInitCommand.java
===================================================================
/*
* jBoss, the OpenSource EJB server
*
* Distributable under GPL license.
* See terms of license at gnu.org.
*/
package org.jboss.ejb.plugins.jaws.jdbc;
import java.util.Iterator;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import org.jboss.ejb.plugins.jaws.JPMInitCommand;
import org.jboss.ejb.plugins.jaws.CMPFieldInfo;
import org.jboss.ejb.plugins.jaws.MetaInfo;
import org.jboss.ejb.plugins.jaws.deployment.JawsCMPField;
/**
* JAWSPersistenceManager JDBCInitCommand
*
* @see <related>
* @author <a href="mailto:[EMAIL PROTECTED]">Rickard �berg</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Marc Fleury</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Joe Shevland</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Justin Forder</a>
* @version $Revision: 1.1 $
*/
public class JDBCInitCommand
extends JDBCUpdateCommand
implements JPMInitCommand
{
// Constructors --------------------------------------------------
public JDBCInitCommand(JDBCCommandFactory factory)
{
super(factory, "Init");
// Create table SQL
String sql = "CREATE TABLE " + metaInfo.getTableName() + " (";
Iterator it = metaInfo.getCMPFieldInfos();
boolean first = true;
while (it.hasNext())
{
CMPFieldInfo fieldInfo = (CMPFieldInfo)it.next();
if (fieldInfo.isEJBReference())
{
JawsCMPField[] pkFields = fieldInfo.getForeignKeyCMPFields();
for (int i = 0; i < pkFields.length; i++)
{
sql += (first ? "" : ",") +
fieldInfo.getColumnName() + "_" +
pkFields[i].getColumnName() + " " +
pkFields[i].getSqlType();
first = false;
}
} else
{
sql += (first ? "" : ",") +
fieldInfo.getColumnName() + " " +
fieldInfo.getSQLType();
first = false;
}
}
sql += ")";
setSQL(sql);
}
// JPMInitCommand implementation ---------------------------------
public void execute() throws Exception
{
// Create table if necessary
if (metaInfo.getCreateTable())
{
// Try to create it
try
{
jdbcExecute();
} catch (Exception e)
{
log.debug("Table " + metaInfo.getTableName() + " exists");
}
}
}
// JDBCUpdateCommand overrides -----------------------------------
protected void handleResult(int rowsAffected) throws Exception
{
log.debug("Table " + metaInfo.getTableName() + " created");
}
}
1.1
jboss/src/main/org/jboss/ejb/plugins/jaws/jdbc/JDBCLoadEntityCommand.java
Index: JDBCLoadEntityCommand.java
===================================================================
/*
* jBoss, the OpenSource EJB server
*
* Distributable under GPL license.
* See terms of license at gnu.org.
*/
package org.jboss.ejb.plugins.jaws.jdbc;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Iterator;
import java.rmi.NoSuchObjectException;
import java.rmi.RemoteException;
import java.rmi.ServerException;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import org.jboss.ejb.EntityEnterpriseContext;
import org.jboss.ejb.plugins.jaws.JAWSPersistenceManager;
import org.jboss.ejb.plugins.jaws.JPMLoadEntityCommand;
import org.jboss.ejb.plugins.jaws.CMPFieldInfo;
import org.jboss.ejb.plugins.jaws.PkFieldInfo;
import org.jboss.ejb.plugins.jaws.deployment.JawsEntity;
import org.jboss.ejb.plugins.jaws.deployment.JawsCMPField;
/**
* JAWSPersistenceManager JDBCLoadEntityCommand
*
* @see <related>
* @author <a href="mailto:[EMAIL PROTECTED]">Rickard �berg</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Marc Fleury</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Joe Shevland</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Justin Forder</a>
* @version $Revision: 1.1 $
*/
public class JDBCLoadEntityCommand
extends JDBCQueryCommand
implements JPMLoadEntityCommand
{
// Attributes ----------------------------------------------------
private EntityEnterpriseContext ctxArgument;
// Constructors --------------------------------------------------
public JDBCLoadEntityCommand(JDBCCommandFactory factory)
{
super(factory, "Load");
// Select SQL
String sql = "SELECT ";
Iterator it = metaInfo.getCMPFieldInfos();
boolean first = true;
while (it.hasNext())
{
CMPFieldInfo fieldInfo = (CMPFieldInfo)it.next();
if (fieldInfo.isEJBReference())
{
JawsCMPField[] pkFields = fieldInfo.getForeignKeyCMPFields();
for (int i = 0; i < pkFields.length; i++)
{
sql += (first ? "" : ",") +
fieldInfo.getColumnName() + "_" +
pkFields[i].getColumnName();
first = false;
}
} else
{
sql += (first ? "" : ",") +
fieldInfo.getColumnName();
first = false;
}
}
sql += " FROM " + metaInfo.getTableName() +
" WHERE " + getPkColumnWhereList();
setSQL(sql);
}
// JPMLoadEntityCommand implementation ---------------------------
public void execute(EntityEnterpriseContext ctx)
throws RemoteException
{
// Save the argument for use by setParameters() and handleResult()
ctxArgument = ctx;
if ( !metaInfo.isReadOnly() || isTimedOut() )
{
try
{
jdbcExecute();
} catch (Exception e)
{
throw new ServerException("Load failed", e);
}
}
}
// JDBCQueryCommand overrides ------------------------------------
protected void setParameters(PreparedStatement stmt) throws Exception
{
// Primary key in WHERE-clause
Iterator it = metaInfo.getPkFieldInfos();
int i = 1; // parameter index
if (metaInfo.hasCompositeKey())
{
// Compound key
while (it.hasNext())
{
PkFieldInfo pkFieldInfo = (PkFieldInfo)it.next();
int jdbcType = pkFieldInfo.getJDBCType();
Object value = getPkFieldValue(ctxArgument.getId(), pkFieldInfo);
setParameter(stmt, i++, jdbcType, value);
}
} else
{
// Primitive key
PkFieldInfo pkFieldInfo = (PkFieldInfo)it.next();
int jdbcType = pkFieldInfo.getJDBCType();
Object value = ctxArgument.getId();
setParameter(stmt, i, jdbcType, value);
}
}
protected void handleResult(ResultSet rs) throws Exception
{
if (!rs.next())
throw new NoSuchObjectException("Entity "+ctxArgument.getId()+" not found");
// Set values
int idx = 1;
Iterator iter = metaInfo.getCMPFieldInfos();
while (iter.hasNext())
{
CMPFieldInfo fieldInfo = (CMPFieldInfo)iter.next();
if (fieldInfo.isEJBReference())
{
// Create pk
JawsCMPField[] pkFields = fieldInfo.getForeignKeyCMPFields();
JawsEntity referencedEntity = (JawsEntity)pkFields[0].getBeanContext();
Object pk;
if (referencedEntity.getPrimaryKeyField().equals(""))
{
// Compound key
pk =
factory.getContainer().getClassLoader().loadClass(referencedEntity.getPrimaryKeyClass()).newInstance();
Field[] fields = pk.getClass().getFields();
for(int j = 0; j < fields.length; j++)
{
Object val = rs.getObject(idx++);
fields[j].set(pk, val);
if (factory.debug)
{
log.debug("Referenced pk field:" + val);
}
}
} else
{
// Primitive key
pk = rs.getObject(idx++);
if (factory.debug)
{
log.debug("Referenced pk:" + pk);
}
}
// Find referenced entity
try
{
Object home = factory.getJavaCtx().lookup(fieldInfo.getSQLType());
Method[] homeMethods = home.getClass().getMethods();
Method finder = null;
// We have to locate fBPK iteratively since we don't
// really know the pk-class
for (int j = 0; j < homeMethods.length; j++)
{
if (homeMethods[j].getName().equals("findByPrimaryKey"))
{
finder = homeMethods[j];
break;
}
}
if (finder == null)
{
throw new NoSuchMethodException(
"FindByPrimaryKey method not found in home interface");
}
log.debug("PK=" + pk);
Object ref = finder.invoke(home, new Object[] { pk });
// Set found entity
setCMPFieldValue(ctxArgument.getInstance(), fieldInfo, ref);
} catch (Exception e)
{
throw new ServerException("Could not restore reference", e);
}
} else
{
// Load primitive
// TODO: this probably needs to be fixed for BLOB's etc.
setCMPFieldValue(ctxArgument.getInstance(), fieldInfo,
rs.getObject(idx++));
}
}
// Store state to be able to do tuned updates
JAWSPersistenceManager.PersistenceContext pCtx =
(JAWSPersistenceManager.PersistenceContext)ctxArgument.getPersistenceContext();
if (metaInfo.isReadOnly()) pCtx.lastRead = System.currentTimeMillis();
pCtx.state = getState(ctxArgument);
}
// Protected -----------------------------------------------------
protected boolean isTimedOut()
{
JAWSPersistenceManager.PersistenceContext pCtx =
(JAWSPersistenceManager.PersistenceContext)ctxArgument.getPersistenceContext();
return (System.currentTimeMillis() - pCtx.lastRead) >
metaInfo.getReadOnlyTimeOut();
}
}
1.1
jboss/src/main/org/jboss/ejb/plugins/jaws/jdbc/JDBCPassivateEntityCommand.java
Index: JDBCPassivateEntityCommand.java
===================================================================
/*
* jBoss, the OpenSource EJB server
*
* Distributable under GPL license.
* See terms of license at gnu.org.
*/
package org.jboss.ejb.plugins.jaws.jdbc;
import java.rmi.RemoteException;
import org.jboss.ejb.EntityEnterpriseContext;
import org.jboss.ejb.plugins.jaws.JPMPassivateEntityCommand;
/**
* JAWSPersistenceManager JDBCPassivateEntityCommand
*
* @see <related>
* @author <a href="mailto:[EMAIL PROTECTED]">Rickard �berg</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Justin Forder</a>
* @version $Revision: 1.1 $
*/
public class JDBCPassivateEntityCommand implements JPMPassivateEntityCommand
{
// Constructors --------------------------------------------------
public JDBCPassivateEntityCommand(JDBCCommandFactory factory)
{
}
// JPMPassivateEntityCommand implementation ----------------------
public void execute(EntityEnterpriseContext ctx) throws RemoteException
{
// There is nothing to do here.
}
}
1.1
jboss/src/main/org/jboss/ejb/plugins/jaws/jdbc/JDBCQueryCommand.java
Index: JDBCQueryCommand.java
===================================================================
/*
* jBoss, the OpenSource EJB server
*
* Distributable under GPL license.
* See terms of license at gnu.org.
*/
package org.jboss.ejb.plugins.jaws.jdbc;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* Abstract superclass for all JAWS Commands that issue JDBC queries
* directly.
* Provides a Template Method implementation for
* <code>executeStatementAndHandleResult</code>.
* @author <a href="mailto:[EMAIL PROTECTED]">Justin Forder</a>
* @version $Revision: 1.1 $
*/
public abstract class JDBCQueryCommand extends JDBCCommand
{
// Constructors --------------------------------------------------
/**
* Pass the arguments on to the superclass constructor.
*/
protected JDBCQueryCommand(JDBCCommandFactory factory, String name)
{
super(factory, name);
}
// Protected -----------------------------------------------------
/**
* Template Method that executes the PreparedStatement and calls
* <code>handleResult</code> on the resulting ResultSet.
*/
protected void executeStatementAndHandleResult(PreparedStatement stmt)
throws Exception
{
ResultSet rs = null;
try
{
rs = stmt.executeQuery();
handleResult(rs);
} finally
{
if (rs != null)
{
try
{
rs.close();
} catch (SQLException e)
{
e.printStackTrace();
}
}
}
}
/**
* Handle the result of successful execution of the query.
*/
protected abstract void handleResult(ResultSet rs) throws Exception;
}
1.1
jboss/src/main/org/jboss/ejb/plugins/jaws/jdbc/JDBCRemoveEntityCommand.java
Index: JDBCRemoveEntityCommand.java
===================================================================
/*
* jBoss, the OpenSource EJB server
*
* Distributable under GPL license.
* See terms of license at gnu.org.
*/
package org.jboss.ejb.plugins.jaws.jdbc;
import java.util.Iterator;
import java.rmi.RemoteException;
import java.sql.PreparedStatement;
import javax.ejb.RemoveException;
import org.jboss.ejb.EntityEnterpriseContext;
import org.jboss.ejb.plugins.jaws.JPMRemoveEntityCommand;
import org.jboss.ejb.plugins.jaws.PkFieldInfo;
/**
* JAWSPersistenceManager JDBCRemoveEntityCommand
*
* @see <related>
* @author <a href="mailto:[EMAIL PROTECTED]">Rickard �berg</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Marc Fleury</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Joe Shevland</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Justin Forder</a>
* @version $Revision: 1.1 $
*/
public class JDBCRemoveEntityCommand
extends JDBCUpdateCommand
implements JPMRemoveEntityCommand
{
// Attributes ----------------------------------------------------
private EntityEnterpriseContext ctxArgument;
// Static --------------------------------------------------------
// Constructors --------------------------------------------------
public JDBCRemoveEntityCommand(JDBCCommandFactory factory)
{
super(factory, "Remove");
// Remove SQL
String sql = "DELETE FROM " + metaInfo.getTableName() +
" WHERE "+getPkColumnWhereList();
setSQL(sql);
}
// JPMRemoveEntityCommand implementation -------------------------
public void execute(EntityEnterpriseContext ctx)
throws RemoteException, RemoveException
{
ctxArgument = ctx;
try
{
// Remove from DB
jdbcExecute();
} catch (Exception e)
{
throw new RemoveException("Could not remove "+ctx.getId());
}
}
// JDBCUpdateCommand overrides -----------------------------------
protected void setParameters(PreparedStatement stmt) throws Exception
{
Iterator it = metaInfo.getPkFieldInfos();
int i = 1; // parameter index
// Primary key in WHERE-clause
if (metaInfo.hasCompositeKey())
{
// Compound key
while (it.hasNext())
{
PkFieldInfo pkFieldInfo = (PkFieldInfo)it.next();
int jdbcType = pkFieldInfo.getJDBCType();
Object value = getPkFieldValue(ctxArgument.getId(), pkFieldInfo);
setParameter(stmt, i++, jdbcType, value);
}
} else
{
// Primitive key
PkFieldInfo pkFieldInfo = (PkFieldInfo)it.next();
int jdbcType = pkFieldInfo.getJDBCType();
Object value = ctxArgument.getId();
setParameter(stmt, i, jdbcType, value);
}
}
protected void handleResult(int rowsAffected) throws Exception
{
if (rowsAffected == 0)
{
throw new RemoveException("Could not remove entity");
}
}
}
1.1
jboss/src/main/org/jboss/ejb/plugins/jaws/jdbc/JDBCStartCommand.java
Index: JDBCStartCommand.java
===================================================================
/*
* jBoss, the OpenSource EJB server
*
* Distributable under GPL license.
* See terms of license at gnu.org.
*/
package org.jboss.ejb.plugins.jaws.jdbc;
import org.jboss.ejb.plugins.jaws.JPMStartCommand;
/**
* JAWSPersistenceManager JDBCStartCommand
*
* @see <related>
* @author <a href="mailto:[EMAIL PROTECTED]">Rickard �berg</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Justin Forder</a>
* @version $Revision: 1.1 $
*/
public class JDBCStartCommand implements JPMStartCommand
{
// Constructors --------------------------------------------------
public JDBCStartCommand(JDBCCommandFactory factory)
{
}
// JPMStartCommand implementation --------------------------------
public void execute() throws Exception
{
}
}
1.1
jboss/src/main/org/jboss/ejb/plugins/jaws/jdbc/JDBCStopCommand.java
Index: JDBCStopCommand.java
===================================================================
/*
* jBoss, the OpenSource EJB server
*
* Distributable under GPL license.
* See terms of license at gnu.org.
*/
package org.jboss.ejb.plugins.jaws.jdbc;
import org.jboss.ejb.plugins.jaws.JPMStopCommand;
/**
* JAWSPersistenceManager JDBCStopCommand
*
* @see <related>
* @author <a href="mailto:[EMAIL PROTECTED]">Rickard �berg</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Justin Forder</a>
* @version $Revision: 1.1 $
*/
public class JDBCStopCommand implements JPMStopCommand
{
// Constructors --------------------------------------------------
public JDBCStopCommand(JDBCCommandFactory factory)
{
}
// JPMStopCommand implementation ---------------------------------
public void execute()
{
}
}
1.1
jboss/src/main/org/jboss/ejb/plugins/jaws/jdbc/JDBCStoreEntityCommand.java
Index: JDBCStoreEntityCommand.java
===================================================================
/*
* jBoss, the OpenSource EJB server
*
* Distributable under GPL license.
* See terms of license at gnu.org.
*/
package org.jboss.ejb.plugins.jaws.jdbc;
import java.lang.reflect.Field;
import java.util.Iterator;
import java.rmi.RemoteException;
import java.rmi.ServerException;
import java.sql.PreparedStatement;
import org.jboss.ejb.EntityEnterpriseContext;
import org.jboss.ejb.plugins.jaws.JAWSPersistenceManager;
import org.jboss.ejb.plugins.jaws.JPMStoreEntityCommand;
import org.jboss.ejb.plugins.jaws.CMPFieldInfo;
import org.jboss.ejb.plugins.jaws.PkFieldInfo;
import org.jboss.ejb.plugins.jaws.deployment.JawsCMPField;
/**
* JAWSPersistenceManager JDBCStoreEntityCommand
*
* @see <related>
* @author <a href="mailto:[EMAIL PROTECTED]">Rickard �berg</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Marc Fleury</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Joe Shevland</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Justin Forder</a>
* @version $Revision: 1.1 $
*/
public class JDBCStoreEntityCommand
extends JDBCUpdateCommand
implements JPMStoreEntityCommand
{
// Attributes ----------------------------------------------------
private EntityEnterpriseContext ctxArgument;
private boolean tuned;
private Object[] currentState;
private boolean[] dirtyField; // only used for tuned updates
// Constructors --------------------------------------------------
public JDBCStoreEntityCommand(JDBCCommandFactory factory)
{
super(factory, "Store");
tuned = metaInfo.hasTunedUpdates();
// If we don't have tuned updates, create static SQL
if (!tuned)
{
setSQL(makeSQL());
}
}
// JPMStoreEntityCommand implementation ---------------------------
/**
* if the readOnly flag is specified in the xml file this won't store.
* if not a tuned or untuned update is issued.
*/
public void execute(EntityEnterpriseContext ctx)
throws RemoteException
{
// Check for read-only
// JF: Shouldn't this throw an exception?
if (metaInfo.isReadOnly())
{
return;
}
ctxArgument = ctx;
currentState = getState(ctx);
boolean dirty = false;
// For tuned updates, need to see which fields have changed
if (tuned)
{
dirtyField = new boolean[currentState.length];
Object[] oldState =
((JAWSPersistenceManager.PersistenceContext)ctx.getPersistenceContext()).state;
for (int i = 0; i < currentState.length; i++)
{
dirtyField[i] = changed(currentState[i], oldState[i]);
dirty |= dirtyField[i];
}
}
if (!tuned || dirty)
{
try
{
// Update db
jdbcExecute();
} catch (Exception e)
{
throw new ServerException("Store failed", e);
}
}
}
// JDBCUpdateCommand overrides -----------------------------------
/**
* Returns dynamically-generated SQL if this entity
* has tuned updates, otherwise static SQL.
*/
protected String getSQL() throws Exception
{
return tuned ? makeSQL() : super.getSQL();
}
protected void setParameters(PreparedStatement stmt) throws Exception
{
int idx = 1;
Iterator iter = metaInfo.getCMPFieldInfos();
int i = 0;
while (iter.hasNext())
{
CMPFieldInfo fieldInfo = (CMPFieldInfo)iter.next();
if (!tuned || dirtyField[i])
{
if (fieldInfo.isEJBReference())
{
idx = setForeignKey(stmt, idx, fieldInfo, currentState[i]);
} else
{
setParameter(stmt, idx++, fieldInfo.getJDBCType(), currentState[i]);
}
}
i++;
}
// Primary key in WHERE-clause
Iterator it = metaInfo.getPkFieldInfos();
while (it.hasNext())
{
PkFieldInfo pkFieldInfo = (PkFieldInfo)it.next();
int jdbcType = pkFieldInfo.getJDBCType();
Field field = pkFieldInfo.getCMPField();
Object value = field.get(ctxArgument.getInstance());
// SA had introduced the change below, but it fails
// for non-composite primary keys.
// Object value = getPkFieldValue(ctxArgument.getId(), pkFieldInfo);
setParameter(stmt, idx++, jdbcType, value);
}
}
protected void handleResult(int rowsAffected) throws Exception
{
if (tuned)
{
// Save current state for tuned updates
JAWSPersistenceManager.PersistenceContext pCtx =
(JAWSPersistenceManager.PersistenceContext)ctxArgument.getPersistenceContext();
pCtx.state = currentState;
}
}
// Protected -----------------------------------------------------
protected final boolean changed(Object current, Object old)
{
return (current == null) ? (old != null) : current.equals(old);
}
/**
* Used to create static SQL (tuned = false) or dynamic SQL (tuned = true).
*/
protected String makeSQL()
{
String sql = "UPDATE "+metaInfo.getTableName()+" SET ";
Iterator iter = metaInfo.getCMPFieldInfos();
int i = 0;
boolean first = true;
while (iter.hasNext())
{
CMPFieldInfo fieldInfo = (CMPFieldInfo)iter.next();
if (!tuned || dirtyField[i++])
{
if (fieldInfo.isEJBReference())
{
JawsCMPField[] pkFields = fieldInfo.getForeignKeyCMPFields();
for (int j = 0; j < pkFields.length; j++)
{
sql += (first?"":",") +
fieldInfo.getColumnName()+"_"+pkFields[j].getColumnName()+
"=?";
first = false;
}
} else
{
sql += (first?"":",") +
fieldInfo.getColumnName() + "=?";
first = false;
}
}
}
sql += " WHERE "+getPkColumnWhereList();
return sql;
}
}
1.1
jboss/src/main/org/jboss/ejb/plugins/jaws/jdbc/JDBCUpdateCommand.java
Index: JDBCUpdateCommand.java
===================================================================
/*
* jBoss, the OpenSource EJB server
*
* Distributable under GPL license.
* See terms of license at gnu.org.
*/
package org.jboss.ejb.plugins.jaws.jdbc;
import java.sql.PreparedStatement;
import java.sql.SQLException;
/**
* Abstract superclass for all JAWS Commands that issue JDBC updates
* directly.
* Provides a Template Method implementation for
* <code>executeStatementAndHandleResult</code>.
* @author <a href="mailto:[EMAIL PROTECTED]">Justin Forder</a>
* @version $Revision: 1.1 $
*/
public abstract class JDBCUpdateCommand extends JDBCCommand
{
// Constructors --------------------------------------------------
/**
* Pass the arguments on to the superclass constructor.
*/
protected JDBCUpdateCommand(JDBCCommandFactory factory, String name)
{
super(factory, name);
}
// Protected -----------------------------------------------------
/**
* Template Method that executes the PreparedStatement and calls
* <code>handleResult</code> on the integer result.
*/
protected void executeStatementAndHandleResult(PreparedStatement stmt)
throws Exception
{
int rowsAffected = stmt.executeUpdate();
if (factory.debug)
{
log.debug("Rows affected = " + rowsAffected);
}
handleResult(rowsAffected);
}
/**
* Handle the result of successful execution of the update.
*/
protected abstract void handleResult(int rowsAffected) throws Exception;
}