package org.exolab.castor.persist.spi; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.castor.core.util.Messages; import org.castor.jdo.engine.SQLTypeInfos; import org.castor.persist.ProposedEntity; import org.exolab.castor.jdo.PersistenceException; import org.exolab.castor.mapping.AccessMode; public abstract class AbstractCallQuery implements PersistenceQuery { /** The <a href="http://jakarta.apache.org/commons/logging/">Jakarta Commons * Logging</a> instance used for all logging. */ private static Log _log = LogFactory.getFactory().getInstance(AbstractCallQuery.class); private int[] _sqlTypes; protected PreparedStatement _stmt; protected ResultSet _rs; protected Identity _lastIdentity; private final Class<?>[] _types; protected final Object[] _values; private final Class<?> _javaClass; protected final String _call; protected AbstractCallQuery(final String call, final Class<?>[] types, final Class<?> javaClass, final int[] sqlTypes) { _types = types; _javaClass = javaClass; _sqlTypes = sqlTypes; _values = new Object[_types.length]; _call = "{call " + call + "}"; } protected abstract boolean nextRow() throws SQLException; /** * @inheritDoc */ public void fetch(final ProposedEntity proposedObject) throws PersistenceException { try { // Load all the fields of the object including one-one relations // index 0 belongs to the identity for (int i = 1; i < _sqlTypes.length; ++i) { proposedObject.setField( SQLTypeInfos.getValue(_rs, i + 1, _sqlTypes[i]), i - 1); } if (nextRow()) { _lastIdentity = new Identity(SQLTypeInfos.getValue(_rs, 1, _sqlTypes[0])); } else { _lastIdentity = null; } } catch (SQLException except) { throw new PersistenceException(Messages.format("persist.nested", except)); } } public void close() { if (_rs != null) { try { _rs.close(); } catch (SQLException except) { _log.warn(Messages.message("persist.rsClosingFailed"), except); } _rs = null; } if (_stmt != null) { try { _stmt.close(); } catch (SQLException except) { _log.warn(Messages.message("persist.stClosingFailed"), except); } _stmt = null; } } public int getParameterCount() { return _types.length; } public Class<?> getParameterType(final int index) throws ArrayIndexOutOfBoundsException { return _types[index]; } public void setParameter(final int index, final Object value) throws ArrayIndexOutOfBoundsException, IllegalArgumentException { _values[index] = value; } public boolean absolute(final int row) throws PersistenceException { return false; } public int size() throws PersistenceException { return 0; } public Class<?> getResultType() { return _javaClass; } public void execute(final Object conn, final AccessMode accessMode, final boolean scrollable) throws PersistenceException { execute(conn, accessMode); } protected abstract void execute(final Object conn, final AccessMode accessMode) throws PersistenceException; public Identity nextIdentity(final Identity identity) throws PersistenceException { try { if (_lastIdentity == null) { if (!nextRow()) { return null; } _lastIdentity = new Identity(SQLTypeInfos.getValue(_rs, 1, _sqlTypes[0])); return _lastIdentity; } while (_lastIdentity.equals(identity)) { if (!nextRow()) { _lastIdentity = null; return null; } _lastIdentity = new Identity(SQLTypeInfos.getValue(_rs, 1, _sqlTypes[0])); } return _lastIdentity; } catch (SQLException except) { _lastIdentity = null; throw new PersistenceException(Messages.format("persist.nested", except)); } } }