| Method from org.jboss.ejb.plugins.jaws.jdbc.JDBCCommand Detail: |
abstract protected Object executeStatementAndHandleResult(PreparedStatement stmt,
Object argOrArgs) throws Exception
Executes the PreparedStatement and handles result of successful execution.
This is implemented in subclasses for queries and updates. |
protected Object getCMPFieldValue(Object instance,
CMPFieldMetaData fieldMetaData) throws IllegalAccessException {
return fieldMetaData.getValue(instance);
}
|
protected Connection getConnection() throws SQLException {
DataSource ds = jawsEntity.getDataSource();
if (ds != null)
{
return ds.getConnection();
} else throw new RuntimeException("Unable to locate data source!");
}
Get a database connection |
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
log.debug("Exception",e);
return Types.OTHER;
}
}
Gets the integer JDBC type code corresponding to the given name. |
protected final String getJDBCTypeName(int jdbcType) {
if (jdbcTypeNames == null)
{
setUpJDBCTypeNames();
}
return (String)jdbcTypeNames.get(new Integer(jdbcType));
}
Gets the JDBC type name corresponding to the given type code. |
protected int getJawsCMPFieldJDBCType(CMPFieldMetaData fieldMetaData) {
return fieldMetaData.getJDBCType();
}
|
public String getName() {
return name;
}
return the name of this command |
protected final String getPkColumnList() {
StringBuffer sb = new StringBuffer();
Iterator it = jawsEntity.getPkFields();
while (it.hasNext())
{
PkFieldMetaData pkFieldMetaData = (PkFieldMetaData)it.next();
sb.append(pkFieldMetaData.getColumnName());
if (it.hasNext())
{
sb.append(",");
}
}
return sb.toString();
}
Returns the comma-delimited list of primary key column names
for this entity. |
protected final String getPkColumnWhereList() {
StringBuffer sb = new StringBuffer();
Iterator it = jawsEntity.getPkFields();
while (it.hasNext())
{
PkFieldMetaData pkFieldMetaData = (PkFieldMetaData)it.next();
sb.append(pkFieldMetaData.getColumnName());
sb.append("=?");
if (it.hasNext())
{
sb.append(" AND ");
}
}
return sb.toString();
}
Returns the string to go in a WHERE clause based on
the entity's primary key. |
protected Object getPkFieldValue(Object pk,
PkFieldMetaData pkFieldMetaData) throws IllegalAccessException {
Field field = pkFieldMetaData.getPkField();
return field.get(pk);
}
|
protected Object getResultObject(ResultSet rs,
int idx,
Class destination) throws SQLException {
// log.debug("getting a "+destination.getName()+" from resultset at index "+idx);
Object result = null;
Method method = (Method)rsTypes.get(destination.getName());
if(method != null) {
try {
result = method.invoke(rs, new Object[]{new Integer(idx)});
if(rs.wasNull()) return null;
return result;
} catch(IllegalAccessException e) {
log.debug("Unable to read from ResultSet: ",e);
} catch(InvocationTargetException e) {
log.debug("Unable to read from ResultSet: ",e);
}
}
result = rs.getObject(idx);
if(result == null)
return null;
if(destination == java.math.BigInteger.class
&& result.getClass() == java.math.BigDecimal.class) {
return ((java.math.BigDecimal)result).toBigInteger();
}
if(destination.isAssignableFrom(result.getClass()) && !result.getClass().equals(MarshalledObject.class) )
return result;
else if(log.isDebugEnabled())
log.debug("Got a "+result.getClass().getName()+": '"+result+"' while looking for a "+destination.getName());
// Also we should detect the EJB references here
// Get the underlying byte[]
byte[] bytes = null;
if(result instanceof byte[]) {
bytes = (byte[])result;
} else if(result instanceof Blob) {
Blob blob = (Blob)result;
bytes = blob.getBytes(1, (int)blob.length());
} else if(result instanceof Clob && destination.getName().equals("java.lang.String")) {
try {
Reader in = new BufferedReader(((Clob)result).getCharacterStream());
char[] buf = new char[512];
StringBuffer string = new StringBuffer("");
int count;
while((count = in.read(buf)) > -1)
string.append(buf, 0, count);
in.close();
return string.toString();
} catch(IOException e) {
log.error("Unable to read a CLOB column", e);
throw new SQLException("Unable to read a CLOB column: " +e);
}
} else {
bytes = rs.getBytes(idx);
}
if( bytes == null ) {
result = null;
} else if (destination.getName().equals("[B")) {
return bytes;
} else {
// We should really reuse these guys
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
// Use the class loader to deserialize
try {
ObjectInputStream ois = new ObjectInputStream(bais);
result = ((MarshalledObject) ois.readObject()).get();
// ejb-reference: get the object back from the handle
if (result instanceof Handle) result = ((Handle)result).getEJBObject();
// is this a marshalled object that we stuck in earlier?
if (result instanceof MarshalledObject && !destination.equals(MarshalledObject.class))
result = ((MarshalledObject)result).get();
if(!destination.isAssignableFrom(result.getClass())) {
boolean found = false;
if(destination.isPrimitive()) {
if((destination.equals(Byte.TYPE) && result instanceof Byte) ||
(destination.equals(Short.TYPE) && result instanceof Short) ||
(destination.equals(Character.TYPE) && result instanceof Character) ||
(destination.equals(Boolean.TYPE) && result instanceof Boolean) ||
(destination.equals(Integer.TYPE) && result instanceof Integer) ||
(destination.equals(Long.TYPE) && result instanceof Long) ||
(destination.equals(Float.TYPE) && result instanceof Float) ||
(destination.equals(Double.TYPE) && result instanceof Double)
) {
found = true;
}
}
if(!found) {
if (log.isDebugEnabled())
log.debug("Unable to load a ResultSet column into a variable of type '"+destination.getName()+"' (got a "+result.getClass().getName()+")");
result = null;
}
}
ois.close();
} catch (RemoteException e) {
throw new SQLException("Unable to load EJBObject back from Handle: " +e);
} catch (IOException e) {
throw new SQLException("Unable to load a ResultSet column "+idx+" into a variable of type '"+destination.getName()+"': "+e);
} catch (ClassNotFoundException e) {
throw new SQLException("Unable to load a ResultSet column "+idx+" into a variable of type '"+destination.getName()+"': "+e);
}
}
return result;
}
Used for all retrieval of results from ResultSets.
Implements tracing, and allows some tweaking of returned types. |
protected Object getResultObject(ResultSet rs,
int idx,
CMPFieldMetaData cmpField) throws SQLException {
if (!cmpField.isNested()) {
// do it as before
return getResultObject(rs, idx, cmpField.getField().getType());
}
// Assuming no one will ever use BLOPS in composite objects.
// TODO Should be tested for BLOPability
return rs.getObject(idx);
}
Wrapper around getResultObject(ResultSet rs, int idx, Class destination). |
protected String getSQL(Object argOrArgs) throws Exception {
return sql;
}
Gets the SQL to be used in the PreparedStatement.
The default implementation returns the sql 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 Object[] getState(EntityEnterpriseContext ctx) {
Object[] state = new Object[jawsEntity.getNumberOfCMPFields()];
Iterator iter = jawsEntity.getCMPFields();
int i = 0;
while (iter.hasNext())
{
CMPFieldMetaData fieldMetaData = (CMPFieldMetaData)iter.next();
try
{
// JF: Should clone
state[i++] = getCMPFieldValue(ctx.getInstance(), fieldMetaData);
} catch (Exception e)
{
return null;
}
}
return state;
}
|
protected final boolean isBinaryType(int jdbcType) {
return (Types.BINARY == jdbcType ||
Types.BLOB == jdbcType ||
Types.CLOB == jdbcType ||
Types.JAVA_OBJECT == jdbcType ||
Types.LONGVARBINARY == jdbcType ||
Types.OTHER == jdbcType ||
Types.STRUCT == jdbcType ||
Types.VARBINARY == jdbcType);
}
Returns true if the JDBC type should be (de-)serialized as a
binary stream and false otherwise. |
protected Object jdbcExecute(Object argOrArgs) throws Exception {
Connection con = null;
PreparedStatement stmt = null;
Object result = null;
try
{
con = getConnection();
String theSQL = getSQL(argOrArgs);
if (log.isDebugEnabled())
{
log.debug(name + " command executing: " + theSQL);
}
stmt = con.prepareStatement(theSQL);
setParameters(stmt, argOrArgs);
result = executeStatementAndHandleResult(stmt, argOrArgs);
} catch(SQLException e) {
log.error("Exception caught executing SQL", e);
throw e;
} finally
{
if (stmt != null)
{
try
{
stmt.close();
} catch (SQLException e)
{
log.error("SQLException", e);
}
}
if (con != null)
{
try
{
con.close();
} catch (SQLException e)
{
log.error("SQLException", e);
}
}
}
return result;
}
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 setCMPFieldValue(Object instance,
CMPFieldMetaData fieldMetaData,
Object value) throws IllegalAccessException {
if (fieldMetaData.isNested()) {
// we have a nested field
fieldMetaData.set(instance, value);
}
else {
// the usual way
Field field = fieldMetaData.getField();
field.set(instance, value);
}
}
|
protected void setParameter(PreparedStatement stmt,
int idx,
int jdbcType,
Object value) throws SQLException {
if (log.isDebugEnabled())
{
log.debug("Set parameter: idx=" + idx +
", jdbcType=" + getJDBCTypeName(jdbcType) +
", value=" +
((value == null) ? "NULL" : value));
}
if (value == null) {
stmt.setNull(idx, jdbcType);
} else {
if(jdbcType == Types.DATE) {
if(value.getClass().getName().equals("java.util.Date"))
value = new java.sql.Date(((java.util.Date)value).getTime());
} else if(jdbcType == Types.TIME) {
if(value.getClass().getName().equals("java.util.Date"))
value = new java.sql.Time(((java.util.Date)value).getTime());
} else if(jdbcType == Types.TIMESTAMP) {
if(value.getClass().getName().equals("java.util.Date"))
value = new java.sql.Timestamp(((java.util.Date)value).getTime());
}
if (isBinaryType(jdbcType)) {
byte[] bytes = null;
if (value instanceof byte[]) {
bytes = (byte[])value;
} else {
// ejb-reference: store the handle
if (value instanceof EJBObject) try {
value = ((EJBObject)value).getHandle();
} catch (RemoteException e) {
throw new SQLException
("Cannot get Handle of EJBObject: "+e);
}
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(new MarshalledObject(value));
bytes = baos.toByteArray();
oos.close();
} catch (IOException e) {
throw new SQLException
("Can't serialize binary object: " + e);
}
}
// it's more efficient to use setBinaryStream for large
// streams, and causes problems if not done on some DBMS
// implementations
// if this is an Oracle Blob only setBlob will work.
if (jdbcType == Types.BLOB) {
stmt.setBlob(idx, new ByteArrayBlob(bytes));
} else if (value instanceof java.math.BigInteger) {
stmt.setObject(idx, ((java.math.BigInteger)value), jdbcType);
} else if (bytes.length < 2000) {
stmt.setBytes(idx, bytes);
} else {
try {
ByteArrayInputStream bais =
new ByteArrayInputStream(bytes);
stmt.setBinaryStream(idx, bais, bytes.length);
bais.close();
} catch (IOException e) {
throw new SQLException
("Couldn't write binary object to DB: " + e);
}
}
} else {
switch(jdbcType)
{
case Types.DECIMAL:
case Types.NUMERIC:
if(value instanceof BigDecimal)
{
stmt.setBigDecimal(idx, (BigDecimal)value);
}
else
{
stmt.setObject(idx, value, jdbcType, 0);
}
break;
default:
stmt.setObject(idx, value, jdbcType);
}
}
}
}
Sets a parameter in this Command's PreparedStatement.
Handles null values, and provides tracing. |
protected void setParameters(PreparedStatement stmt,
Object argOrArgs) throws Exception {
}
Default implementation does nothing.
Override if parameters need to be set. |
protected int setPrimaryKeyParameters(PreparedStatement stmt,
int parameterIndex,
Object id) throws SQLException, IllegalAccessException {
Iterator it = jawsEntity.getPkFields();
if (jawsEntity.hasCompositeKey())
{
while (it.hasNext())
{
PkFieldMetaData pkFieldMetaData = (PkFieldMetaData)it.next();
int jdbcType = pkFieldMetaData.getJDBCType();
Object value = getPkFieldValue(id, pkFieldMetaData);
setParameter(stmt, parameterIndex++, jdbcType, value);
}
} else
{
PkFieldMetaData pkFieldMetaData = (PkFieldMetaData)it.next();
int jdbcType = pkFieldMetaData.getJDBCType();
setParameter(stmt, parameterIndex++, jdbcType, id);
}
return parameterIndex;
}
Sets the PreparedStatement parameters for a primary key
in a WHERE clause. |
protected void setSQL(String sql) {
if (log.isDebugEnabled())
log.debug(name + " SQL: " + sql);
this.sql = sql;
}
Used to set static SQL in subclass constructors. |