You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ibatis.apache.org by cb...@apache.org on 2008/08/08 01:21:58 UTC

svn commit: r683745 [3/22] - in /ibatis/trunk/java/ibatis-3: ./ ibatis-3-compat/ ibatis-3-compat/src/ ibatis-3-compat/src/main/ ibatis-3-compat/src/main/java/ ibatis-3-compat/src/main/java/com/ ibatis-3-compat/src/main/java/com/ibatis/ ibatis-3-compat/...

Added: ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/dao/engine/transaction/jdbc/JdbcDaoTransactionManager.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/dao/engine/transaction/jdbc/JdbcDaoTransactionManager.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/dao/engine/transaction/jdbc/JdbcDaoTransactionManager.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/dao/engine/transaction/jdbc/JdbcDaoTransactionManager.java Thu Aug  7 16:21:46 2008
@@ -0,0 +1,87 @@
+package com.ibatis.dao.engine.transaction.jdbc;
+
+import com.ibatis.common.jdbc.*;
+import com.ibatis.dao.client.*;
+import com.ibatis.dao.engine.transaction.DaoTransactionManager;
+
+import javax.naming.*;
+import javax.sql.DataSource;
+import java.util.*;
+
+/**
+ * DaoTransactionManager implementation for JDBC
+ */
+public class JdbcDaoTransactionManager implements DaoTransactionManager {
+
+  private DataSource dataSource;
+
+  public void configure(Properties properties) {
+    if (properties.containsKey("DataSource")) {
+      String type = (String) properties.get("DataSource");
+      if ("SIMPLE".equals(type)) {
+        configureSimpleDataSource(properties);
+      } else if ("DBCP".equals(type)) {
+        configureDbcp(properties);
+      } else if ("JNDI".equals(type)) {
+        configureJndi(properties);
+      } else {
+        throw new DaoException("DAO Transaction Manager properties must include a value for 'DataSource' of SIMPLE, DBCP or JNDI.");
+      }
+    } else {
+      throw new DaoException("DAO Transaction Manager properties must include a value for 'DataSource' of SIMPLE, DBCP or JNDI.");
+    }
+  }
+
+  public DaoTransaction startTransaction() {
+    return new JdbcDaoTransaction(dataSource);
+  }
+
+  private void configureSimpleDataSource(Map properties) {
+    dataSource = new SimpleDataSource(properties);
+  }
+
+  private void configureDbcp(Map properties) {
+    DbcpConfiguration dbcp = new DbcpConfiguration(properties);
+    dataSource = dbcp.getDataSource();
+  }
+
+  private void configureJndi(Map properties) {
+    try {
+      Hashtable contextProps = getContextProperties(properties);
+      InitialContext initCtx = null;
+      if (contextProps == null) {
+        initCtx = new InitialContext();
+      } else {
+        initCtx = new InitialContext(contextProps);
+      }
+      dataSource = (DataSource) initCtx.lookup((String) properties.get("DBJndiContext"));
+    } catch (NamingException e) {
+      throw new DaoException("There was an error configuring the DataSource from JNDI.  Cause: " + e, e);
+    }
+  }
+
+  public void commitTransaction(DaoTransaction trans) {
+    ((JdbcDaoTransaction) trans).commit();
+  }
+
+  public void rollbackTransaction(DaoTransaction trans) {
+    ((JdbcDaoTransaction) trans).rollback();
+  }
+
+  private static Hashtable getContextProperties(Map allProps) {
+    final String PREFIX = "context.";
+    Hashtable contextProperties = null;
+    Iterator keys = allProps.keySet().iterator();
+    while (keys.hasNext()) {
+      String key = (String) keys.next();
+      String value = (String) allProps.get(key);
+      if (key.startsWith(PREFIX)) {
+        if (contextProperties == null) {
+          contextProperties = new Properties();
+        }
+        contextProperties.put(key.substring(PREFIX.length()), value);
+      }
+    }
+    return contextProperties;
+  }
+}

Added: ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/dao/engine/transaction/sqlmap/SqlMapDaoTransaction.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/dao/engine/transaction/sqlmap/SqlMapDaoTransaction.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/dao/engine/transaction/sqlmap/SqlMapDaoTransaction.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/dao/engine/transaction/sqlmap/SqlMapDaoTransaction.java Thu Aug  7 16:21:46 2008
@@ -0,0 +1,51 @@
+package com.ibatis.dao.engine.transaction.sqlmap;
+
+import com.ibatis.dao.client.DaoException;
+import com.ibatis.dao.engine.transaction.ConnectionDaoTransaction;
+import com.ibatis.sqlmap.client.SqlMapClient;
+
+import java.sql.*;
+
+public class SqlMapDaoTransaction implements ConnectionDaoTransaction {
+
+  private SqlMapClient client;
+
+  public SqlMapDaoTransaction(SqlMapClient client) {
+    try {
+      client.startTransaction();
+      this.client = client;
+    } catch (SQLException e) {
+      throw new DaoException("Error starting SQL Map transaction.  Cause: " + e, e);
+    }
+  }
+
+  public void commit() {
+    try {
+      client.commitTransaction();
+      client.endTransaction();
+    } catch (SQLException e) {
+      throw new DaoException("Error committing SQL Map transaction.  Cause: " + e, e);
+    }
+  }
+
+  public void rollback() {
+    try {
+      client.endTransaction();
+    } catch (SQLException e) {
+      throw new DaoException("Error ending SQL Map transaction.  Cause: " + e, e);
+    }
+  }
+
+  public SqlMapClient getSqlMap() {
+    return client;
+  }
+
+  public Connection getConnection() {
+    try {
+      return client.getCurrentConnection();
+    } catch (SQLException e) {
+      throw new DaoException("Error getting connection from SQL Map Client.  Cause: " + e, e);
+    }
+  }
+
+}

Added: ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/dao/engine/transaction/sqlmap/SqlMapDaoTransactionManager.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/dao/engine/transaction/sqlmap/SqlMapDaoTransactionManager.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/dao/engine/transaction/sqlmap/SqlMapDaoTransactionManager.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/dao/engine/transaction/sqlmap/SqlMapDaoTransactionManager.java Thu Aug  7 16:21:46 2008
@@ -0,0 +1,70 @@
+package com.ibatis.dao.engine.transaction.sqlmap;
+
+import com.ibatis.common.resources.Resources;
+import com.ibatis.dao.client.*;
+import com.ibatis.dao.engine.transaction.DaoTransactionManager;
+import com.ibatis.sqlmap.client.*;
+
+import java.io.*;
+import java.util.Properties;
+
+/**
+ * @see com.ibatis.dao.engine.transaction.DaoTransactionManager
+ */
+public class SqlMapDaoTransactionManager implements DaoTransactionManager {
+
+  private SqlMapClient client;
+
+  /**
+   * Required by interface
+   *
+   * @param properties required by interface
+   * @see com.ibatis.dao.engine.transaction.DaoTransactionManager
+   */
+  public void configure(Properties properties) {
+    try {
+      Reader reader = null;
+      if (properties.containsKey("SqlMapConfigURL")) {
+        reader = Resources.getUrlAsReader((String) properties.get("SqlMapConfigURL"));
+      } else if (properties.containsKey("SqlMapConfigResource")) {
+        reader = Resources.getResourceAsReader((String) properties.get("SqlMapConfigResource"));
+      } else {
+        throw new DaoException("SQLMAP transaction manager requires either 'SqlMapConfigURL' or 'SqlMapConfigResource' to be specified as a property.");
+      }
+      client = SqlMapClientBuilder.buildSqlMapClient(reader, properties);
+    } catch (IOException e) {
+      throw new DaoException("Error configuring SQL Map.  Cause: " + e);
+    }
+  }
+
+  /**
+   * Required by interface
+   *
+   * @return A new Transaction
+   * @see com.ibatis.dao.engine.transaction.DaoTransactionManager
+   */
+  public DaoTransaction startTransaction() {
+    return new SqlMapDaoTransaction(client);
+  }
+
+  /**
+   * Required by interface
+   *
+   * @param trans Required by interface
+   * @see com.ibatis.dao.engine.transaction.DaoTransactionManager
+   */
+  public void commitTransaction(DaoTransaction trans) {
+    ((SqlMapDaoTransaction) trans).commit();
+  }
+
+  /**
+   * Required by interface
+   *
+   * @param trans Required by interface
+   * @see com.ibatis.dao.engine.transaction.DaoTransactionManager
+   */
+  public void rollbackTransaction(DaoTransaction trans) {
+    ((SqlMapDaoTransaction) trans).rollback();
+  }
+
+}

Added: ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/client/SqlMapClient.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/client/SqlMapClient.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/client/SqlMapClient.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/client/SqlMapClient.java Thu Aug  7 16:21:46 2008
@@ -0,0 +1,208 @@
+package com.ibatis.sqlmap.client;
+
+import java.sql.Connection;
+
+/**
+ * A thread safe client for working with your SQL Maps (Start Here).  This interface inherits transaction control
+ * and execution methods from the SqlMapTransactionManager and SqlMapExecutor interfaces.
+ * <p/>
+ * The SqlMapClient is the central class for working with SQL Maps.  This class will allow you
+ * to run mapped statements (select, insert, update, delete etc.), and also demarcate
+ * transactions and work with batches.  Once you have an SqlMapClient instance, everything
+ * you need to work with SQL Maps is easily available.
+ * <p/>
+ * The SqlMapClient can either
+ * be worked with directly as a multi-threaded client (internal session management), or you can get a single threaded
+ * session and work with that.  There may be a slight performance increase if you explicitly
+ * get a session (using the openSession() method), as it saves the SqlMapClient from having
+ * to manage threads contexts.  But for most cases it won't make much of a difference, so
+ * choose whichever paradigm suits your needs or preferences.
+ * <p/>
+ * An SqlMapClient instance can be safely made <i>static</i> or applied as a <i>Singleton</i>.
+ * Generally it's a good idea to make a simple configuration class that will configure the
+ * instance (using SqlMapClientBuilder) and provide access to it.
+ * <p/>
+ * <b>The following example will demonstrate the use of SqlMapClient.</b>
+ * <pre>
+ * <i><font color="green">
+ * //
+ * // autocommit simple query --these are just examples...not patterns
+ * //
+ * </font></i>
+ * Employee emp = (Employee) <b>sqlMap.queryForObject("getEmployee", new Integer(1))</b>;
+ * <i><font color="green">
+ * //
+ * // transaction --these are just examples...not patterns
+ * //
+ * </font></i>
+ * try {
+ *   <b>sqlMap.startTransaction()</b>
+ *   Employee emp2 = new Employee();
+ *   // ...set emp2 data
+ *   Integer generatedKey = (Integer) <b>sqlMap.insert ("insertEmployee", emp2)</b>;
+ *   emp2.setFavouriteColour ("green");
+ *   <b>sqlMap.update("updateEmployee", emp2)</b>;
+ *   <b>sqlMap.commitTransaction()</b>;
+ * } finally {
+ *   <b>sqlMap.endTransaction()</b>;
+ * }
+ * <i><font color="green">
+ * //
+ * // session --these are just examples...not patterns
+ * //
+ * </font></i>
+ * try {
+ *   <b>SqlMapSession session = sqlMap.openSession()</b>
+ *   <b>session.startTransaction()</b>
+ *   Employee emp2 = new Employee();
+ *   // ...set emp2 data
+ *   Integer generatedKey = (Integer) <b>session.insert ("insertEmployee", emp2)</b>;
+ *   emp2.setFavouriteColour ("green");
+ *   <b>session.update("updateEmployee", emp2)</b>;
+ *   <b>session.commitTransaction()</b>;
+ * } finally {
+ *   try {
+ *     <b>session.endTransaction()</b>;
+ *   } finally {
+ *     <b>session.close()</b>;
+ *   }
+ *   // Generally your session scope would be in a wider context and therefore the
+ *   // ugly nested finally block above would not be there.  Realize that sessions
+ *   // MUST be closed if explicitly opened (via openSession()).
+ * }
+ * <i><font color="green">
+ * //
+ * // batch --these are just examples...not patterns
+ * //
+ * </font></i>
+ * try {
+ *   <b>sqlMap.startTransaction()</b>
+ *   List list = (Employee) <b>sqlMap.queryForList("getFiredEmployees", null)</b>;
+ *   <b>sqlMap.startBatch ()</b>;
+ *   for (int i=0, n=list.size(); i < n; i++) {
+ *     <b>sqlMap.delete ("deleteEmployee", list.get(i))</b>;
+ *   }
+ *   <b>sqlMap.executeBatch()</b>;
+ *   <b>sqlMap.commitTransaction()</b>;
+ * } finally {
+ *   <b>sqlMap.endTransaction()</b>;
+ * }
+ * </pre>
+ *
+ * @see SqlMapClientBuilder
+ * @see com.ibatis.sqlmap.client.SqlMapSession
+ * @see com.ibatis.sqlmap.client.SqlMapExecutor
+ */
+public interface SqlMapClient extends SqlMapExecutor, SqlMapTransactionManager {
+
+  /**
+   * Returns a single threaded SqlMapSession implementation for use by
+   * one user.  Remember though, that SqlMapClient itself is a thread safe SqlMapSession
+   * implementation, so you can also just work directly with it.  If you do get a session
+   * explicitly using this method <b>be sure to close it!</b>  You can close a session using
+   * the sqlMapSession.close() method.
+   * <p/>
+   *
+   * @return An SqlMapSession instance.
+   */
+  public SqlMapSession openSession();
+
+  /**
+   * Returns a single threaded SqlMapSession implementation for use by
+   * one user.  Remember though, that SqlMapClient itself is a thread safe SqlMapSession
+   * implementation, so you can also just work directly with it.  If you do get a session
+   * explicitly using this method <b>be sure to close it!</b>  You can close a session using
+   * the SqlMapSession.close() method.
+   * <p/>
+   * This particular implementation takes a user provided connection as a parameter.  This
+   * connection will be used for executing statements, and therefore overrides any
+   * configured datasources.  Using this approach allows the developer to easily use an externally
+   * supplied connection for executing statements.
+   * <p/>
+   * <b>Important:</b> Using a user supplied connection basically sidesteps the datasource
+   * so you are responsible for appropriately handling your connection lifecycle (i.e. closing).
+   * Here's a (very) simple example (throws SQLException):
+   * <pre>
+   * try {
+   *   Connection connection = dataSource.getConnection();
+   *   SqlMapSession session = sqlMap.openSession(connection);
+   *   // do work
+   *   connection.commit();
+   * } catch (SQLException e) {
+   *     try {
+   *       if (connection != null) commit.rollback();
+   *     } catch (SQLException ignored) {
+   *       // generally ignored
+   *     }
+   *     throw e;  // rethrow the exception
+   * } finally {
+   *   try {
+   *     if (connection != null) connection.close();
+   *   } catch (SQLException ignored) {
+   *     // generally ignored
+   *   }
+   * }
+   * </pre>
+   *
+   * @param conn - the connection to use for the session
+   * @return An SqlMapSession instance.
+   */
+  public SqlMapSession openSession(Connection conn);
+
+  /**
+   * Flushes all data caches.
+   */
+  public void flushDataCache();
+
+  /**
+   * Flushes the data cache that matches the cache model ID provided.
+   * cacheId should include the namespace, even when
+   * useStatementNamespaces="false".
+   *
+   * @param cacheId The cache model to flush
+   */
+  public void flushDataCache(String cacheId);
+
+  /**
+   * Returns a generated implementation of a cusom mapper class as specified by the method
+   * parameter.  The generated implementation will run mapped statements by matching the method
+   * name to the statement name.  The mapped statement elements determine how the statement is
+   * run as per the following:
+   * <ul>
+   *   <li>&lt;insert&gt; -- insert()
+   *   <li>&lt;update&gt; -- update()
+   *   <li>&lt;delete&gt; -- delete()
+   *   <li>&lt;select&gt; -- queryForObject, queryForList or queryForMap, as determined by signature (see below)
+   *   <li>&lt;procedure&gt; -- determined by method name (see below)
+   * </ul>
+   *
+   * How select statements are run is determined by the method signature,
+   * as per the following:
+   * <ul>
+   *   <li> Object methodName (Object param) -- queryForObject
+   *   <li> List methodName (Object param [, int skip, int max | , int pageSize]) -- queryForList
+   *   <li> Map methodName (Object param, String keyProp [,valueProp]) -- queryForMap
+   * </ul>
+   *
+   * How stored procedures are run is determined by the method name,
+   * as per the following:
+   * <ul>
+   *   <li> insertXxxxx -- insert()
+   *   <li> createXxxxx -- insert()
+   *   <li> updateXxxxx -- update()
+   *   <li> saveXxxxx -- update()
+   *   <li> deleteXxxxx -- delete()
+   *   <li> removeXxxxx -- delete()
+   *   <li> selectXxxxx -- queryForXxxxxx() determined by method signature as above
+   *   <li> queryXxxxx -- queryForXxxxxx() determined by method signature as above
+   *   <li> fetchXxxxx -- queryForXxxxxx() determined by method signature as above
+   *   <li> getXxxxx -- queryForXxxxxx() determined by method signature as above
+   * </ul>
+   *
+   * @param iface The interface that contains methods representing the mapped statements contained.
+   * @return An instance of iface that can be used to call mapped statements directly in a typesafe
+   * manner.
+   */
+  //public Object getMapper(Class iface);
+
+}
\ No newline at end of file

Added: ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/client/SqlMapClientBuilder.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/client/SqlMapClientBuilder.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/client/SqlMapClientBuilder.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/client/SqlMapClientBuilder.java Thu Aug  7 16:21:46 2008
@@ -0,0 +1,69 @@
+package com.ibatis.sqlmap.client;
+
+import com.ibatis.sqlmap.engine.builder.*;
+import com.ibatis.sqlmap.engine.impl.SqlMapClientImpl;
+
+import java.io.Reader;
+import java.util.Properties;
+
+/**
+ * Builds SqlMapClient instances from a supplied resource (e.g. XML configuration file)
+ * <p/>
+ * The SqlMapClientBuilder class is responsible for parsing configuration documents
+ * and building the SqlMapClient instance.  Its current implementation works with
+ * XML configuration files (e.g. sql-map-config.xml).
+ * <p/>
+ * Example:
+ * <pre>
+ * Reader reader = Resources.getResourceAsReader("properties/sql-map-config.xml");
+ * SqlMapClient client = SqlMapClientBuilder.buildSqlMapClient (reader);
+ * </pre>
+ * <p/>
+ * Examples of the XML document structure used by SqlMapClientBuilder can
+ * be found at the links below.
+ * <p/>
+ * Note: They might look big, but they're mostly comments!
+ * <ul>
+ * <li> <a href="sql-map-config.txt">The SQL Map Config File</a>
+ * <li> <a href="sql-map.txt">An SQL Map File</a>
+ * <ul>
+ */
+public class SqlMapClientBuilder {
+
+  /**
+   * No instantiation allowed.
+   */
+  protected SqlMapClientBuilder() {
+  }
+
+  /**
+   * Builds an SqlMapClient using the specified reader.
+   *
+   * @param reader A Reader instance that reads an sql-map-config.xml file.
+   *               The reader should read an well formed sql-map-config.xml file.
+   * @return An SqlMapClient instance.
+   */
+  public static SqlMapClient buildSqlMapClient(Reader reader) {
+    XmlSqlMapConfigParser configParser = new XmlSqlMapConfigParser(reader);
+    configParser.parse();
+    return new SqlMapClientImpl((Ibatis2Configuration) configParser.getConfiguration());
+  }
+
+  /**
+   * Builds an SqlMapClient using the specified reader and properties file.
+   * <p/>
+   *
+   * @param reader A Reader instance that reads an sql-map-config.xml file.
+   *               The reader should read an well formed sql-map-config.xml file.
+   * @param props  Properties to be used to provide values to dynamic property tokens
+   *               in the sql-map-config.xml configuration file.  This provides an easy way to
+   *               achieve some level of programmatic configuration.
+   * @return An SqlMapClient instance.
+   */
+  public static SqlMapClient buildSqlMapClient(Reader reader, Properties props) {
+    XmlSqlMapConfigParser configParser = new XmlSqlMapConfigParser(reader, props);
+    configParser.parse();
+    return new SqlMapClientImpl((Ibatis2Configuration) configParser.getConfiguration());
+  }
+
+}

Added: ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/client/SqlMapException.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/client/SqlMapException.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/client/SqlMapException.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/client/SqlMapException.java Thu Aug  7 16:21:46 2008
@@ -0,0 +1,48 @@
+package com.ibatis.sqlmap.client;
+
+
+/**
+ * Thrown to indicate a problem with SQL Map configuration or state.  Generally
+ * if an SqlMapException is thrown, something is critically wronge and cannot
+ * be corrected until a change to the configuration or the environment is made.
+ * <p/>
+ * Note: Generally this wouldn't be used to indicate that an SQL execution error
+ * occurred (that's what SQLException is for).
+ */
+public class SqlMapException extends RuntimeException {
+
+  /**
+   * Simple constructor
+   */
+  public SqlMapException() {
+  }
+
+  /**
+   * Constructor to create exception with a message
+   *
+   * @param msg A message to associate with the exception
+   */
+  public SqlMapException(String msg) {
+    super(msg);
+  }
+
+  /**
+   * Constructor to create exception to wrap another exception
+   *
+   * @param cause The real cause of the exception
+   */
+  public SqlMapException(Throwable cause) {
+    super(cause);
+  }
+
+  /**
+   * Constructor to create exception to wrap another exception and pass a message
+   *
+   * @param msg   The message
+   * @param cause The real cause of the exception
+   */
+  public SqlMapException(String msg, Throwable cause) {
+    super(msg, cause);
+  }
+
+}

Added: ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/client/SqlMapExecutor.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/client/SqlMapExecutor.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/client/SqlMapExecutor.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/client/SqlMapExecutor.java Thu Aug  7 16:21:46 2008
@@ -0,0 +1,311 @@
+package com.ibatis.sqlmap.client;
+
+import com.ibatis.common.util.PaginatedList;
+import com.ibatis.sqlmap.client.event.RowHandler;
+import com.ibatis.sqlmap.engine.execution.BatchException;
+
+import java.sql.SQLException;
+import java.util.*;
+
+/**
+ * This interface declares all methods involved with executing statements
+ * and batches for an SQL Map.
+ *
+ * @see com.ibatis.sqlmap.client.SqlMapSession
+ * @see SqlMapClient
+ */
+public interface SqlMapExecutor {
+
+  /**
+   * Executes a mapped SQL INSERT statement.
+   * Insert is a bit different from other update methods, as it
+   * provides facilities for returning the primary key of the
+   * newly inserted row (rather than the effected rows).  This
+   * functionality is of course optional.
+   * <p/>
+   * The parameter object is generally used to supply the input
+   * data for the INSERT values.
+   *
+   * @param id              The name of the statement to execute.
+   * @param parameterObject The parameter object (e.g. JavaBean, Map, XML etc.).
+   * @return The primary key of the newly inserted row.  This might be automatically
+   *         generated by the RDBMS, or selected from a sequence table or other source.
+   * @throws java.sql.SQLException If an error occurs.
+   */
+  Object insert(String id, Object parameterObject) throws SQLException;
+
+  /**
+   * Executes a mapped SQL INSERT statement.
+   * Insert is a bit different from other update methods, as it
+   * provides facilities for returning the primary key of the
+   * newly inserted row (rather than the effected rows).  This
+   * functionality is of course optional.
+   * <p/>
+   * This overload assumes no parameter is needed.
+   *
+   * @param id The name of the statement to execute.
+   * @return The primary key of the newly inserted row.  This might be automatically
+   *         generated by the RDBMS, or selected from a sequence table or other source.
+   * @throws java.sql.SQLException If an error occurs.
+   */
+  Object insert(String id) throws SQLException;
+
+  /**
+   * Executes a mapped SQL UPDATE statement.
+   * Update can also be used for any other update statement type,
+   * such as inserts and deletes.  Update returns the number of
+   * rows effected.
+   * <p/>
+   * The parameter object is generally used to supply the input
+   * data for the UPDATE values as well as the WHERE clause parameter(s).
+   *
+   * @param id              The name of the statement to execute.
+   * @param parameterObject The parameter object (e.g. JavaBean, Map, XML etc.).
+   * @return The number of rows effected.
+   * @throws java.sql.SQLException If an error occurs.
+   */
+  int update(String id, Object parameterObject) throws SQLException;
+
+  /**
+   * Executes a mapped SQL UPDATE statement.
+   * Update can also be used for any other update statement type,
+   * such as inserts and deletes.  Update returns the number of
+   * rows effected.
+   * <p/>
+   * This overload assumes no parameter is needed.
+   *
+   * @param id The name of the statement to execute.
+   * @return The number of rows effected.
+   * @throws java.sql.SQLException If an error occurs.
+   */
+  int update(String id) throws SQLException;
+
+  /**
+   * Executes a mapped SQL DELETE statement.
+   * Delete returns the number of rows effected.
+   * <p/>
+   * The parameter object is generally used to supply the input
+   * data for the WHERE clause parameter(s) of the DELETE statement.
+   *
+   * @param id              The name of the statement to execute.
+   * @param parameterObject The parameter object (e.g. JavaBean, Map, XML etc.).
+   * @return The number of rows effected.
+   * @throws java.sql.SQLException If an error occurs.
+   */
+  int delete(String id, Object parameterObject) throws SQLException;
+
+  /**
+   * Executes a mapped SQL DELETE statement.
+   * Delete returns the number of rows effected.
+   * <p/>
+   * This overload assumes no parameter is needed.
+   *
+   * @param id The name of the statement to execute.
+   * @return The number of rows effected.
+   * @throws java.sql.SQLException If an error occurs.
+   */
+  int delete(String id) throws SQLException;
+
+  /**
+   * Executes a mapped SQL SELECT statement that returns data to populate
+   * a single object instance.
+   * <p/>
+   * The parameter object is generally used to supply the input
+   * data for the WHERE clause parameter(s) of the SELECT statement.
+   *
+   * @param id              The name of the statement to execute.
+   * @param parameterObject The parameter object (e.g. JavaBean, Map, XML etc.).
+   * @return The single result object populated with the result set data,
+   *         or null if no result was found
+   * @throws java.sql.SQLException If more than one result was found, or if any other error occurs.
+   */
+  Object queryForObject(String id, Object parameterObject) throws SQLException;
+
+  /**
+   * Executes a mapped SQL SELECT statement that returns data to populate
+   * a single object instance.
+   * <p/>
+   * This overload assumes no parameter is needed.
+   *
+   * @param id The name of the statement to execute.
+   * @return The single result object populated with the result set data,
+   *         or null if no result was found
+   * @throws java.sql.SQLException If more than one result was found, or if any other error occurs.
+   */
+  Object queryForObject(String id) throws SQLException;
+
+  /**
+   * Executes a mapped SQL SELECT statement that returns data to populate
+   * the supplied result object.
+   * <p/>
+   * The parameter object is generally used to supply the input
+   * data for the WHERE clause parameter(s) of the SELECT statement.
+   *
+   * @param id              The name of the statement to execute.
+   * @param parameterObject The parameter object (e.g. JavaBean, Map, XML etc.).
+   * @param resultObject    The result object instance that should be populated with result data.
+   * @return The single result object as supplied by the resultObject parameter, populated with the result set data,
+   *         or null if no result was found
+   * @throws java.sql.SQLException If more than one result was found, or if any other error occurs.
+   */
+  Object queryForObject(String id, Object parameterObject, Object resultObject) throws SQLException;
+
+  /**
+   * Executes a mapped SQL SELECT statement that returns data to populate
+   * a number of result objects.
+   * <p/>
+   * The parameter object is generally used to supply the input
+   * data for the WHERE clause parameter(s) of the SELECT statement.
+   *
+   * @param id              The name of the statement to execute.
+   * @param parameterObject The parameter object (e.g. JavaBean, Map, XML etc.).
+   * @return A List of result objects.
+   * @throws java.sql.SQLException If an error occurs.
+   */
+  List queryForList(String id, Object parameterObject) throws SQLException;
+
+  /**
+   * Executes a mapped SQL SELECT statement that returns data to populate
+   * a number of result objects.
+   * <p/>
+   * This overload assumes no parameter is needed.
+   *
+   * @param id The name of the statement to execute.
+   * @return A List of result objects.
+   * @throws java.sql.SQLException If an error occurs.
+   */
+  List queryForList(String id) throws SQLException;
+
+  /**
+   * Executes a mapped SQL SELECT statement that returns data to populate
+   * a number of result objects within a certain range.
+   * <p/>
+   * The parameter object is generally used to supply the input
+   * data for the WHERE clause parameter(s) of the SELECT statement.
+   *
+   * @param id              The name of the statement to execute.
+   * @param parameterObject The parameter object (e.g. JavaBean, Map, XML etc.).
+   * @param skip            The number of results to ignore.
+   * @param max             The maximum number of results to return.
+   * @return A List of result objects.
+   * @throws java.sql.SQLException If an error occurs.
+   */
+  List queryForList(String id, Object parameterObject, int skip, int max) throws SQLException;
+
+  /**
+   * Executes a mapped SQL SELECT statement that returns data to populate
+   * a number of result objects within a certain range.
+   * <p/>
+   * This overload assumes no parameter is needed.
+   *
+   * @param id   The name of the statement to execute.
+   * @param skip The number of results to ignore.
+   * @param max  The maximum number of results to return.
+   * @return A List of result objects.
+   * @throws java.sql.SQLException If an error occurs.
+   */
+  List queryForList(String id, int skip, int max) throws SQLException;
+
+  /**
+   * Executes a mapped SQL SELECT statement that returns a number of
+   * result objects that will be handled one at a time by a
+   * RowHandler.
+   * <p/>
+   * This is generally a good approach to take when dealing with large sets
+   * of records (i.e. hundreds, thousands...) that need to be processed without
+   * eating up all of the system resources.
+   * <p/>
+   * The parameter object is generally used to supply the input
+   * data for the WHERE clause parameter(s) of the SELECT statement.
+   *
+   * @param id              The name of the statement to execute.
+   * @param parameterObject The parameter object (e.g. JavaBean, Map, XML etc.).
+   * @param rowHandler      A RowHandler instance
+   * @throws java.sql.SQLException If an error occurs.
+   */
+  void queryWithRowHandler(String id, Object parameterObject, RowHandler rowHandler) throws SQLException;
+
+  /**
+   * Executes a mapped SQL SELECT statement that returns a number of
+   * result objects that will be handled one at a time by a
+   * RowHandler.
+   * <p/>
+   * This is generally a good approach to take when dealing with large sets
+   * of records (i.e. hundreds, thousands...) that need to be processed without
+   * eating up all of the system resources.
+   * <p/>
+   * This overload assumes no parameter is needed.
+   *
+   * @param id         The name of the statement to execute.
+   * @param rowHandler A RowHandler instance
+   * @throws java.sql.SQLException If an error occurs.
+   */
+  void queryWithRowHandler(String id, RowHandler rowHandler) throws SQLException;
+
+  /**
+   * Executes a mapped SQL SELECT statement that returns data to populate
+   * a number of result objects that will be keyed into a Map.
+   * <p/>
+   * The parameter object is generally used to supply the input
+   * data for the WHERE clause parameter(s) of the SELECT statement.
+   *
+   * @param id              The name of the statement to execute.
+   * @param parameterObject The parameter object (e.g. JavaBean, Map, XML etc.).
+   * @param keyProp         The property to be used as the key in the Map.
+   * @return A Map keyed by keyProp with values being the result object instance.
+   * @throws java.sql.SQLException If an error occurs.
+   */
+  Map queryForMap(String id, Object parameterObject, String keyProp) throws SQLException;
+
+  /**
+   * Executes a mapped SQL SELECT statement that returns data to populate
+   * a number of result objects from which one property will be keyed into a Map.
+   * <p/>
+   * The parameter object is generally used to supply the input
+   * data for the WHERE clause parameter(s) of the SELECT statement.
+   *
+   * @param id              The name of the statement to execute.
+   * @param parameterObject The parameter object (e.g. JavaBean, Map, XML etc.).
+   * @param keyProp         The property to be used as the key in the Map.
+   * @param valueProp       The property to be used as the value in the Map.
+   * @return A Map keyed by keyProp with values of valueProp.
+   * @throws java.sql.SQLException If an error occurs.
+   */
+  Map queryForMap(String id, Object parameterObject, String keyProp, String valueProp) throws SQLException;
+
+  /**
+   * Starts a batch in which update statements will be cached before being sent to
+   * the database all at once. This can improve overall performance of updates update
+   * when dealing with numerous updates (e.g. inserting 1:M related data).
+   *
+   * @throws java.sql.SQLException If the batch could not be started.
+   */
+  void startBatch() throws SQLException;
+
+  /**
+   * Executes (flushes) all statements currently batched.
+   *
+   * @return the number of rows updated in the batch
+   * @throws java.sql.SQLException If the batch could not be executed or if any of the statements
+   *                               fails.
+   */
+  int executeBatch() throws SQLException;
+
+  /**
+   * Executes (flushes) all statements currently batched.
+   *
+   * @return a List of BatchResult objects.  There will be one element in the
+   *         list for each sub-batch executed.  A sub-batch is created by adding a statement
+   *         to the batch that does not equal the prior statement.
+   * @throws java.sql.SQLException if a database access error occurs, or the drive
+   *                               does not support batch statements
+   * @throws BatchException        if the driver throws BatchUpdateException
+   * @see com.ibatis.sqlmap.engine.execution.BatchException
+   */
+  List executeBatchDetailed() throws SQLException, BatchException;
+
+  PaginatedList queryForPaginatedList(String id, Object param, int pageSize) throws SQLException;
+
+  PaginatedList queryForPaginatedList(String id, int pageSize) throws SQLException;
+
+}

Added: ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/client/SqlMapSession.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/client/SqlMapSession.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/client/SqlMapSession.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/client/SqlMapSession.java Thu Aug  7 16:21:46 2008
@@ -0,0 +1,18 @@
+package com.ibatis.sqlmap.client;
+
+/**
+ * A single threaded session for working with your SQL Maps.  This interface inherits transaction control
+ * and execution methods from the SqlMapTransactionManager and SqlMapExecutor interfaces.
+ *
+ * @see SqlMapClient
+ * @see com.ibatis.sqlmap.client.SqlMapSession
+ * @see SqlMapExecutor
+ */
+public interface SqlMapSession extends SqlMapExecutor, SqlMapTransactionManager {
+
+  /**
+   * Closes the session
+   */
+  public void close();
+
+}

Added: ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/client/SqlMapTransactionManager.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/client/SqlMapTransactionManager.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/client/SqlMapTransactionManager.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/client/SqlMapTransactionManager.java Thu Aug  7 16:21:46 2008
@@ -0,0 +1,126 @@
+package com.ibatis.sqlmap.client;
+
+import javax.sql.DataSource;
+import java.sql.*;
+
+/**
+ * This interface declares methods for demarcating SQL Map transactions.
+ *
+ * @see com.ibatis.sqlmap.client.SqlMapSession
+ * @see SqlMapClient
+ */
+public interface SqlMapTransactionManager {
+
+  /**
+   * Demarcates the beginning of a transaction scope.  Transactions must be properly
+   * committed or rolled back to be effective.  Use the following pattern when working
+   * with transactions:
+   * <pre>
+   * try {
+   *   sqlMap.startTransaction();
+   *   // do work
+   *   sqlMap.commitTransaction();
+   * } finally {
+   *   sqlMap.endTransaction();
+   * }
+   * </pre>
+   * <p/>
+   * Always call endTransaction() once startTransaction() has been called.
+   *
+   * @throws java.sql.SQLException If an error occurs while starting the transaction, or
+   *                               the transaction could not be started.
+   */
+  public void startTransaction() throws SQLException;
+
+
+  /**
+   * Demarcates the beginning of a transaction scope using the specified transaction
+   * isolation.  Transactions must be properly committed or rolled back to be effective.
+   * Use the following pattern when working with transactions:
+   * <pre>
+   * try {
+   *   sqlMap.startTransaction(Connection.TRANSACTION_REPEATABLE_READ);
+   *   // do work
+   *   sqlMap.commitTransaction();
+   * } finally {
+   *   sqlMap.endTransaction();
+   * }
+   * </pre>
+   * <p/>
+   * Always call endTransaction() once startTransaction() has been called.
+   *
+   * @throws java.sql.SQLException If an error occurs while starting the transaction, or
+   *                               the transaction could not be started.
+   */
+  public void startTransaction(int transactionIsolation) throws SQLException;
+
+  /**
+   * Commits the currently started transaction.
+   *
+   * @throws java.sql.SQLException If an error occurs while committing the transaction, or
+   *                               the transaction could not be committed.
+   */
+  public void commitTransaction() throws SQLException;
+
+  /**
+   * Ends a transaction and rolls back if necessary.  If the transaction has
+   * been started, but not committed, it will be rolled back upon calling
+   * endTransaction().
+   *
+   * @throws java.sql.SQLException If an error occurs during rollback or the transaction could
+   *                               not be ended.
+   */
+  public void endTransaction() throws SQLException;
+
+  /**
+   * Allows the developer to easily use an externally supplied connection
+   * when executing statements.
+   * <p/>
+   * <b>Important:</b> Using a user supplied connection basically sidesteps the transaction manager,
+   * so you are responsible for appropriately.  Here's a (very) simple example (throws SQLException):
+   * <pre>
+   * try {
+   *   Connection connection = dataSource.getConnection();
+   *   sqlMap.setUserConnection(connection);
+   *   // do work
+   *   connection.commit();
+   * } catch (SQLException e) {
+   *     try {
+   *       if (connection != null) commit.rollback();
+   *     } catch (SQLException ignored) {
+   *       // generally ignored
+   *     }
+   *     throw e;  // rethrow the exception
+   * } finally {
+   *   try {
+   *     if (connection != null) connection.close();
+   *   } catch (SQLException ignored) {
+   *     // generally ignored
+   *   }
+   * }
+   * </pre>
+   *
+   * @param connnection
+   * @throws java.sql.SQLException
+   */
+  public void setUserConnection(Connection connnection) throws SQLException;
+
+  /**
+   * Returns the current connection in use.  If no connection exists null will
+   * be returned. There may be no connection if no transaction has been started,
+   * and if no user provided connection has been set.
+   *
+   * @return The current connection or null.
+   * @throws java.sql.SQLException
+   */
+  public Connection getCurrentConnection() throws SQLException;
+
+  /**
+   * Returns the DataSource instance currently being used by the SqlMapSession.
+   *
+   * @return The DataSource instance currently being used by the SqlMapSession.
+   */
+  public DataSource getDataSource();
+
+
+}

Added: ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/client/event/RowHandler.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/client/event/RowHandler.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/client/event/RowHandler.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/client/event/RowHandler.java Thu Aug  7 16:21:46 2008
@@ -0,0 +1,30 @@
+package com.ibatis.sqlmap.client.event;
+
+
+/**
+ * Event handler for row by row processing.
+ * <p/>
+ * The RowHandler interface is used by the SqlMapSession.queryWithRowHandler() method.
+ * Generally a RowHandler implementation will perform some row-by-row processing logic
+ * in cases where there are too many rows to efficiently load into memory.
+ * <p/>
+ * Example:
+ * <pre>
+ * sqlMap.queryWithRowHandler ("findAllEmployees", null, new MyRowHandler()));
+ * </pre>
+ */
+public interface RowHandler {
+
+  /**
+   * Handles a single row of a result set.
+   * <p/>
+   * This method will be called for each row in a result set.  For each row the result map
+   * will be applied to build the value object, which is then passed in as the valueObject
+   * parameter.
+   *
+   * @param valueObject The object representing a single row from the query.
+   * @see com.ibatis.sqlmap.client.SqlMapSession
+   */
+  void handleRow(Object valueObject);
+
+}

Added: ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/client/extensions/ParameterSetter.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/client/extensions/ParameterSetter.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/client/extensions/ParameterSetter.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/client/extensions/ParameterSetter.java Thu Aug  7 16:21:46 2008
@@ -0,0 +1,277 @@
+package com.ibatis.sqlmap.client.extensions;
+
+import java.io.*;
+import java.math.BigDecimal;
+import java.net.URL;
+import java.sql.*;
+import java.util.Calendar;
+
+/**
+ * Allows parameters to be set on the underlying prepared statement.
+ * TypeHandlerCallback implementations use this interface to
+ * process values before they are set on the prepared statement.
+ * Each of these methods has a corresponding method on the
+ * PreparedStatement class, the only difference being
+ * that there is no need to specify the parameter index with these
+ * methods.
+ * <p/>
+ * <b>NOTE:</b> There is no need to implement this.  The implementation
+ * will be passed into the TypeHandlerCallback automatically.
+ */
+public interface ParameterSetter {
+
+  /**
+   * Set an array on the underlying prepared statement
+   *
+   * @param x - the array to set
+   * @throws java.sql.SQLException - thrown if the underlying prepared statement throws it
+   */
+  public void setArray(Array x) throws SQLException;
+
+  /**
+   * Set an InputStream on the underlying prepared statement
+   *
+   * @param x      - the InputStream
+   * @param length - the length of the InputStream
+   * @throws java.sql.SQLException - thrown if the underlying prepared statement throws it
+   */
+  public void setAsciiStream(InputStream x, int length) throws SQLException;
+
+  /**
+   * Set an on the underlying prepared statement
+   *
+   * @param x
+   * @throws java.sql.SQLException - thrown if the underlying prepared statement throws it
+   */
+  public void setBigDecimal(BigDecimal x) throws SQLException;
+
+  /**
+   * Set an InputStream on the underlying prepared statement
+   *
+   * @param x      - the InputStream
+   * @param length - the length of the InputStream
+   * @throws java.sql.SQLException - thrown if the underlying prepared statement throws it
+   */
+  public void setBinaryStream(InputStream x, int length) throws SQLException;
+
+  /**
+   * Set a blob on the underlying prepared statement
+   *
+   * @param x - the blob
+   * @throws java.sql.SQLException - thrown if the underlying prepared statement throws it
+   */
+  public void setBlob(Blob x) throws SQLException;
+
+  /**
+   * Set a boolean on the underlying prepared statement
+   *
+   * @param x - the boolean
+   * @throws java.sql.SQLException - thrown if the underlying prepared statement throws it
+   */
+  public void setBoolean(boolean x) throws SQLException;
+
+  /**
+   * Set a byte on the underlying prepared statement
+   *
+   * @param x - the byte
+   * @throws java.sql.SQLException - thrown if the underlying prepared statement throws it
+   */
+  public void setByte(byte x) throws SQLException;
+
+  /**
+   * Set a byte array on the underlying prepared statement
+   *
+   * @param x - the byte[]
+   * @throws java.sql.SQLException - thrown if the underlying prepared statement throws it
+   */
+  public void setBytes(byte x[]) throws SQLException;
+
+  /**
+   * Set a character stream on the underlying prepared statement
+   *
+   * @param reader - the reader
+   * @param length - the length of the reader
+   * @throws java.sql.SQLException - thrown if the underlying prepared statement throws it
+   */
+  public void setCharacterStream(Reader reader, int length) throws SQLException;
+
+  /**
+   * Set a clob on the underlying prepared statement
+   *
+   * @param x - the clob
+   * @throws java.sql.SQLException - thrown if the underlying prepared statement throws it
+   */
+  public void setClob(Clob x) throws SQLException;
+
+  /**
+   * Set a date on the underlying prepared statement
+   *
+   * @param x - the date
+   * @throws java.sql.SQLException - thrown if the underlying prepared statement throws it
+   */
+  public void setDate(Date x) throws SQLException;
+
+  /**
+   * Set a date with a calendar on the underlying prepared statement
+   *
+   * @param x   - the date
+   * @param cal - the calendar
+   * @throws java.sql.SQLException - thrown if the underlying prepared statement throws it
+   */
+  public void setDate(Date x, Calendar cal) throws SQLException;
+
+  /**
+   * Set a double on the underlying prepared statement
+   *
+   * @param x - the double
+   * @throws java.sql.SQLException - thrown if the underlying prepared statement throws it
+   */
+  public void setDouble(double x) throws SQLException;
+
+  /**
+   * Set a float on the underlying prepared statement
+   *
+   * @param x the float
+   * @throws java.sql.SQLException - thrown if the underlying prepared statement throws it
+   */
+  public void setFloat(float x) throws SQLException;
+
+  /**
+   * Set an integer on the underlying prepared statement
+   *
+   * @param x - the int
+   * @throws java.sql.SQLException - thrown if the underlying prepared statement throws it
+   */
+  public void setInt(int x) throws SQLException;
+
+  /**
+   * Set a long on the underlying prepared statement
+   *
+   * @param x - the long
+   * @throws java.sql.SQLException - thrown if the underlying prepared statement throws it
+   */
+  public void setLong(long x) throws SQLException;
+
+  /**
+   * Set a null on the underlying prepared statement
+   *
+   * @param sqlType - the type for the null value
+   * @throws java.sql.SQLException - thrown if the underlying prepared statement throws it
+   */
+  public void setNull(int sqlType) throws SQLException;
+
+  /**
+   * Set a null on the underlying prepared statement
+   *
+   * @param sqlType  -  the type for the null value
+   * @param typeName -  the name of the type
+   * @throws java.sql.SQLException - thrown if the underlying prepared statement throws it
+   */
+  public void setNull(int sqlType, String typeName) throws SQLException;
+
+  /**
+   * Set an object on the underlying prepared statement
+   *
+   * @param x - the object to set
+   * @throws java.sql.SQLException - thrown if the underlying prepared statement throws it
+   */
+  public void setObject(Object x) throws SQLException;
+
+  /**
+   * Set an object on the underlying prepared statement
+   *
+   * @param x             - the object to set
+   * @param targetSqlType - the sql type of the object
+   * @throws java.sql.SQLException - thrown if the underlying prepared statement throws it
+   */
+  public void setObject(Object x, int targetSqlType) throws SQLException;
+
+  /**
+   * Set an object on the underlying prepared statement
+   *
+   * @param x             - the object to set
+   * @param targetSqlType - the sql type of the object
+   * @param scale         - the scale of the object
+   * @throws java.sql.SQLException - thrown if the underlying prepared statement throws it
+   */
+  public void setObject(Object x, int targetSqlType, int scale) throws SQLException;
+
+  /**
+   * Set a reference on the underlying prepared statement
+   *
+   * @param x - the reference to set
+   * @throws java.sql.SQLException - thrown if the underlying prepared statement throws it
+   */
+  public void setRef(Ref x) throws SQLException;
+
+  /**
+   * Set a short on the underlying prepared statement
+   *
+   * @param x - the short to set
+   * @throws java.sql.SQLException - thrown if the underlying prepared statement throws it
+   */
+  public void setShort(short x) throws SQLException;
+
+  /**
+   * Set a string on the underlying prepared statement
+   *
+   * @param x - the string to set
+   * @throws java.sql.SQLException - thrown if the underlying prepared statement throws it
+   */
+  public void setString(String x) throws SQLException;
+
+  /**
+   * Set a time on the underlying prepared statement
+   *
+   * @param x - the time to set
+   * @throws java.sql.SQLException - thrown if the underlying prepared statement throws it
+   */
+  public void setTime(Time x) throws SQLException;
+
+  /**
+   * Set a time with a calendar on the underlying prepared statement
+   *
+   * @param x   - the time to set
+   * @param cal - the calendar to use
+   * @throws java.sql.SQLException - thrown if the underlying prepared statement throws it
+   */
+  public void setTime(Time x, Calendar cal) throws SQLException;
+
+  /**
+   * Set a timestamp on the underlying prepared statement
+   *
+   * @param x - the timestamp to set
+   * @throws java.sql.SQLException - thrown if the underlying prepared statement throws it
+   */
+  public void setTimestamp(Timestamp x) throws SQLException;
+
+  /**
+   * Set a timestamp on the underlying prepared statement
+   *
+   * @param x   - the timestamp to set
+   * @param cal - the calendar to use
+   * @throws java.sql.SQLException - thrown if the underlying prepared statement throws it
+   */
+  public void setTimestamp(Timestamp x, Calendar cal) throws SQLException;
+
+  /**
+   * Set a URL on the underlying prepared statement
+   *
+   * @param x - the url to set
+   * @throws java.sql.SQLException - thrown if the underlying prepared statement throws it
+   */
+  public void setURL(URL x) throws SQLException;
+
+  /**
+   * Returns the underlying prepared statement...be careful!
+   */
+  public PreparedStatement getPreparedStatement();
+
+  /**
+   * Returns the index of the parameter being set.
+   *
+   * @return the parameter index used to set the value in the underlying
+   *         PreparedStatement
+   */
+  public int getParameterIndex();
+}

Added: ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/client/extensions/ResultGetter.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/client/extensions/ResultGetter.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/client/extensions/ResultGetter.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/client/extensions/ResultGetter.java Thu Aug  7 16:21:46 2008
@@ -0,0 +1,243 @@
+package com.ibatis.sqlmap.client.extensions;
+
+import java.math.BigDecimal;
+import java.net.URL;
+import java.sql.*;
+import java.sql.Date;
+import java.util.*;
+
+/**
+ * Allows values to be retrieved from the underlying result set.
+ * TypeHandlerCallback implementations use this interface to
+ * get values that they can subsequently manipulate before
+ * having them returned.  Each of these methods has a corresponding
+ * method on the ResultSet (or CallableStatement) class, the only
+ * difference being that there is no need to specify the column name
+ * or index with these methods.
+ * <p/>
+ * <b>NOTE:</b> There is no need to implement this.  The implementation
+ * will be passed into the TypeHandlerCallback automatically.
+ */
+public interface ResultGetter {
+
+  /**
+   * Gets an array from the underlying result set
+   *
+   * @return - the array
+   * @throws java.sql.SQLException - if the underlying result set throws an exception
+   */
+  public Array getArray() throws SQLException;
+
+  /**
+   * Gets a BigDecimal from the underlying result set
+   *
+   * @return - the BigDecimal
+   * @throws java.sql.SQLException - if the underlying result set throws an exception
+   */
+  public BigDecimal getBigDecimal() throws SQLException;
+
+  /**
+   * Gets a Blob from the underlying result set
+   *
+   * @return - the Blob
+   * @throws java.sql.SQLException - if the underlying result set throws an exception
+   */
+  public Blob getBlob() throws SQLException;
+
+  /**
+   * Gets a boolean from the underlying result set
+   *
+   * @return - the boolean
+   * @throws java.sql.SQLException - if the underlying result set throws an exception
+   */
+  public boolean getBoolean() throws SQLException;
+
+  /**
+   * Gets a byte from the underlying result set
+   *
+   * @return - the byte
+   * @throws java.sql.SQLException - if the underlying result set throws an exception
+   */
+  public byte getByte() throws SQLException;
+
+  /**
+   * Gets a byte[] from the underlying result set
+   *
+   * @return - the byte[]
+   * @throws java.sql.SQLException - if the underlying result set throws an exception
+   */
+  public byte[] getBytes() throws SQLException;
+
+  /**
+   * Gets a Clob from the underlying result set
+   *
+   * @return - the Clob
+   * @throws java.sql.SQLException - if the underlying result set throws an exception
+   */
+  public Clob getClob() throws SQLException;
+
+  /**
+   * Gets a Date from the underlying result set
+   *
+   * @return - the Date
+   * @throws java.sql.SQLException - if the underlying result set throws an exception
+   */
+  public Date getDate() throws SQLException;
+
+  /**
+   * Gets a Date from the underlying result set using a calendar
+   *
+   * @param cal - the Calendar
+   * @return - the Date
+   * @throws java.sql.SQLException - if the underlying result set throws an exception
+   */
+  public Date getDate(Calendar cal) throws SQLException;
+
+  /**
+   * Gets a double from the underlying result set
+   *
+   * @return - the double
+   * @throws java.sql.SQLException - if the underlying result set throws an exception
+   */
+  public double getDouble() throws SQLException;
+
+  /**
+   * Gets a float from the underlying result set
+   *
+   * @return - the float
+   * @throws java.sql.SQLException - if the underlying result set throws an exception
+   */
+  public float getFloat() throws SQLException;
+
+  /**
+   * Gets an int from the underlying result set
+   *
+   * @return - the int
+   * @throws java.sql.SQLException - if the underlying result set throws an exception
+   */
+  public int getInt() throws SQLException;
+
+  /**
+   * Gets a long from the underlying result set
+   *
+   * @return - the long
+   * @throws java.sql.SQLException - if the underlying result set throws an exception
+   */
+  public long getLong() throws SQLException;
+
+  /**
+   * Gets an Object from the underlying result set
+   *
+   * @return - the Object
+   * @throws java.sql.SQLException - if the underlying result set throws an exception
+   */
+  public Object getObject() throws SQLException;
+
+  /**
+   * Gets an Object from the underlying result set using a Map
+   *
+   * @param map - the Map
+   * @return - the Object
+   * @throws java.sql.SQLException - if the underlying result set throws an exception
+   */
+  public Object getObject(Map map) throws SQLException;
+
+  /**
+   * Gets a Ref from the underlying result set
+   *
+   * @return - the Ref
+   * @throws java.sql.SQLException - if the underlying result set throws an exception
+   */
+  public Ref getRef() throws SQLException;
+
+  /**
+   * Gets a short from the underlying result set
+   *
+   * @return - the short
+   * @throws java.sql.SQLException - if the underlying result set throws an exception
+   */
+  public short getShort() throws SQLException;
+
+  /**
+   * Gets a String from the underlying result set
+   *
+   * @return - the String
+   * @throws java.sql.SQLException - if the underlying result set throws an exception
+   */
+  public String getString() throws SQLException;
+
+  /**
+   * Gets a Time from the underlying result set
+   *
+   * @return - the Time
+   * @throws java.sql.SQLException - if the underlying result set throws an exception
+   */
+  public Time getTime() throws SQLException;
+
+  /**
+   * Gets a Time from the underlying result set using a Calendar
+   *
+   * @param cal - the Calendar
+   * @return - the Time
+   * @throws java.sql.SQLException - if the underlying result set throws an exception
+   */
+  public Time getTime(Calendar cal) throws SQLException;
+
+  /**
+   * Gets a Timestamp from the underlying result set
+   *
+   * @return - the Timestamp
+   * @throws java.sql.SQLException - if the underlying result set throws an exception
+   */
+  public Timestamp getTimestamp() throws SQLException;
+
+  /**
+   * Gets a Timestamp from the underlying result set
+   *
+   * @param cal - the Calendar
+   * @return - the Timestamp
+   * @throws java.sql.SQLException - if the underlying result set throws an exception
+   */
+  public Timestamp getTimestamp(Calendar cal) throws SQLException;
+
+  /**
+   * Gets a URL from the underlying result set
+   *
+   * @return - the URL
+   * @throws java.sql.SQLException - if the underlying result set throws an exception
+   */
+  public URL getURL() throws SQLException;
+
+  /**
+   * Tells if the field was null
+   *
+   * @return - true if it was null
+   * @throws java.sql.SQLException - if the underlying result set throws an exception
+   */
+  public boolean wasNull() throws SQLException;
+
+  /**
+   * Returns the underlying ResultSet...be careful!
+   *
+   * @return a ResultSet instance.
+   */
+  public ResultSet getResultSet();
+
+  /**
+   * Returns the name of the column being got in the underlying ResultSet.
+   * May be <code>null</code> in which case the <code>getColumnIndex</code>
+   * method should be used.
+   *
+   * @return the column name (may be null)
+   */
+  public String getColumnName();
+
+  /**
+   * Returns the index of the column being got in the underlying ResultSet.
+   * Only use this method if the value returned from <code>getColumnName</code>
+   * is null.
+   *
+   * @return the index of the column (if zero then use the column name)
+   */
+  public int getColumnIndex();
+}

Added: ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/client/extensions/TypeHandlerCallback.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/client/extensions/TypeHandlerCallback.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/client/extensions/TypeHandlerCallback.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/client/extensions/TypeHandlerCallback.java Thu Aug  7 16:21:46 2008
@@ -0,0 +1,102 @@
+package com.ibatis.sqlmap.client.extensions;
+
+import java.sql.SQLException;
+
+/**
+ * A simple interface for implementing custom type handlers.
+ * <p/>
+ * Using this interface, you can implement a type handler that
+ * will perform customized processing before parameters are set
+ * on a PreparedStatement and after values are retrieved from
+ * a ResultSet.  Using a custom type handler you can extend
+ * the framework to handle types that are not supported, or
+ * handle supported types in a different way.  For example,
+ * you might use a custom type handler to implement proprietary
+ * BLOB support (e.g. Oracle), or you might use it to handle
+ * booleans using "Y" and "N" instead of the more typical 0/1.
+ * <p/>
+ * <b>EXAMPLE</b>
+ * <p>Here's a simple example of a boolean handler that uses "Yes" and "No".</p>
+ * <pre>
+ * public class YesNoBoolTypeHandlerCallback implements TypeHandlerCallback {
+ * <p/>
+ *   private static final String YES = "Yes";
+ *   private static final String NO = "No";
+ * <p/>
+ *   public Object getResult(ResultGetter getter) throws SQLException {
+ *     String s = getter.getString();
+ *     if (YES.equalsIgnoreCase(s)) {
+ *       return new Boolean (true);
+ *     } else if (NO.equalsIgnoreCase(s)) {
+ *       return new Boolean (false);
+ *     } else {
+ *       throw new SQLException ("Unexpected value " + s + " found where "+YES+" or "+NO+" was expected.");
+ *     }
+ *   }
+ * <p/>
+ *   public void setParameter(ParameterSetter setter, Object parameter) throws SQLException {
+ *     boolean b = ((Boolean)parameter).booleanValue();
+ *     if (b) {
+ *       setter.setString(YES);
+ *     } else {
+ *       setter.setString(NO);
+ *     }
+ *   }
+ * <p/>
+ *   public Object valueOf(String s) {
+ *     if (YES.equalsIgnoreCase(s)) {
+ *       return new Boolean (true);
+ *     } else if (NO.equalsIgnoreCase(s)) {
+ *       return new Boolean (false);
+ *     } else {
+ *       throw new SQLException ("Unexpected value " + s + " found where "+YES+" or "+NO+" was expected.");
+ *     }
+ *   }
+ * <p/>
+ * }
+ * </pre>
+ */
+public interface TypeHandlerCallback {
+
+  /**
+   * Performs processing on a value before it is used to set
+   * the parameter of a PreparedStatement.
+   *
+   * @param setter    The interface for setting the value on the PreparedStatement.
+   * @param parameter The value to be set.
+   * @throws java.sql.SQLException If any error occurs.
+   */
+  public void setParameter(ParameterSetter setter, Object parameter)
+      throws SQLException;
+
+  /**
+   * Performs processing on a value before after it has been retrieved
+   * from a ResultSet.
+   *
+   * @param getter The interface for getting the value from the ResultSet.
+   * @return The processed value.
+   * @throws java.sql.SQLException If any error occurs.
+   */
+  public Object getResult(ResultGetter getter)
+      throws SQLException;
+
+  /**
+   * Casts the string representation of a value into a type recognized by
+   * this type handler.  This method is used to translate nullValue values
+   * into types that can be appropriately compared.  If your custom type handler
+   * cannot support nullValues, or if there is no reasonable string representation
+   * for this type (e.g. File type), you can simply return the String representation
+   * as it was passed in.  It is not recommended to return null, unless null was passed
+   * in.
+   *
+   * @param s A string representation of a valid value for this type.
+   * @return One of the following:
+   *         <ol>
+   *         <li>the casted repersentation of the String value,</li>
+   *         <li>the string as is,</li>
+   *         <li>null, only if null was passed in.</li>
+   *         </ol>
+   */
+  public Object valueOf(String s);
+
+}

Added: ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/builder/DynamicSqlSource.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/builder/DynamicSqlSource.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/builder/DynamicSqlSource.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/builder/DynamicSqlSource.java Thu Aug  7 16:21:46 2008
@@ -0,0 +1,115 @@
+package com.ibatis.sqlmap.engine.builder;
+
+import com.ibatis.sqlmap.engine.mapping.sql.SqlText;
+import com.ibatis.sqlmap.engine.mapping.sql.dynamic.DynamicSql;
+import com.ibatis.sqlmap.engine.mapping.sql.dynamic.elements.*;
+import org.apache.ibatis.mapping.Configuration;
+import org.apache.ibatis.mapping.*;
+import org.apache.ibatis.xml.NodeletContext;
+import org.w3c.dom.*;
+
+import java.util.List;
+
+public class DynamicSqlSource implements SqlSource {
+  private NodeletContext context;
+  private Configuration configuration;
+  private XmlSqlMapConfigParser configParser;
+  private XmlSqlMapParser mapParser;
+
+  public DynamicSqlSource(XmlSqlMapParser mapParser, NodeletContext context) {
+    this.context = context;
+    this.configuration = mapParser.getConfigParser().getConfiguration();
+    this.configParser = mapParser.getConfigParser();
+    this.mapParser = mapParser;
+  }
+
+  public List<ParameterMapping> getParameterMappings(Object parameterObject) {
+    DynamicSql dynamic = new DynamicSql(configuration);
+    parseDynamicTags(context, dynamic, true);
+    return dynamic.getParameterMappings(parameterObject);
+  }
+
+  public String getSql(Object parameterObject) {
+    DynamicSql dynamic = new DynamicSql(configuration);
+    parseDynamicTags(context, dynamic, true);
+    return dynamic.getSql(parameterObject);
+  }
+
+  private void parseDynamicTags(NodeletContext node, DynamicParent dynamic, boolean postParseRequired) {
+    NodeList children = node.getNode().getChildNodes();
+    for (int i = 0; i < children.getLength(); i++) {
+      NodeletContext child = new NodeletContext(children.item(i), configuration.getVariables());
+      String nodeName = child.getNode().getNodeName();
+      if (child.getNode().getNodeType() == Node.CDATA_SECTION_NODE
+          || child.getNode().getNodeType() == Node.TEXT_NODE) {
+        String data = child.getStringBody("");
+        SqlText sqlText;
+        if (postParseRequired) {
+          sqlText = new SqlText();
+          sqlText.setPostParseRequired(postParseRequired);
+          sqlText.setText(data);
+        } else {
+          InlineParameterMapParser inlineParameterMapParser = new InlineParameterMapParser(configuration);
+          sqlText = inlineParameterMapParser.parseInlineParameterMap(data);
+          sqlText.setPostParseRequired(postParseRequired);
+        }
+        dynamic.addChild(sqlText);
+      } else if ("include".equals(nodeName)) {
+        String refid = child.getStringAttribute("refid");
+        NodeletContext includeNode = configParser.getSqlFragment(refid);
+        if (includeNode == null) {
+          String nsrefid = mapParser.applyNamespace(refid);
+          includeNode = configParser.getSqlFragment(nsrefid);
+          if (includeNode == null) {
+            throw new RuntimeException("Could not find SQL statement to include with refid '" + refid + "'");
+          }
+        }
+        parseDynamicTags(includeNode, dynamic, postParseRequired);
+      } else {
+        SqlTagHandler handler = SqlTagHandlerFactory.getSqlTagHandler(nodeName);
+        if (handler != null) {
+          SqlTag tag = new SqlTag();
+          tag.setName(nodeName);
+          tag.setHandler(handler);
+
+          tag.setPrependAttr(child.getStringAttribute("prepend"));
+          tag.setPropertyAttr(child.getStringAttribute("property"));
+          tag.setRemoveFirstPrepend(child.getStringAttribute("removeFirstPrepend"));
+
+          tag.setOpenAttr(child.getStringAttribute("open"));
+          tag.setCloseAttr(child.getStringAttribute("close"));
+
+          tag.setComparePropertyAttr(child.getStringAttribute("compareProperty"));
+          tag.setCompareValueAttr(child.getStringAttribute("compareValue"));
+          tag.setConjunctionAttr(child.getStringAttribute("conjunction"));
+
+          if (handler instanceof IterateTagHandler
+              && (tag.getPropertyAttr() == null || "".equals(tag.getPropertyAttr()))) {
+            tag.setPropertyAttr("_collection");
+          }
+
+          // an iterate ancestor requires a post parse
+
+          if (dynamic instanceof SqlTag) {
+            SqlTag parentSqlTag = (SqlTag) dynamic;
+            if (parentSqlTag.isPostParseRequired() ||
+                tag.getHandler() instanceof IterateTagHandler) {
+              tag.setPostParseRequired(true);
+            }
+          } else if (dynamic instanceof DynamicSql) {
+            if (tag.getHandler() instanceof IterateTagHandler) {
+              tag.setPostParseRequired(true);
+            }
+          }
+
+          dynamic.addChild(tag);
+
+          if (child.getNode().hasChildNodes()) {
+            parseDynamicTags(child, tag, tag.isPostParseRequired());
+          }
+        }
+      }
+    }
+  }
+
+}

Added: ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/builder/FlushCacheInterceptor.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/builder/FlushCacheInterceptor.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/builder/FlushCacheInterceptor.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/builder/FlushCacheInterceptor.java Thu Aug  7 16:21:46 2008
@@ -0,0 +1,43 @@
+package com.ibatis.sqlmap.engine.builder;
+
+import org.apache.ibatis.cache.Cache;
+import org.apache.ibatis.executor.Executor;
+import org.apache.ibatis.executor.result.ResultHandler;
+import org.apache.ibatis.mapping.MappedStatement;
+import org.apache.ibatis.plugin.*;
+
+import java.util.*;
+
+@Intercepts({
+@Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class}),
+@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, int.class, int.class, ResultHandler.class})
+    })
+public class FlushCacheInterceptor implements Interceptor {
+
+  private Map<String, Set<Cache>> flushCacheMap = new HashMap<String, Set<Cache>>();
+
+  public Object intercept(Invocation invocation) throws Throwable {
+    MappedStatement statement = (MappedStatement) invocation.getArgs()[0];
+    Set<Cache> cachesToFlush = flushCacheMap.get(statement.getId());
+    if (cachesToFlush != null) {
+      for (Cache c : cachesToFlush) {
+        c.clear();
+      }
+    }
+    return invocation.proceed();
+  }
+
+  public Object plugin(Object target) {
+    return Plugin.wrap(target, this);
+  }
+
+  public void addFlushOnExecute(String statementId, Cache cache) {
+    Set<Cache> cachesToFlush = flushCacheMap.get(statementId);
+    if (cachesToFlush == null) {
+      cachesToFlush = new HashSet<Cache>();
+      flushCacheMap.put(statementId, cachesToFlush);
+    }
+    cachesToFlush.add(cache);
+  }
+
+}

Added: ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/builder/Ibatis2Configuration.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/builder/Ibatis2Configuration.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/builder/Ibatis2Configuration.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/builder/Ibatis2Configuration.java Thu Aug  7 16:21:46 2008
@@ -0,0 +1,78 @@
+package com.ibatis.sqlmap.engine.builder;
+
+import com.ibatis.sqlmap.engine.datasource.*;
+import com.ibatis.sqlmap.engine.transaction.TransactionManager;
+import com.ibatis.sqlmap.engine.transaction.external.ExternalTransactionConfig;
+import com.ibatis.sqlmap.engine.transaction.jdbc.JdbcTransactionConfig;
+import com.ibatis.sqlmap.engine.transaction.jta.JtaTransactionConfig;
+import org.apache.ibatis.cache.impl.*;
+import org.apache.ibatis.mapping.Configuration;
+
+import javax.sql.DataSource;
+import java.util.*;
+
+public class Ibatis2Configuration extends Configuration {
+
+  private TransactionManager transactionManager;
+
+  private DataSource dataSource;
+
+
+  private FlushCacheInterceptor flushCachePlugin;
+
+  private Map<String, Boolean> postSelectKeyMap;
+
+  public Ibatis2Configuration() {
+    setGeneratedKeysEnabled(false);
+    this.flushCachePlugin = new FlushCacheInterceptor();
+    this.addInterceptor(flushCachePlugin);
+    this.postSelectKeyMap = new HashMap<String, Boolean>();
+    registerDefaultTypeAliases();
+  }
+
+  private void registerDefaultTypeAliases() {
+    // TRANSACTION ALIASES
+    this.getTypeAliasRegistry().registerAlias("JDBC", JdbcTransactionConfig.class.getName());
+    this.getTypeAliasRegistry().registerAlias("JTA", JtaTransactionConfig.class.getName());
+    this.getTypeAliasRegistry().registerAlias("EXTERNAL", ExternalTransactionConfig.class.getName());
+
+    // DATA SOURCE ALIASES
+    this.getTypeAliasRegistry().registerAlias("SIMPLE", SimpleDataSourceFactory.class.getName());
+    this.getTypeAliasRegistry().registerAlias("DBCP", DbcpDataSourceFactory.class.getName());
+    this.getTypeAliasRegistry().registerAlias("JNDI", JndiDataSourceFactory.class.getName());
+
+    // CACHE ALIASES
+    this.getTypeAliasRegistry().registerAlias("FIFO", FifoCache.class.getName());
+    this.getTypeAliasRegistry().registerAlias("LRU", LruCache.class.getName());
+    this.getTypeAliasRegistry().registerAlias("MEMORY", WeakCache.class.getName());
+  }
+
+  public TransactionManager getTransactionManager() {
+    return transactionManager;
+  }
+
+  public void setTransactionManager(TransactionManager transactionManager) {
+    this.transactionManager = transactionManager;
+  }
+
+  public DataSource getDataSource() {
+    return dataSource;
+  }
+
+  public void setDataSource(DataSource dataSource) {
+    this.dataSource = dataSource;
+  }
+
+  public FlushCacheInterceptor getFlushCachePlugin() {
+    return flushCachePlugin;
+  }
+
+  public void setPostSelectKey(String statement, boolean postSelectKey) {
+    this.postSelectKeyMap.put(statement, postSelectKey);
+  }
+
+  public boolean isPostSelectKey(String statement) {
+    Boolean postSelectKey = postSelectKeyMap.get(statement);
+    return postSelectKey == null || postSelectKey;
+  }
+}

Added: ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/builder/InlineParameterMapParser.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/builder/InlineParameterMapParser.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/builder/InlineParameterMapParser.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/builder/InlineParameterMapParser.java Thu Aug  7 16:21:46 2008
@@ -0,0 +1,231 @@
+package com.ibatis.sqlmap.engine.builder;
+
+import com.ibatis.sqlmap.client.SqlMapException;
+import com.ibatis.sqlmap.engine.mapping.sql.SqlText;
+import org.apache.ibatis.mapping.Configuration;
+import org.apache.ibatis.io.Resources;
+import org.apache.ibatis.mapping.*;
+import org.apache.ibatis.reflection.MetaClass;
+import org.apache.ibatis.type.*;
+
+import java.util.*;
+
+public class InlineParameterMapParser {
+
+  private TypeHandlerRegistry typeHandlerRegistry;
+  private TypeAliasRegistry typeAliasRegistry;
+
+  private static final String PARAMETER_TOKEN = "#";
+  private static final String PARAM_DELIM = ":";
+
+  public InlineParameterMapParser(Configuration configuration) {
+    this.typeHandlerRegistry = configuration.getTypeHandlerRegistry();
+    this.typeAliasRegistry = configuration.getTypeAliasRegistry();
+  }
+
+  public SqlText parseInlineParameterMap(String sqlStatement) {
+    return parseInlineParameterMap(sqlStatement, null);
+  }
+
+  public SqlText parseInlineParameterMap(String sqlStatement, Class parameterClass) {
+
+    String newSql;
+
+    List mappingList = new ArrayList();
+
+    StringTokenizer parser = new StringTokenizer(sqlStatement, PARAMETER_TOKEN, true);
+    StringBuffer newSqlBuffer = new StringBuffer();
+
+    String token;
+    String lastToken = null;
+    while (parser.hasMoreTokens()) {
+      token = parser.nextToken();
+      if (PARAMETER_TOKEN.equals(lastToken)) {
+        if (PARAMETER_TOKEN.equals(token)) {
+          newSqlBuffer.append(PARAMETER_TOKEN);
+          token = null;
+        } else {
+          ParameterMapping mapping;
+          if (token.indexOf(PARAM_DELIM) > -1) {
+            mapping = oldParseMapping(token, parameterClass, typeHandlerRegistry);
+          } else {
+            mapping = newParseMapping(token, parameterClass);
+          }
+
+          mappingList.add(mapping);
+          newSqlBuffer.append("?");
+          token = parser.nextToken();
+          if (!PARAMETER_TOKEN.equals(token)) {
+            throw new SqlMapException("Unterminated inline parameter in mapped statement (" + "statement.getId()" + ").");
+          }
+          token = null;
+        }
+      } else {
+        if (!PARAMETER_TOKEN.equals(token)) {
+          newSqlBuffer.append(token);
+        }
+      }
+
+      lastToken = token;
+    }
+    newSql = newSqlBuffer.toString();
+
+    SqlText sqlText = new SqlText();
+    sqlText.setText(newSql);
+    sqlText.setParameterMappings(mappingList);
+    return sqlText;
+  }
+
+  private ParameterMapping newParseMapping(String token, Class parameterClass) {
+
+    // #propertyName,javaType=string,jdbcType=VARCHAR,mode=IN,nullValue=N/A,handler=string,numericScale=2#
+
+    StringTokenizer paramParser = new StringTokenizer(token, "=, ", false);
+    String propertyName = paramParser.nextToken();
+    TypeHandler typeHandler = null;
+    Class javaType = null;
+    JdbcType jdbcType = null;
+    ParameterMode parameterMode = null;
+    Integer numericScale = null;
+
+    while (paramParser.hasMoreTokens()) {
+      String field = paramParser.nextToken();
+      if (paramParser.hasMoreTokens()) {
+        String value = paramParser.nextToken();
+        if ("javaType".equals(field)) {
+          value = typeAliasRegistry.resolveAlias(value);
+          try {
+            javaType = Class.forName(value);
+          } catch (ClassNotFoundException e) {
+            throw new SqlMapException("Error loading javaType class");
+          }
+        } else if ("jdbcType".equals(field)) {
+          jdbcType = JdbcType.valueOf(value);
+        } else if ("mode".equals(field)) {
+          parameterMode = ParameterMode.valueOf(value);
+        } else if ("nullValue".equals(field)) {
+          throw new UnsupportedOperationException("iBATIS 3 does not support null value substitution.");
+        } else if ("handler".equals(field)) {
+          try {
+            value = typeAliasRegistry.resolveAlias(value);
+            Object impl = Resources.classForName(value).newInstance();
+            typeHandler = ((TypeHandler) impl);
+          } catch (Exception e) {
+            throw new SqlMapException("Error loading class specified by handler field in " + token + ".  Cause: " + e, e);
+          }
+        } else if ("numericScale".equals(field)) {
+          try {
+            numericScale = Integer.valueOf(value);
+            if (numericScale < 0) {
+              throw new SqlMapException("Value specified for numericScale must be greater than or equal to zero");
+            }
+          } catch (NumberFormatException e) {
+            throw new SqlMapException("Value specified for numericScale is not a valid Integer");
+          }
+        } else {
+          throw new SqlMapException("Unrecognized parameter mapping field: '" + field + "' in " + token);
+        }
+      } else {
+        throw new SqlMapException("Incorrect inline parameter map format (missmatched name=value pairs): " + token);
+      }
+    }
+
+    if (typeHandler == null) {
+      if (parameterClass == null) {
+        typeHandler = typeHandlerRegistry.getUnkownTypeHandler();
+      } else {
+        String javaTypeString = javaType == null ? null : javaType.getName();
+        typeHandler = resolveTypeHandler(parameterClass, propertyName, javaTypeString, jdbcType);
+      }
+    }
+
+    if (propertyName != null && propertyName.startsWith("[")) {
+      propertyName = "_collection" + propertyName;
+    }
+
+    ParameterMapping.Builder mapping = new ParameterMapping.Builder(propertyName, typeHandler);
+    mapping.javaType(javaType);
+    mapping.jdbcType(jdbcType);
+    mapping.mode(parameterMode);
+    mapping.numericScale(numericScale);
+
+    return mapping.build();
+  }
+
+  private ParameterMapping oldParseMapping(String token, Class parameterClass, TypeHandlerRegistry typeHandlerRegistry) {
+    if (token.indexOf(PARAM_DELIM) > -1) {
+      StringTokenizer paramParser = new StringTokenizer(token, PARAM_DELIM, true);
+      int n1 = paramParser.countTokens();
+      if (n1 == 3) {
+        String name = paramParser.nextToken();
+        paramParser.nextToken(); //ignore ":"
+        String type = paramParser.nextToken();
+        TypeHandler handler;
+        if (parameterClass == null) {
+          handler = typeHandlerRegistry.getUnkownTypeHandler();
+        } else {
+          handler = resolveTypeHandler(parameterClass, name, null, JdbcType.valueOf(type));
+        }
+        ParameterMapping.Builder mapping = new ParameterMapping.Builder(name, handler);
+        mapping.jdbcType(JdbcType.valueOf(type));
+        return mapping.build();
+      } else if (n1 >= 5) {
+        throw new UnsupportedOperationException("iBATIS 3 does not support null value substitution.");
+      } else {
+        throw new SqlMapException("Incorrect inline parameter map format: " + token);
+      }
+    } else {
+      TypeHandler handler;
+      if (parameterClass == null) {
+        handler = typeHandlerRegistry.getUnkownTypeHandler();
+      } else {
+        handler = resolveTypeHandler(parameterClass, token, null, null);
+      }
+      ParameterMapping.Builder mapping = new ParameterMapping.Builder(token, handler);
+      return mapping.build();
+    }
+  }
+
+  private TypeHandler resolveTypeHandler(Class clazz, String propertyName, String javaType, JdbcType jdbcType) {
+    TypeHandler handler;
+    if (clazz == null) {
+      // Unknown
+      handler = typeHandlerRegistry.getUnkownTypeHandler();
+    } else if (java.util.Map.class.isAssignableFrom(clazz)) {
+      // Map
+      if (javaType == null) {
+        handler = typeHandlerRegistry.getUnkownTypeHandler(); //BUG 1012591 - typeHandlerRegistry.getTypeHandler(java.lang.Object.class, jdbcType);
+      } else {
+        try {
+          javaType = typeAliasRegistry.resolveAlias(javaType);
+          Class javaClass = Resources.classForName(javaType);
+          handler = typeHandlerRegistry.getTypeHandler(javaClass, jdbcType);
+        } catch (Exception e) {
+          throw new SqlMapException("Error.  Could not set TypeHandler.  Cause: " + e, e);
+        }
+      }
+    } else if (typeHandlerRegistry.getTypeHandler(clazz, jdbcType) != null) {
+      // Primitive
+      handler = typeHandlerRegistry.getTypeHandler(clazz, jdbcType);
+    } else {
+      // JavaBean
+      if (javaType == null) {
+
+        Class type = MetaClass.forClass(clazz).getGetterType(propertyName);
+        handler = typeHandlerRegistry.getTypeHandler(type, jdbcType);
+
+      } else {
+        try {
+          javaType = typeAliasRegistry.resolveAlias(javaType);
+          Class javaClass = Resources.classForName(javaType);
+          handler = typeHandlerRegistry.getTypeHandler(javaClass, jdbcType);
+        } catch (Exception e) {
+          throw new SqlMapException("Error.  Could not set TypeHandler.  Cause: " + e, e);
+        }
+      }
+    }
+    return handler;
+  }
+
+
+}