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 [4/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/sqlmap/engine/builder/SimpleSqlSource.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/builder/SimpleSqlSource.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/builder/SimpleSqlSource.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/builder/SimpleSqlSource.java Thu Aug  7 16:21:46 2008
@@ -0,0 +1,72 @@
+package com.ibatis.sqlmap.engine.builder;
+
+import com.ibatis.sqlmap.engine.mapping.sql.SqlText;
+import com.ibatis.sqlmap.engine.mapping.sql.simple.SimpleDynamicSql;
+import com.ibatis.sqlmap.engine.mapping.sql.statik.StaticSql;
+import org.apache.ibatis.mapping.Configuration;
+import org.apache.ibatis.mapping.*;
+import org.apache.ibatis.xml.NodeletContext;
+import org.w3c.dom.*;
+
+import java.util.*;
+
+public class SimpleSqlSource implements SqlSource {
+
+  private Configuration configuration;
+  private XmlSqlMapConfigParser configParser;
+  private XmlSqlMapParser mapParser;
+
+  private String sql = "";
+  private List<ParameterMapping> parameterMappings = new ArrayList<ParameterMapping>();
+
+  public SimpleSqlSource(XmlSqlMapParser mapParser, NodeletContext context) {
+    this.configuration = mapParser.getConfigParser().getConfiguration();
+    this.configParser = mapParser.getConfigParser();
+    this.mapParser = mapParser;
+    this.parseNodes(context);
+  }
+
+  public String getSql(Object parameterObject) {
+    if (SimpleDynamicSql.isSimpleDynamicSql(sql)) {
+      return new SimpleDynamicSql(sql, parameterMappings, configuration.getTypeHandlerRegistry()).getSql(parameterObject);
+    }
+    return new StaticSql(sql).getSql(parameterObject);
+  }
+
+  public List<ParameterMapping> getParameterMappings(Object parameterObject) {
+    return parameterMappings;
+  }
+
+  private void parseNodes(NodeletContext node) {
+    StringBuilder sqlBuffer = new StringBuilder(sql);
+    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();
+        InlineParameterMapParser inlineParameterMapParser = new InlineParameterMapParser(configuration);
+        SqlText sqlText = inlineParameterMapParser.parseInlineParameterMap(data);
+        sqlText.setPostParseRequired(false);
+
+        parameterMappings.addAll(sqlText.getParameterMappings());
+        sqlBuffer.append(sqlText.getText());
+
+      } 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 + "'");
+          }
+        }
+        parseNodes(includeNode);
+      }
+    }
+    sql = sqlBuffer.toString();
+  }
+
+}

Added: ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/builder/SqlMapEntityResolver.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/builder/SqlMapEntityResolver.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/builder/SqlMapEntityResolver.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/builder/SqlMapEntityResolver.java Thu Aug  7 16:21:46 2008
@@ -0,0 +1,72 @@
+package com.ibatis.sqlmap.engine.builder;
+
+import com.ibatis.common.resources.Resources;
+import org.xml.sax.*;
+
+import java.io.*;
+import java.util.*;
+
+/**
+ * Offline entity resolver for the iBATIS DTDs
+ */
+public class SqlMapEntityResolver implements EntityResolver {
+
+  private static final String SQL_MAP_CONFIG_DTD = "com/ibatis/sqlmap/engine/builder/sql-map-config-2.dtd";
+  private static final String SQL_MAP_DTD = "com/ibatis/sqlmap/engine/builder/sql-map-2.dtd";
+
+  private static final Map<String, String> doctypeMap = new HashMap<String, String>();
+
+  static {
+    doctypeMap.put("http://www.ibatis.com/dtd/sql-map-config-2.dtd".toUpperCase(), SQL_MAP_CONFIG_DTD);
+    doctypeMap.put("http://ibatis.apache.org/dtd/sql-map-config-2.dtd".toUpperCase(), SQL_MAP_CONFIG_DTD);
+    doctypeMap.put("-//iBATIS.com//DTD SQL Map Config 2.0//EN".toUpperCase(), SQL_MAP_CONFIG_DTD);
+    doctypeMap.put("-//ibatis.apache.org//DTD SQL Map Config 2.0//EN".toUpperCase(), SQL_MAP_CONFIG_DTD);
+
+    doctypeMap.put("http://www.ibatis.com/dtd/sql-map-2.dtd".toUpperCase(), SQL_MAP_DTD);
+    doctypeMap.put("http://ibatis.apache.org/dtd/sql-map-2.dtd".toUpperCase(), SQL_MAP_DTD);
+    doctypeMap.put("-//iBATIS.com//DTD SQL Map 2.0//EN".toUpperCase(), SQL_MAP_DTD);
+    doctypeMap.put("-//ibatis.apache.org//DTD SQL Map 2.0//EN".toUpperCase(), SQL_MAP_DTD);
+  }
+
+  /**
+   * Converts a public DTD into a local one
+   *
+   * @param publicId Unused but required by EntityResolver interface
+   * @param systemId The DTD that is being requested
+   * @return The InputSource for the DTD
+   * @throws SAXException If anything goes wrong
+   */
+  public InputSource resolveEntity(String publicId, String systemId)
+      throws SAXException {
+
+    if (publicId != null) publicId = publicId.toUpperCase();
+    if (systemId != null) systemId = systemId.toUpperCase();
+
+    InputSource source = null;
+    try {
+      String path = doctypeMap.get(publicId);
+      source = getInputSource(path, source);
+      if (source == null) {
+        path = doctypeMap.get(systemId);
+        source = getInputSource(path, source);
+      }
+    } catch (Exception e) {
+      throw new SAXException(e.toString());
+    }
+    return source;
+  }
+
+  private InputSource getInputSource(String path, InputSource source) {
+    if (path != null) {
+      InputStream in;
+      try {
+        in = Resources.getResourceAsStream(path);
+        source = new InputSource(in);
+      } catch (IOException e) {
+        // ignore, null is ok
+      }
+    }
+    return source;
+  }
+
+}

Added: ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/builder/SqlSourceFactory.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/builder/SqlSourceFactory.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/builder/SqlSourceFactory.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/builder/SqlSourceFactory.java Thu Aug  7 16:21:46 2008
@@ -0,0 +1,57 @@
+package com.ibatis.sqlmap.engine.builder;
+
+import com.ibatis.sqlmap.engine.mapping.sql.dynamic.elements.*;
+import org.apache.ibatis.mapping.SqlSource;
+import org.apache.ibatis.xml.NodeletContext;
+import org.w3c.dom.*;
+
+public class SqlSourceFactory {
+
+  private XmlSqlMapParser mapParser;
+  private XmlSqlMapConfigParser configParser;
+  private Ibatis2Configuration configuration;
+
+  public SqlSourceFactory(XmlSqlMapParser mapParser) {
+    this.mapParser = mapParser;
+    this.configParser = mapParser.getConfigParser();
+    this.configuration = mapParser.getConfigParser().getConfiguration();
+  }
+
+  public SqlSource newSqlSourceIntance(XmlSqlMapParser mapParser, NodeletContext context) {
+    if (isDynamic(context, false)) {
+      return new DynamicSqlSource(mapParser, context);
+    } else {
+      return new SimpleSqlSource(mapParser, context);
+    }
+  }
+
+  private boolean isDynamic(NodeletContext node, boolean isDynamic) {
+    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) {
+      } 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 + "'");
+          }
+        }
+        isDynamic = isDynamic(includeNode, isDynamic);
+      } else {
+        SqlTagHandler handler = SqlTagHandlerFactory.getSqlTagHandler(nodeName);
+        if (handler != null) {
+          isDynamic = true;
+        }
+      }
+    }
+    return isDynamic;
+  }
+
+
+}

Added: ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/builder/TypeHandlerCallbackAdapter.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/builder/TypeHandlerCallbackAdapter.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/builder/TypeHandlerCallbackAdapter.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/builder/TypeHandlerCallbackAdapter.java Thu Aug  7 16:21:46 2008
@@ -0,0 +1,976 @@
+package com.ibatis.sqlmap.engine.builder;
+
+import com.ibatis.sqlmap.client.extensions.*;
+import org.apache.ibatis.type.*;
+
+import java.io.*;
+import java.math.BigDecimal;
+import java.net.URL;
+import java.sql.*;
+import java.sql.Date;
+import java.util.*;
+
+public class TypeHandlerCallbackAdapter implements TypeHandler {
+
+  private TypeHandlerCallback callback;
+
+  public TypeHandlerCallbackAdapter(TypeHandlerCallback callback) {
+    this.callback = callback;
+  }
+
+  public void setParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType) throws SQLException {
+    callback.setParameter(new ParameterSetterImpl(ps, i), parameter);
+  }
+
+  public Object getResult(ResultSet rs, String columnName) throws SQLException {
+    return callback.getResult(new ResultGetterImpl(rs, columnName));
+  }
+
+  public Object getResult(CallableStatement cs, int columnIndex) throws SQLException {
+    return callback.getResult(new ResultGetterImpl(new CallableStatementResultSet(cs), columnIndex));
+  }
+
+  public static class ParameterSetterImpl implements ParameterSetter {
+
+    private PreparedStatement ps;
+    private int index;
+
+    /**
+     * Creates an instance for a PreparedStatement and column index
+     *
+     * @param statement   - the PreparedStatement
+     * @param columnIndex - the column index
+     */
+    public ParameterSetterImpl(PreparedStatement statement, int columnIndex) {
+      this.ps = statement;
+      this.index = columnIndex;
+    }
+
+    public void setArray(Array x) throws SQLException {
+      ps.setArray(index, x);
+    }
+
+    public void setAsciiStream(InputStream x, int length) throws SQLException {
+      ps.setAsciiStream(index, x, length);
+    }
+
+    public void setBigDecimal(BigDecimal x) throws SQLException {
+      ps.setBigDecimal(index, x);
+    }
+
+    public void setBinaryStream(InputStream x, int length) throws SQLException {
+      ps.setBinaryStream(index, x, length);
+    }
+
+    public void setBlob(Blob x) throws SQLException {
+      ps.setBlob(index, x);
+    }
+
+    public void setBoolean(boolean x) throws SQLException {
+      ps.setBoolean(index, x);
+    }
+
+    public void setByte(byte x) throws SQLException {
+      ps.setByte(index, x);
+    }
+
+    public void setBytes(byte x[]) throws SQLException {
+      ps.setBytes(index, x);
+    }
+
+    public void setCharacterStream(Reader reader, int length) throws SQLException {
+      ps.setCharacterStream(index, reader, length);
+    }
+
+    public void setClob(Clob x) throws SQLException {
+      ps.setClob(index, x);
+    }
+
+    public void setDate(Date x) throws SQLException {
+      ps.setDate(index, x);
+    }
+
+    public void setDate(Date x, Calendar cal) throws SQLException {
+      ps.setDate(index, x, cal);
+    }
+
+    public void setDouble(double x) throws SQLException {
+      ps.setDouble(index, x);
+    }
+
+    public void setFloat(float x) throws SQLException {
+      ps.setFloat(index, x);
+    }
+
+    public void setInt(int x) throws SQLException {
+      ps.setInt(index, x);
+    }
+
+    public void setLong(long x) throws SQLException {
+      ps.setLong(index, x);
+    }
+
+    public void setNull(int sqlType) throws SQLException {
+      ps.setNull(index, sqlType);
+    }
+
+    public void setNull(int sqlType, String typeName) throws SQLException {
+      ps.setNull(index, sqlType, typeName);
+    }
+
+    public void setObject(Object x) throws SQLException {
+      ps.setObject(index, x);
+    }
+
+    public void setObject(Object x, int targetSqlType) throws SQLException {
+      ps.setObject(index, x, targetSqlType);
+    }
+
+    public void setObject(Object x, int targetSqlType, int scale) throws SQLException {
+      ps.setObject(index, x, scale);
+    }
+
+    public void setRef(Ref x) throws SQLException {
+      ps.setRef(index, x);
+    }
+
+    public void setShort(short x) throws SQLException {
+      ps.setShort(index, x);
+    }
+
+    public void setString(String x) throws SQLException {
+      ps.setString(index, x);
+    }
+
+    public void setTime(Time x) throws SQLException {
+      ps.setTime(index, x);
+    }
+
+    public void setTime(Time x, Calendar cal) throws SQLException {
+      ps.setTime(index, x, cal);
+    }
+
+    public void setTimestamp(Timestamp x) throws SQLException {
+      ps.setTimestamp(index, x);
+    }
+
+    public void setTimestamp(Timestamp x, Calendar cal) throws SQLException {
+      ps.setTimestamp(index, x, cal);
+    }
+
+    public void setURL(URL x) throws SQLException {
+      ps.setURL(index, x);
+    }
+
+    public PreparedStatement getPreparedStatement() {
+      return ps;
+    }
+
+    public int getParameterIndex() {
+      return index;
+    }
+  }
+
+  public static class ResultGetterImpl implements ResultGetter {
+
+    private ResultSet rs;
+    private String name;
+    private int index;
+
+    /**
+     * Creates an instance for a PreparedStatement and column index
+     *
+     * @param resultSet   - the result set
+     * @param columnIndex - the column index
+     */
+    public ResultGetterImpl(ResultSet resultSet, int columnIndex) {
+      this.rs = resultSet;
+      this.index = columnIndex;
+    }
+
+    /**
+     * Creates an instance for a PreparedStatement and column name
+     *
+     * @param resultSet  - the result set
+     * @param columnName - the column index
+     */
+    public ResultGetterImpl(ResultSet resultSet, String columnName) {
+      this.rs = resultSet;
+      this.name = columnName;
+    }
+
+
+    public Array getArray() throws SQLException {
+      if (name != null) {
+        return rs.getArray(name);
+      } else {
+        return rs.getArray(index);
+      }
+    }
+
+    public BigDecimal getBigDecimal() throws SQLException {
+      if (name != null) {
+        return rs.getBigDecimal(name);
+      } else {
+        return rs.getBigDecimal(index);
+      }
+    }
+
+    public Blob getBlob() throws SQLException {
+      if (name != null) {
+        return rs.getBlob(name);
+      } else {
+        return rs.getBlob(index);
+      }
+    }
+
+    public boolean getBoolean() throws SQLException {
+      if (name != null) {
+        return rs.getBoolean(name);
+      } else {
+        return rs.getBoolean(index);
+      }
+    }
+
+    public byte getByte() throws SQLException {
+      if (name != null) {
+        return rs.getByte(name);
+      } else {
+        return rs.getByte(index);
+      }
+    }
+
+    public byte[] getBytes() throws SQLException {
+      if (name != null) {
+        return rs.getBytes(name);
+      } else {
+        return rs.getBytes(index);
+      }
+    }
+
+    public Clob getClob() throws SQLException {
+      if (name != null) {
+        return rs.getClob(name);
+      } else {
+        return rs.getClob(index);
+      }
+    }
+
+    public Date getDate() throws SQLException {
+      if (name != null) {
+        return rs.getDate(name);
+      } else {
+        return rs.getDate(index);
+      }
+    }
+
+    public Date getDate(Calendar cal) throws SQLException {
+      if (name != null) {
+        return rs.getDate(name, cal);
+      } else {
+        return rs.getDate(index, cal);
+      }
+    }
+
+    public double getDouble() throws SQLException {
+      if (name != null) {
+        return rs.getDouble(name);
+      } else {
+        return rs.getDouble(index);
+      }
+    }
+
+    public float getFloat() throws SQLException {
+      if (name != null) {
+        return rs.getFloat(name);
+      } else {
+        return rs.getFloat(index);
+      }
+    }
+
+    public int getInt() throws SQLException {
+      if (name != null) {
+        return rs.getInt(name);
+      } else {
+        return rs.getInt(index);
+      }
+    }
+
+    public long getLong() throws SQLException {
+      if (name != null) {
+        return rs.getLong(name);
+      } else {
+        return rs.getLong(index);
+      }
+    }
+
+    public Object getObject() throws SQLException {
+      if (name != null) {
+        return rs.getObject(name);
+      } else {
+        return rs.getObject(index);
+      }
+    }
+
+    public Object getObject(Map map) throws SQLException {
+      if (name != null) {
+        return rs.getObject(name, map);
+      } else {
+        return rs.getObject(index, map);
+      }
+    }
+
+    public Ref getRef() throws SQLException {
+      if (name != null) {
+        return rs.getRef(name);
+      } else {
+        return rs.getRef(index);
+      }
+    }
+
+    public short getShort() throws SQLException {
+      if (name != null) {
+        return rs.getShort(name);
+      } else {
+        return rs.getShort(index);
+      }
+    }
+
+    public String getString() throws SQLException {
+      if (name != null) {
+        return rs.getString(name);
+      } else {
+        return rs.getString(index);
+      }
+    }
+
+    public Time getTime() throws SQLException {
+      if (name != null) {
+        return rs.getTime(name);
+      } else {
+        return rs.getTime(index);
+      }
+    }
+
+    public Time getTime(Calendar cal) throws SQLException {
+      if (name != null) {
+        return rs.getTime(name);
+      } else {
+        return rs.getTime(index);
+      }
+    }
+
+    public Timestamp getTimestamp() throws SQLException {
+      if (name != null) {
+        return rs.getTimestamp(name);
+      } else {
+        return rs.getTimestamp(index);
+      }
+    }
+
+    public Timestamp getTimestamp(Calendar cal) throws SQLException {
+      if (name != null) {
+        return rs.getTimestamp(name, cal);
+      } else {
+        return rs.getTimestamp(index, cal);
+      }
+    }
+
+    public URL getURL() throws SQLException {
+      if (name != null) {
+        return rs.getURL(name);
+      } else {
+        return rs.getURL(index);
+      }
+    }
+
+    public boolean wasNull() throws SQLException {
+      return rs.wasNull();
+    }
+
+    public ResultSet getResultSet() {
+      return rs;
+    }
+
+    public int getColumnIndex() {
+      return index;
+    }
+
+    public String getColumnName() {
+      return name;
+    }
+  }
+
+  public static class CallableStatementResultSet implements ResultSet {
+
+    private CallableStatement cs;
+
+    /**
+     * Constructor to stretch a ResultSet interface over a CallableStatement
+     *
+     * @param cs - the CallableStatement
+     */
+    public CallableStatementResultSet(CallableStatement cs) {
+      this.cs = cs;
+    }
+
+    public boolean absolute(int row) throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public void afterLast() throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public void beforeFirst() throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public void cancelRowUpdates() throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public void clearWarnings() throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public void close() throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public void deleteRow() throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public int findColumn(String columnName) throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public boolean first() throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public Array getArray(String colName) throws SQLException {
+      return cs.getArray(colName);
+    }
+
+    public Array getArray(int i) throws SQLException {
+      return cs.getArray(i);
+    }
+
+    public InputStream getAsciiStream(int columnIndex) throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public InputStream getAsciiStream(String columnName) throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public BigDecimal getBigDecimal(int columnIndex) throws SQLException {
+      return cs.getBigDecimal(columnIndex);
+    }
+
+    public BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public BigDecimal getBigDecimal(String columnName) throws SQLException {
+      return cs.getBigDecimal(columnName);
+    }
+
+    public BigDecimal getBigDecimal(String columnName, int scale) throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public InputStream getBinaryStream(int columnIndex) throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public InputStream getBinaryStream(String columnName) throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public Blob getBlob(String colName) throws SQLException {
+      return cs.getBlob(colName);
+    }
+
+    public Blob getBlob(int i) throws SQLException {
+      return cs.getBlob(i);
+    }
+
+    public boolean getBoolean(int columnIndex) throws SQLException {
+      return cs.getBoolean(columnIndex);
+    }
+
+    public boolean getBoolean(String columnName) throws SQLException {
+      return cs.getBoolean(columnName);
+    }
+
+    public byte getByte(int columnIndex) throws SQLException {
+      return cs.getByte(columnIndex);
+    }
+
+    public byte getByte(String columnName) throws SQLException {
+      return cs.getByte(columnName);
+    }
+
+    public byte[] getBytes(int columnIndex) throws SQLException {
+      return cs.getBytes(columnIndex);
+    }
+
+    public byte[] getBytes(String columnName) throws SQLException {
+      return cs.getBytes(columnName);
+    }
+
+    public Reader getCharacterStream(int columnIndex) throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public Reader getCharacterStream(String columnName) throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public Clob getClob(String colName) throws SQLException {
+      return cs.getClob(colName);
+    }
+
+    public Clob getClob(int i) throws SQLException {
+      return cs.getClob(i);
+    }
+
+    public int getConcurrency() throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public String getCursorName() throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public Date getDate(int columnIndex) throws SQLException {
+      return cs.getDate(columnIndex);
+    }
+
+    public Date getDate(int columnIndex, Calendar cal) throws SQLException {
+      return cs.getDate(columnIndex, cal);
+    }
+
+    public Date getDate(String columnName) throws SQLException {
+      return cs.getDate(columnName);
+    }
+
+    public Date getDate(String columnName, Calendar cal) throws SQLException {
+      return cs.getDate(columnName, cal);
+    }
+
+    public double getDouble(int columnIndex) throws SQLException {
+      return cs.getDouble(columnIndex);
+    }
+
+    public double getDouble(String columnName) throws SQLException {
+      return cs.getDouble(columnName);
+    }
+
+    public int getFetchDirection() throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public int getFetchSize() throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public float getFloat(int columnIndex) throws SQLException {
+      return cs.getFloat(columnIndex);
+    }
+
+    public float getFloat(String columnName) throws SQLException {
+      return cs.getFloat(columnName);
+    }
+
+    public int getInt(int columnIndex) throws SQLException {
+      return cs.getInt(columnIndex);
+    }
+
+    public int getInt(String columnName) throws SQLException {
+      return cs.getInt(columnName);
+    }
+
+    public long getLong(int columnIndex) throws SQLException {
+      return cs.getLong(columnIndex);
+    }
+
+    public long getLong(String columnName) throws SQLException {
+      return cs.getLong(columnName);
+    }
+
+    public ResultSetMetaData getMetaData() throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public Object getObject(String colName, Map map) throws SQLException {
+      return cs.getObject(colName, map);
+    }
+
+    public Object getObject(int columnIndex) throws SQLException {
+      return cs.getObject(columnIndex);
+    }
+
+    public Object getObject(String columnName) throws SQLException {
+      return cs.getObject(columnName);
+    }
+
+    public Object getObject(int i, Map map) throws SQLException {
+      return cs.getObject(i, map);
+    }
+
+    public Ref getRef(String colName) throws SQLException {
+      return cs.getRef(colName);
+    }
+
+    public Ref getRef(int i) throws SQLException {
+      return cs.getRef(i);
+    }
+
+    public int getRow() throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public short getShort(int columnIndex) throws SQLException {
+      return cs.getShort(columnIndex);
+    }
+
+    public short getShort(String columnName) throws SQLException {
+      return cs.getShort(columnName);
+    }
+
+    public Statement getStatement() throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public String getString(int columnIndex) throws SQLException {
+      return cs.getString(columnIndex);
+    }
+
+    public String getString(String columnName) throws SQLException {
+      return cs.getString(columnName);
+    }
+
+    public Time getTime(int columnIndex) throws SQLException {
+      return cs.getTime(columnIndex);
+    }
+
+    public Time getTime(int columnIndex, Calendar cal) throws SQLException {
+      return cs.getTime(columnIndex, cal);
+    }
+
+    public Time getTime(String columnName) throws SQLException {
+      return cs.getTime(columnName);
+    }
+
+    public Time getTime(String columnName, Calendar cal) throws SQLException {
+      return cs.getTime(columnName, cal);
+    }
+
+    public Timestamp getTimestamp(int columnIndex) throws SQLException {
+      return cs.getTimestamp(columnIndex);
+    }
+
+    public Timestamp getTimestamp(int columnIndex, Calendar cal) throws SQLException {
+      return cs.getTimestamp(columnIndex, cal);
+    }
+
+    public Timestamp getTimestamp(String columnName) throws SQLException {
+      return cs.getTimestamp(columnName);
+    }
+
+    public Timestamp getTimestamp(String columnName, Calendar cal) throws SQLException {
+      return cs.getTimestamp(columnName, cal);
+    }
+
+    public int getType() throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public InputStream getUnicodeStream(int columnIndex) throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public InputStream getUnicodeStream(String columnName) throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public URL getURL(int columnIndex) throws SQLException {
+      return cs.getURL(columnIndex);
+    }
+
+    public URL getURL(String columnName) throws SQLException {
+      return cs.getURL(columnName);
+    }
+
+    public SQLWarning getWarnings() throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public void insertRow() throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public boolean isAfterLast() throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public boolean isBeforeFirst() throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public boolean isFirst() throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public boolean isLast() throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public boolean last() throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public void moveToCurrentRow() throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public void moveToInsertRow() throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public boolean next() throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public boolean previous() throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public void refreshRow() throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public boolean relative(int rows) throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public boolean rowDeleted() throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public boolean rowInserted() throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public boolean rowUpdated() throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public void setFetchDirection(int direction) throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public void setFetchSize(int rows) throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public void updateArray(int columnIndex, Array x) throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public void updateArray(String columnName, Array x) throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public void updateAsciiStream(int columnIndex, InputStream x, int length) throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public void updateAsciiStream(String columnName, InputStream x, int length) throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public void updateBigDecimal(int columnIndex, BigDecimal x) throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public void updateBigDecimal(String columnName, BigDecimal x) throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public void updateBinaryStream(int columnIndex, InputStream x, int length) throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public void updateBinaryStream(String columnName, InputStream x, int length) throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public void updateBlob(int columnIndex, Blob x) throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public void updateBlob(String columnName, Blob x) throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public void updateBoolean(int columnIndex, boolean x) throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public void updateBoolean(String columnName, boolean x) throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public void updateByte(int columnIndex, byte x) throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public void updateByte(String columnName, byte x) throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public void updateBytes(int columnIndex, byte x[]) throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public void updateBytes(String columnName, byte x[]) throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public void updateCharacterStream(int columnIndex, Reader x, int length) throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public void updateCharacterStream(String columnName, Reader reader, int length) throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public void updateClob(int columnIndex, Clob x) throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public void updateClob(String columnName, Clob x) throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public void updateDate(int columnIndex, Date x) throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public void updateDate(String columnName, Date x) throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public void updateDouble(int columnIndex, double x) throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public void updateDouble(String columnName, double x) throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public void updateFloat(int columnIndex, float x) throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public void updateFloat(String columnName, float x) throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public void updateInt(int columnIndex, int x) throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public void updateInt(String columnName, int x) throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public void updateLong(int columnIndex, long x) throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public void updateLong(String columnName, long x) throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public void updateNull(int columnIndex) throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public void updateNull(String columnName) throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public void updateObject(int columnIndex, Object x) throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public void updateObject(int columnIndex, Object x, int scale) throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public void updateObject(String columnName, Object x) throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public void updateObject(String columnName, Object x, int scale) throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public void updateRef(int columnIndex, Ref x) throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public void updateRef(String columnName, Ref x) throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public void updateRow() throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public void updateShort(int columnIndex, short x) throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public void updateShort(String columnName, short x) throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public void updateString(int columnIndex, String x) throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public void updateString(String columnName, String x) throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public void updateTime(int columnIndex, Time x) throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public void updateTime(String columnName, Time x) throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public void updateTimestamp(int columnIndex, Timestamp x) throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public void updateTimestamp(String columnName, Timestamp x) throws SQLException {
+      throw new UnsupportedOperationException("CallableStatement does not support this method.");
+    }
+
+    public boolean wasNull() throws SQLException {
+      return cs.wasNull();
+    }
+
+  }
+
+
+}

Added: ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/builder/XmlSqlMapConfigParser.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/builder/XmlSqlMapConfigParser.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/builder/XmlSqlMapConfigParser.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/builder/XmlSqlMapConfigParser.java Thu Aug  7 16:21:46 2008
@@ -0,0 +1,214 @@
+package com.ibatis.sqlmap.engine.builder;
+
+import com.ibatis.sqlmap.client.SqlMapException;
+import com.ibatis.sqlmap.client.extensions.TypeHandlerCallback;
+import com.ibatis.sqlmap.engine.datasource.DataSourceFactory;
+import com.ibatis.sqlmap.engine.transaction.*;
+import org.apache.ibatis.io.Resources;
+import org.apache.ibatis.reflection.*;
+import org.apache.ibatis.type.*;
+import org.apache.ibatis.xml.*;
+
+import java.io.Reader;
+import java.util.*;
+
+public class XmlSqlMapConfigParser {
+
+  private Reader reader;
+  private NodeletParser parser = new NodeletParser();
+
+  private Ibatis2Configuration config = new Ibatis2Configuration();
+  private Properties dataSourceProps = new Properties();
+  private Properties transactionManagerProps = new Properties();
+  private boolean useStatementNamespaces;
+
+  private Map<String, NodeletContext> sqlFragments = new HashMap<String, NodeletContext>();
+
+  public XmlSqlMapConfigParser(Reader reader) {
+    this.reader = reader;
+    this.parser.addNodeletHandler(this);
+    this.useStatementNamespaces = false;
+  }
+
+  public XmlSqlMapConfigParser(Reader reader, Properties props) {
+    this(reader);
+    this.config.setVariables(props);
+    this.parser.setVariables(props);
+    this.parser.setEntityResolver(new SqlMapEntityResolver());
+  }
+
+  public void parse() {
+    parser.parse(reader);
+  }
+
+  public boolean hasSqlFragment(String id) {
+    return sqlFragments.containsKey(id);
+  }
+
+  public NodeletContext getSqlFragment(String id) {
+    return sqlFragments.get(id);
+  }
+
+  public void addSqlFragment(String id, NodeletContext context) {
+    sqlFragments.put(id, context);
+  }
+
+  public Ibatis2Configuration getConfiguration() {
+    return config;
+  }
+
+  public boolean isUseStatementNamespaces() {
+    return useStatementNamespaces;
+  }
+
+  @Nodelet("/sqlMapConfig/properties")
+  public void sqlMapConfigproperties(NodeletContext context) throws Exception {
+    String resource = context.getStringAttribute("resource");
+    String url = context.getStringAttribute("url");
+    Properties fileVariables;
+    if (resource != null) {
+      fileVariables = Resources.getResourceAsProperties(resource);
+    } else if (url != null) {
+      fileVariables = Resources.getUrlAsProperties(url);
+    } else {
+      throw new RuntimeException("The properties element requires either a resource or a url attribute.");
+    }
+    // Override file variables with those passed in programmatically
+    Properties passedVariables = config.getVariables();
+    if (passedVariables != null) {
+      fileVariables.putAll(passedVariables);
+    }
+    config.setVariables(fileVariables);
+    parser.setVariables(fileVariables);
+  }
+
+  @Nodelet("/sqlMapConfig/settings")
+  public void sqlMapConfigsettings(NodeletContext context) throws Exception {
+    boolean classInfoCacheEnabled = context.getBooleanAttribute("classInfoCacheEnabled", true);
+    MetaClass.setClassCacheEnabled(classInfoCacheEnabled);
+
+    boolean lazyLoadingEnabled = context.getBooleanAttribute("lazyLoadingEnabled", true);
+    config.setLazyLoadingEnabled(lazyLoadingEnabled);
+
+    boolean enhancementEnabled = context.getBooleanAttribute("enhancementEnabled", true);
+    config.setEnhancementEnabled(enhancementEnabled);
+
+    boolean statementCachingEnabled = context.getBooleanAttribute("statementCachingEnabled", true);
+    config.setStatementCachingEnabled(statementCachingEnabled);
+
+    boolean batchUpdatesEnabled = context.getBooleanAttribute("batchUpdatesEnabled", true);
+    config.setBatchUpdatesEnabled(batchUpdatesEnabled);
+
+    boolean cacheModelsEnabled = context.getBooleanAttribute("cacheModelsEnabled", true);
+    config.setCacheEnabled(cacheModelsEnabled);
+
+    boolean useColumnLabel = context.getBooleanAttribute("useColumnLabel", true);
+    config.setUseColumnLabel(useColumnLabel);
+
+    boolean forceMultipleResultSetSupport = context.getBooleanAttribute("forceMultipleResultSetSupport", true);
+    config.setMultipleResultSetsEnabled(forceMultipleResultSetSupport);
+
+    useStatementNamespaces = context.getBooleanAttribute("useStatementNamespaces", false);
+
+    Integer defaultTimeout = context.getIntAttribute("defaultStatementTimeout");
+    config.setDefaultStatementTimeout(defaultTimeout);
+  }
+
+  @Nodelet("/sqlMapConfig/typeAlias")
+  public void sqlMapConfigtypeAlias(NodeletContext context) throws Exception {
+    String alias = context.getStringAttribute("alias");
+    String type = context.getStringAttribute("type");
+    config.getTypeAliasRegistry().registerAlias(alias, type);
+  }
+
+  @Nodelet("/sqlMapConfig/typeHandler")
+  public void sqlMapConfigtypeHandler(NodeletContext context) throws Exception {
+    String jdbcType = context.getStringAttribute("jdbcType");
+    String javaType = context.getStringAttribute("javaType");
+    String callback = context.getStringAttribute("callback");
+
+    javaType = config.getTypeAliasRegistry().resolveAlias(javaType);
+    callback = config.getTypeAliasRegistry().resolveAlias(callback);
+
+    if (javaType != null && callback != null) {
+      JdbcType jdbcTypeEnum = JdbcType.valueOf(jdbcType);
+      Class javaTypeClass = Resources.classForName(javaType);
+      Class callbackClass = Resources.classForName(callback);
+      Object o = callbackClass.newInstance();
+      if (o instanceof TypeHandlerCallback) {
+        TypeHandler typeHandler = new TypeHandlerCallbackAdapter((TypeHandlerCallback) o);
+        config.getTypeHandlerRegistry().register(javaTypeClass, jdbcTypeEnum, typeHandler);
+      }
+    }
+  }
+
+  @Nodelet("/sqlMapConfig/transactionManager/end()")
+  public void sqlMapConfigtransactionManagerend(NodeletContext context) throws Exception {
+    String type = context.getStringAttribute("type");
+    type = config.getTypeAliasRegistry().resolveAlias(type);
+    Class txClass = Class.forName(type);
+    boolean commitRequired = context.getBooleanAttribute("commitRequired", false);
+
+    TransactionConfig txConfig = (TransactionConfig) txClass.newInstance();
+    txConfig.setDataSource(config.getDataSource());
+    txConfig.setProperties(transactionManagerProps);
+    txConfig.setForceCommit(commitRequired);
+    config.setTransactionManager(new TransactionManager(config, txConfig));
+  }
+
+  @Nodelet("/sqlMapConfig/transactionManager/property")
+  public void sqlMapConfigtransactionManagerproperty(NodeletContext context) throws Exception {
+    String name = context.getStringAttribute("name");
+    String value = context.getStringAttribute("value");
+    transactionManagerProps.setProperty(name, value);
+  }
+
+  @Nodelet("/sqlMapConfig/transactionManager/dataSource/property")
+  public void sqlMapConfigtransactionManagerdataSourceproperty(NodeletContext context) throws Exception {
+    String name = context.getStringAttribute("name");
+    String value = context.getStringAttribute("value");
+    dataSourceProps.setProperty(name, value);
+  }
+
+  @Nodelet("/sqlMapConfig/transactionManager/dataSource/end()")
+  public void sqlMapConfigtransactionManagerdataSourceend(NodeletContext context) throws Exception {
+    String type = context.getStringAttribute("type");
+    type = config.getTypeAliasRegistry().resolveAlias(type);
+    Class dataSourceClass = Class.forName(type);
+    DataSourceFactory dsFactory = (DataSourceFactory) dataSourceClass.newInstance();
+    dsFactory.initialize(dataSourceProps);
+    config.setDataSource(dsFactory.getDataSource());
+  }
+
+  @Nodelet("/sqlMapConfig/resultObjectFactory")
+  public void sqlMapConfigresultObjectFactory(NodeletContext context) throws Exception {
+    String type = context.getStringAttribute("type");
+    Class factoryClass = Class.forName(type);
+    ObjectFactory factory = (ObjectFactory) factoryClass.newInstance();
+    config.setObjectFactory(factory);
+  }
+
+  @Nodelet("/sqlMapConfig/resultObjectFactory/property")
+  public void sqlMapConfigresultObjectFactoryproperty(NodeletContext context) throws Exception {
+    String name = context.getStringAttribute("name");
+    String value = context.getStringAttribute("value");
+    config.getObjectFactory().setProperty(name, value);
+  }
+
+  @Nodelet("/sqlMapConfig/sqlMap")
+  public void sqlMapConfigsqlMap(NodeletContext context) throws Exception {
+    String resource = context.getStringAttribute("resource");
+    String url = context.getStringAttribute("url");
+
+    Reader reader = null;
+    if (resource != null) {
+      reader = Resources.getResourceAsReader(resource);
+    } else if (url != null) {
+      reader = Resources.getUrlAsReader(url);
+    } else {
+      throw new SqlMapException("The sqlMap element requires either a resource or a url attribute.");
+    }
+    new XmlSqlMapParser(this, reader).parse();
+  }
+
+}

Added: ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/builder/XmlSqlMapParser.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/builder/XmlSqlMapParser.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/builder/XmlSqlMapParser.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/builder/XmlSqlMapParser.java Thu Aug  7 16:21:46 2008
@@ -0,0 +1,523 @@
+package com.ibatis.sqlmap.engine.builder;
+
+import com.ibatis.sqlmap.client.SqlMapException;
+import com.ibatis.sqlmap.client.extensions.TypeHandlerCallback;
+import org.apache.ibatis.cache.Cache;
+import org.apache.ibatis.io.Resources;
+import org.apache.ibatis.mapping.*;
+import org.apache.ibatis.reflection.MetaClass;
+import org.apache.ibatis.type.*;
+import org.apache.ibatis.xml.*;
+
+import java.io.Reader;
+import java.util.*;
+
+public class XmlSqlMapParser {
+
+  private XmlSqlMapConfigParser configParser;
+  private Ibatis2Configuration config;
+  private Reader reader;
+  private NodeletParser parser;
+
+  private Cache.Builder cacheBuilder;
+  private List<String> flushCacheStatements;
+
+  private ResultMap.Builder resultMapBuilder;
+  private List<ResultMapping> resultMappingList;
+  private Map<String, String> discriminatorSubMap;
+
+  private Discriminator.Builder discriminatorBuilder;
+
+  private ParameterMap.Builder parameterMapBuilder;
+  private List<ParameterMapping> parameterMappingList;
+
+  private String namespace;
+  private List<String> groupByProperties;
+
+  public XmlSqlMapParser(XmlSqlMapConfigParser configParser, Reader reader) {
+    this.configParser = configParser;
+    this.config = (Ibatis2Configuration) configParser.getConfiguration();
+    this.reader = reader;
+    this.parser = new NodeletParser();
+    this.parser.addNodeletHandler(this);
+    this.parser.setVariables(config.getVariables());
+    this.flushCacheStatements = new ArrayList<String>();
+    this.parser.setEntityResolver(new SqlMapEntityResolver());
+  }
+
+  public void parse() {
+    parser.parse(reader);
+  }
+
+  public XmlSqlMapConfigParser getConfigParser() {
+    return configParser;
+  }
+
+  public String getNamespace() {
+    return namespace;
+  }
+
+  public String applyNamespace(String id) {
+
+    return id == null ? null : namespace == null ? id : namespace + "." + id;
+  }
+
+  @Nodelet("/sqlMap")
+  public void sqlMap(NodeletContext context) throws Exception {
+    this.namespace = context.getStringAttribute("namespace");
+  }
+
+  @Nodelet("/sqlMap/typeAlias")
+  public void sqlMaptypeAlias(NodeletContext context) throws Exception {
+    String alias = context.getStringAttribute("alias");
+    String type = context.getStringAttribute("type");
+    config.getTypeAliasRegistry().registerAlias(alias, type);
+  }
+
+  @Nodelet("/sqlMap/cacheModel")
+  public void sqlMapcacheModel(NodeletContext context) throws Exception {
+    String id = applyNamespace(context.getStringAttribute("id"));
+    String type = context.getStringAttribute("type");
+    Boolean readOnly = context.getBooleanAttribute("readOnly", true);
+    Boolean serialize = context.getBooleanAttribute("serialize", true);
+    type = config.getTypeAliasRegistry().resolveAlias(type);
+    Class clazz = Resources.classForName(type);
+    cacheBuilder = new Cache.Builder(id, clazz);
+
+    //LOCAL_READ_WRITE (serializable=false, readOnly=false)
+    //SHARED_READ_ONLY (serializable=false, readOnly=true)
+    //SHARED_READ_WRITE (serializable=true, readOnly=false)
+    if (serialize) {
+      if (readOnly) {
+        cacheBuilder.readWrite(false);
+      } else {
+        cacheBuilder.readWrite(true);
+      }
+    } else {
+      if (readOnly) {
+        cacheBuilder.readWrite(false);
+      } else {
+        cacheBuilder = null;
+      }
+    }
+  }
+
+  @Nodelet("/sqlMap/cacheModel/property")
+  public void sqlMapcacheModelproperty(NodeletContext context) throws Exception {
+    if (cacheBuilder != null) {
+      String name = context.getStringAttribute("name");
+      String value = context.getStringAttribute("value");
+      if ("size".equals(name)) {
+        cacheBuilder.size(Integer.parseInt(value));
+      }
+    }
+  }
+
+  @Nodelet("/sqlMap/cacheModel/flushInterval")
+  public void sqlMapcacheModelflushInterval(NodeletContext context) throws Exception {
+    if (cacheBuilder != null) {
+      long clearInterval = 0L;
+      clearInterval += context.getIntAttribute("milliseconds", 0);
+      clearInterval += context.getIntAttribute("seconds", 0) * 1000L;
+      clearInterval += context.getIntAttribute("minutes", 0) * 60L * 1000L;
+      clearInterval += context.getIntAttribute("hours", 0) * 60L * 60L * 1000L;
+      if (clearInterval < 1L) {
+        throw new RuntimeException("A flush interval must specify one or more of milliseconds, seconds, minutes or hours.");
+      }
+      cacheBuilder.clearInterval(clearInterval);
+    }
+  }
+
+  @Nodelet("/sqlMap/cacheModel/flushOnExecute")
+  public void sqlMapcacheModelflushOnExecute(NodeletContext context) throws Exception {
+    if (cacheBuilder != null) {
+      String statement = context.getStringAttribute("statement");
+      flushCacheStatements.add(statement);
+    }
+  }
+
+  @Nodelet("/sqlMap/cacheModel/end()")
+  public void sqlMapcacheModelEnd(NodeletContext context) throws Exception {
+    if (cacheBuilder != null) {
+      Cache cache = cacheBuilder.build();
+      for (String sid : flushCacheStatements) {
+        config.getFlushCachePlugin().addFlushOnExecute(sid, cache);
+      }
+      config.addCache(cache);
+      flushCacheStatements = new ArrayList<String>();
+    }
+  }
+
+  @Nodelet("/sqlMap/resultMap")
+  public void sqlMapresultMap(NodeletContext context) throws Exception {
+    String xmlName = context.getStringAttribute("xmlName");
+    if (xmlName != null) {
+      throw new UnsupportedOperationException("xmlName is not supported by iBATIS 3");
+    }
+
+    String id = applyNamespace(context.getStringAttribute("id"));
+    String resultClassName = context.getStringAttribute("class");
+    String extendedId = applyNamespace(context.getStringAttribute("extends"));
+
+    String groupBy = context.getStringAttribute("groupBy");
+    if (groupBy != null) {
+      groupByProperties = Arrays.asList(groupBy.split(", "));
+    }
+
+    resultClassName = config.getTypeAliasRegistry().resolveAlias(resultClassName);
+    Class resultClass;
+    try {
+      resultClass = Resources.classForName(resultClassName);
+    } catch (Exception e) {
+      throw new RuntimeException("Error configuring Result.  Could not set ResultClass.  Cause: " + e, e);
+    }
+
+    resultMappingList = new ArrayList<ResultMapping>();
+    resultMapBuilder = new ResultMap.Builder(id, resultClass, resultMappingList);
+
+    if (extendedId != null) {
+      ResultMap extendedResultMap = config.getResultMap(extendedId);
+      if (extendedResultMap != null) {
+        for (ResultMapping mapping : extendedResultMap.getResultMappings()) {
+          resultMappingList.add(mapping);
+        }
+        resultMapBuilder.discriminator(extendedResultMap.getDiscriminator());
+      } else {
+        throw new SqlMapException("Could not extend non-existant result map named " + extendedId);
+      }
+    }
+
+  }
+
+  @Nodelet("/sqlMap/resultMap/discriminator")
+  public void sqlMapresultMapdiscriminator(NodeletContext context) throws Exception {
+    String nullValue = context.getStringAttribute("nullValue");
+    if (nullValue != null) {
+      throw new UnsupportedOperationException("Null value subsitution is not supported by iBATIS 3.");
+    }
+    String columnIndexProp = context.getStringAttribute("columnIndex");
+    if (columnIndexProp != null) {
+      throw new UnsupportedOperationException("Numerical column indices are not supported.  Use the column name instead.");
+    }
+
+    String jdbcType = context.getStringAttribute("jdbcType");
+    String javaType = context.getStringAttribute("javaType");
+    String columnName = context.getStringAttribute("column");
+    String callback = context.getStringAttribute("typeHandler");
+
+    Class javaClass = null;
+    try {
+      javaType = config.getTypeAliasRegistry().resolveAlias(javaType);
+      if (javaType != null && javaType.length() > 0) {
+        javaClass = Resources.classForName(javaType);
+      }
+    } catch (ClassNotFoundException e) {
+      throw new RuntimeException("Error setting java type on result discriminator mapping.  Cause: " + e);
+    }
+
+    JdbcType jdbcTypeEnum = null;
+    if (jdbcType != null) {
+      jdbcTypeEnum = JdbcType.valueOf(jdbcType);
+    }
+
+    TypeHandler typeHandler = null;
+    if (javaClass != null) {
+      typeHandler = config.getTypeHandlerRegistry().getTypeHandler(javaClass, jdbcTypeEnum);
+    }
+    try {
+      if (callback != null && callback.length() > 0) {
+        callback = config.getTypeAliasRegistry().resolveAlias(callback);
+        typeHandler = (TypeHandler) Resources.classForName(callback).newInstance();
+      }
+    } catch (Exception e) {
+      throw new RuntimeException("Error occurred during custom type handler configuration.  Cause: " + e, e);
+    }
+
+
+    ResultMapping.Builder resultMappingBuilder = new ResultMapping.Builder(columnName, columnName, typeHandler);
+    resultMappingBuilder.javaType(javaClass);
+    resultMappingBuilder.jdbcType(jdbcTypeEnum);
+    ResultMapping resultMapping = resultMappingBuilder.build();
+
+    discriminatorSubMap = new HashMap<String, String>();
+    discriminatorBuilder = new Discriminator.Builder(resultMapping, discriminatorSubMap);
+
+  }
+
+  @Nodelet("/sqlMap/resultMap/discriminator/subMap")
+  public void sqlMapresultMapdiscriminatorsubMap(NodeletContext context) throws Exception {
+    String value = context.getStringAttribute("value");
+    String resultMap = context.getStringAttribute("resultMap");
+    resultMap = applyNamespace(resultMap);
+    discriminatorSubMap.put(value, resultMap);
+  }
+
+  @Nodelet("/sqlMap/resultMap/discriminator/end()")
+  public void sqlMapresultMapdiscriminatorEnd(NodeletContext context) throws Exception {
+    resultMapBuilder.discriminator(discriminatorBuilder.build());
+  }
+
+
+  @Nodelet("/sqlMap/resultMap/result")
+  public void sqlMapresultMapresult(NodeletContext context) throws Exception {
+    String nullValue = context.getStringAttribute("nullValue");
+    if (nullValue != null) {
+      throw new UnsupportedOperationException("Null value subsitution is not supported by iBATIS 3.");
+    }
+    String columnIndexProp = context.getStringAttribute("columnIndex");
+    if (columnIndexProp != null) {
+      throw new UnsupportedOperationException("Numerical column indices are not supported.  Use the column name instead.");
+    }
+
+    String propertyName = context.getStringAttribute("property");
+    String jdbcType = context.getStringAttribute("jdbcType");
+    String javaType = context.getStringAttribute("javaType");
+    String columnName = context.getStringAttribute("column");
+
+    String statementName = context.getStringAttribute("select");
+    String resultMapName = context.getStringAttribute("resultMap");
+    String callback = context.getStringAttribute("typeHandler");
+
+    Class javaClass = null;
+    try {
+      javaType = config.getTypeAliasRegistry().resolveAlias(javaType);
+      if (javaType != null && javaType.length() > 0) {
+        javaClass = Resources.classForName(javaType);
+      }
+    } catch (ClassNotFoundException e) {
+      throw new RuntimeException("Error setting java type on result discriminator mapping.  Cause: " + e);
+    }
+    if (javaClass == null
+        && !Map.class.isAssignableFrom(resultMapBuilder.type())
+        && !config.getTypeHandlerRegistry().hasTypeHandler(resultMapBuilder.type())) {
+      javaClass = MetaClass.forClass(resultMapBuilder.type()).getSetterType(propertyName);
+    }
+    if (javaClass == null && statementName != null) {
+      javaClass = List.class;
+    }
+
+    JdbcType jdbcTypeEnum = null;
+    if (jdbcType != null) {
+      jdbcTypeEnum = JdbcType.valueOf(jdbcType);
+    }
+
+    TypeHandler typeHandler = null;
+    if (javaClass != null) {
+      typeHandler = config.getTypeHandlerRegistry().getTypeHandler(javaClass, jdbcTypeEnum);
+    }
+    try {
+      if (callback != null && callback.length() > 0) {
+        callback = config.getTypeAliasRegistry().resolveAlias(callback);
+        Object o = Resources.classForName(callback).newInstance();
+        if (o instanceof TypeHandlerCallback) {
+          typeHandler = new TypeHandlerCallbackAdapter((TypeHandlerCallback) o);
+        }
+      }
+    } catch (Exception e) {
+      throw new RuntimeException("Error occurred during custom type handler configuration.  Cause: " + e, e);
+    }
+    if (typeHandler == null && config.getTypeHandlerRegistry().hasTypeHandler(resultMapBuilder.type())) {
+      typeHandler = config.getTypeHandlerRegistry().getTypeHandler(resultMapBuilder.type());
+    }
+
+    if (typeHandler == null) {
+      Class resultClass = resultMapBuilder.type();
+      if (resultClass != null && !Map.class.isAssignableFrom(resultClass)) {
+        MetaClass metaResultClass = MetaClass.forClass(resultClass);
+        Class resultType = null;
+        if (metaResultClass.hasGetter(propertyName)) {
+          resultType = metaResultClass.getGetterType(propertyName);
+        } else if (metaResultClass.hasSetter(propertyName)) {
+          resultType = metaResultClass.getSetterType(propertyName);
+        }
+        if (resultType != null) {
+          typeHandler = config.getTypeHandlerRegistry().getTypeHandler(resultType);
+        }
+      } else {
+        typeHandler = config.getTypeHandlerRegistry().getUnkownTypeHandler();
+      }
+    }
+
+    List<ResultMapping> composites = parseCompositeColumnName(columnName);
+    if (composites.size() > 0) {
+      ResultMapping first = composites.get(0);
+      columnName = first.getColumn();
+    }
+
+    ResultMapping.Builder resultMappingBuilder = new ResultMapping.Builder(propertyName, columnName, typeHandler);
+    resultMappingBuilder.javaType(javaClass);
+    resultMappingBuilder.nestedQueryId(statementName);
+    resultMappingBuilder.nestedResultMapId(resultMapName);
+    resultMappingBuilder.jdbcType(jdbcTypeEnum);
+    resultMappingBuilder.composites(composites);
+    if (groupByProperties != null && groupByProperties.contains(propertyName)) {
+      List<ResultFlag> flags = new ArrayList<ResultFlag>();
+      resultMappingBuilder.flags(flags);
+    }
+    resultMappingList.add(resultMappingBuilder.build());
+  }
+
+  private List<ResultMapping> parseCompositeColumnName(String columnName) {
+    List<ResultMapping> composites = new ArrayList<ResultMapping>();
+    if (columnName != null) {
+      if (columnName.indexOf('=') > -1
+          || columnName.indexOf(',') > -1) {
+        StringTokenizer parser = new StringTokenizer(columnName, "{}=, ", false);
+        while (parser.hasMoreTokens()) {
+          String property = parser.nextToken();
+          String column = parser.nextToken();
+          ResultMapping.Builder complexBuilder = new ResultMapping.Builder(property, column, config.getTypeHandlerRegistry().getUnkownTypeHandler());
+          composites.add(complexBuilder.build());
+        }
+      }
+    }
+    return composites;
+  }
+
+  @Nodelet("/sqlMap/resultMap/end()")
+  public void sqlMapresultMapend(NodeletContext context) throws Exception {
+    config.addResultMap(resultMapBuilder.build());
+  }
+
+  @Nodelet("/sqlMap/parameterMap")
+  public void sqlMapparameterMap(NodeletContext context) throws Exception {
+    String id = applyNamespace(context.getStringAttribute("id"));
+    String parameterClassName = context.getStringAttribute("class");
+    parameterClassName = config.getTypeAliasRegistry().resolveAlias(parameterClassName);
+    Class parameterClass = Resources.classForName(parameterClassName);
+    parameterMappingList = new ArrayList<ParameterMapping>();
+    parameterMapBuilder = new ParameterMap.Builder(id, parameterClass, parameterMappingList);
+  }
+
+  @Nodelet("/sqlMap/parameterMap/parameter")
+  public void sqlMapparameterMapparameter(NodeletContext context) throws Exception {
+    String nullValue = context.getStringAttribute("nullValue");
+    if (nullValue != null) {
+      throw new UnsupportedOperationException("Null value subsitution is not supported by iBATIS 3.");
+    }
+
+    String propertyName = context.getStringAttribute("property");
+    String jdbcType = context.getStringAttribute("jdbcType");
+    String javaType = context.getStringAttribute("javaType");
+    String resultMap = context.getStringAttribute("resultMap");
+    String mode = context.getStringAttribute("mode");
+    String callback = context.getStringAttribute("typeHandler");
+    String numericScaleProp = context.getStringAttribute("numericScale");
+
+    javaType = config.getTypeAliasRegistry().resolveAlias(javaType);
+    Class javaClass = null;
+    try {
+      if (javaType != null && javaType.length() > 0) {
+        javaClass = Resources.classForName(javaType);
+      }
+    } catch (ClassNotFoundException e) {
+      throw new RuntimeException("Error setting javaType on parameter mapping.  Cause: " + e);
+    }
+
+    JdbcType jdbcTypeEnum = null;
+    if (jdbcType != null) {
+      jdbcTypeEnum = JdbcType.valueOf(jdbcType);
+    }
+
+    callback = config.getTypeAliasRegistry().resolveAlias(callback);
+    TypeHandler typeHandler = null;
+    if (javaClass != null) {
+      typeHandler = config.getTypeHandlerRegistry().getTypeHandler(javaClass, jdbcTypeEnum);
+    }
+    if (callback != null) {
+      Object o = Resources.classForName(callback).newInstance();
+      if (o instanceof TypeHandlerCallback) {
+        typeHandler = new TypeHandlerCallbackAdapter((TypeHandlerCallback) o);
+      }
+    }
+    if (typeHandler == null && config.getTypeHandlerRegistry().hasTypeHandler(parameterMapBuilder.type())) {
+      typeHandler = config.getTypeHandlerRegistry().getTypeHandler(parameterMapBuilder.type());
+    }
+    if (typeHandler == null) {
+      Class parameterClass = parameterMapBuilder.type();
+      if (parameterClass != null && !Map.class.isAssignableFrom(parameterClass)) {
+        MetaClass metaParamClass = MetaClass.forClass(parameterClass);
+        Class paramType = null;
+        if (metaParamClass.hasGetter(propertyName)) {
+          paramType = metaParamClass.getGetterType(propertyName);
+        } else if (metaParamClass.hasSetter(propertyName)) {
+          paramType = metaParamClass.getSetterType(propertyName);
+        }
+        if (paramType != null) {
+          typeHandler = config.getTypeHandlerRegistry().getTypeHandler(paramType);
+        }
+      } else {
+        typeHandler = config.getTypeHandlerRegistry().getUnkownTypeHandler();
+      }
+    }
+
+    ParameterMode paramModeEnum = ParameterMode.IN;
+    if (mode != null) {
+      paramModeEnum = ParameterMode.valueOf(mode);
+    }
+
+    Integer numericScale = null;
+    if (numericScaleProp != null) {
+      numericScale = new Integer(numericScaleProp);
+    }
+
+    ParameterMapping.Builder parameterMappingBuilder = new ParameterMapping.Builder(propertyName, typeHandler);
+    parameterMappingBuilder.javaType(javaClass);
+    parameterMappingBuilder.jdbcType(jdbcTypeEnum);
+    parameterMappingBuilder.mode(paramModeEnum);
+    parameterMappingBuilder.numericScale(numericScale);
+    parameterMappingBuilder.resultMapId(resultMap);
+
+    parameterMappingList.add(parameterMappingBuilder.build());
+  }
+
+
+  @Nodelet("/sqlMap/parameterMap/end()")
+  public void sqlMapparameterMapend(NodeletContext context) throws Exception {
+    config.addParameterMap(parameterMapBuilder.build());
+  }
+
+  @Nodelet("/sqlMap/sql")
+  public void sqlMapsql(NodeletContext context) throws Exception {
+    String id = context.getStringAttribute("id");
+    if (configParser.isUseStatementNamespaces()) {
+      id = applyNamespace(id);
+    }
+    if (configParser.hasSqlFragment(id)) {
+      throw new SqlMapException("Duplicate <sql>-include '" + id + "' found.");
+    } else {
+      configParser.addSqlFragment(id, context);
+    }
+  }
+
+  @Nodelet("/sqlMap/statement")
+  public void sqlMapstatement(NodeletContext context) throws Exception {
+    new XmlSqlStatementParser(this).parseGeneralStatement(context);
+  }
+
+  @Nodelet("/sqlMap/select")
+  public void sqlMapselect(NodeletContext context) throws Exception {
+    new XmlSqlStatementParser(this).parseGeneralStatement(context);
+  }
+
+  @Nodelet("/sqlMap/insert")
+  public void sqlMapinsert(NodeletContext context) throws Exception {
+    new XmlSqlStatementParser(this).parseGeneralStatement(context);
+  }
+
+  @Nodelet("/sqlMap/update")
+  public void sqlMapupdate(NodeletContext context) throws Exception {
+    new XmlSqlStatementParser(this).parseGeneralStatement(context);
+  }
+
+  @Nodelet("/sqlMap/delete")
+  public void sqlMapdelete(NodeletContext context) throws Exception {
+    new XmlSqlStatementParser(this).parseGeneralStatement(context);
+  }
+
+  @Nodelet("/sqlMap/procedure")
+  public void sqlMapprocedure(NodeletContext context) throws Exception {
+    new XmlSqlStatementParser(this).parseGeneralStatement(context);
+  }
+
+}

Added: ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/builder/XmlSqlStatementParser.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/builder/XmlSqlStatementParser.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/builder/XmlSqlStatementParser.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/builder/XmlSqlStatementParser.java Thu Aug  7 16:21:46 2008
@@ -0,0 +1,213 @@
+package com.ibatis.sqlmap.engine.builder;
+
+import com.ibatis.sqlmap.client.SqlMapException;
+import com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl;
+import org.apache.ibatis.cache.Cache;
+import org.apache.ibatis.io.Resources;
+import org.apache.ibatis.mapping.*;
+import org.apache.ibatis.type.TypeHandler;
+import org.apache.ibatis.xml.NodeletContext;
+import org.w3c.dom.*;
+
+import java.util.*;
+
+public class XmlSqlStatementParser {
+
+  private XmlSqlMapParser mapParser;
+  private Ibatis2Configuration configuration;
+
+  public XmlSqlStatementParser(XmlSqlMapParser mapParser) {
+    this.mapParser = mapParser;
+    this.configuration = mapParser.getConfigParser().getConfiguration();
+  }
+
+  public void parseGeneralStatement(NodeletContext context) {
+    // get attributes
+    String id = context.getStringAttribute("id");
+    String parameterMapName = context.getStringAttribute("parameterMap");
+    String parameterClassName = context.getStringAttribute("parameterClass");
+    String resultMapName = context.getStringAttribute("resultMap");
+    String resultClassName = context.getStringAttribute("resultClass");
+    String cacheModelName = context.getStringAttribute("cacheModel");
+    String resultSetType = context.getStringAttribute("resultSetType");
+    String fetchSize = context.getStringAttribute("fetchSize");
+    String timeout = context.getStringAttribute("timeout");
+    // 2.x -- String allowRemapping = context.getStringAttribute("remapResults");
+
+    if (context.getStringAttribute("xmlResultName") != null) {
+      throw new UnsupportedOperationException("xmlResultName is not supported by iBATIS 3");
+    }
+
+    if (mapParser.getConfigParser().isUseStatementNamespaces()) {
+      id = mapParser.applyNamespace(id);
+    }
+
+    String[] additionalResultMapNames = null;
+    if (resultMapName != null) {
+      additionalResultMapNames = getAllButFirstToken(resultMapName);
+      resultMapName = getFirstToken(resultMapName);
+      resultMapName = mapParser.applyNamespace(resultMapName);
+      for (int i = 0; i < additionalResultMapNames.length; i++) {
+        additionalResultMapNames[i] = mapParser.applyNamespace(additionalResultMapNames[i]);
+      }
+    }
+
+    String[] additionalResultClassNames = null;
+    if (resultClassName != null) {
+      additionalResultClassNames = getAllButFirstToken(resultClassName);
+      resultClassName = getFirstToken(resultClassName);
+    }
+    Class[] additionalResultClasses = null;
+    if (additionalResultClassNames != null) {
+      additionalResultClasses = new Class[additionalResultClassNames.length];
+      for (int i = 0; i < additionalResultClassNames.length; i++) {
+        additionalResultClasses[i] = resolveClass(additionalResultClassNames[i]);
+      }
+    }
+
+    Integer timeoutInt = timeout == null ? null : new Integer(timeout);
+    Integer fetchSizeInt = fetchSize == null ? null : new Integer(fetchSize);
+
+    // 2.x -- boolean allowRemappingBool = "true".equals(allowRemapping);
+
+    SqlSource sqlSource = new SqlSourceFactory(mapParser).newSqlSourceIntance(mapParser, context);
+
+
+    MappedStatement.Builder builder = new MappedStatement.Builder(configuration, id, sqlSource);
+
+    if (parameterMapName != null) {
+      parameterMapName = mapParser.applyNamespace(parameterMapName);
+      builder.parameterMap(configuration.getParameterMap(parameterMapName));
+    } else if (parameterClassName != null) {
+      Class parameterClass = resolveClass(parameterClassName);
+      List<ParameterMapping> parameterMappings = new ArrayList<ParameterMapping>();
+      if (sqlSource instanceof SimpleSqlSource) {
+        parameterMappings = sqlSource.getParameterMappings(null);
+      }
+      ParameterMap.Builder parameterMapBuilder = new ParameterMap.Builder(id + "-ParameterMap", parameterClass, parameterMappings);
+      builder.parameterMap(parameterMapBuilder.build());
+    }
+
+    List<ResultMap> resultMaps = new ArrayList<ResultMap>();
+    if (resultMapName != null) {
+      resultMaps.add(configuration.getResultMap(resultMapName));
+      if (additionalResultMapNames != null) {
+        for (String additionalResultMapName : additionalResultMapNames) {
+          resultMaps.add(configuration.getResultMap(additionalResultMapName));
+        }
+      }
+    } else if (resultClassName != null) {
+      Class resultClass = resolveClass(resultClassName);
+      ResultMap.Builder resultMapBuilder = new ResultMap.Builder(id + "-ResultMap", resultClass, new ArrayList<ResultMapping>());
+      resultMaps.add(resultMapBuilder.build());
+      if (additionalResultClasses != null) {
+        for (Class additionalResultClass : additionalResultClasses) {
+          resultMapBuilder = new ResultMap.Builder(id + "-ResultMap", additionalResultClass, new ArrayList<ResultMapping>());
+          resultMaps.add(resultMapBuilder.build());
+        }
+      }
+    }
+    builder.resultMaps(resultMaps);
+
+    builder.fetchSize(fetchSizeInt);
+
+    builder.timeout(timeoutInt);
+
+    if (cacheModelName != null) {
+      cacheModelName = mapParser.applyNamespace(cacheModelName);
+      Cache cache = configuration.getCache(cacheModelName);
+      builder.cache(cache);
+    }
+
+    if (resultSetType != null) {
+      builder.resultSetType(ResultSetType.valueOf(resultSetType));
+    }
+
+    // allowRemappingBool -- silently ignored
+
+    findAndParseSelectKey(id, context);
+
+    configuration.addMappedStatement(builder.build());
+  }
+
+  private Class resolveClass(String resultClassName) {
+    try {
+      if (resultClassName != null) {
+        String name = configuration.getTypeAliasRegistry().resolveAlias(resultClassName);
+        return Resources.classForName(name);
+      } else {
+        return null;
+      }
+    } catch (ClassNotFoundException e) {
+      throw new SqlMapException("Error.  Could not initialize class.  Cause: " + e, e);
+    }
+  }
+
+  private void findAndParseSelectKey(String parentId, NodeletContext context) {
+    try {
+      boolean runStatementFirst = false;
+      NodeList children = context.getNode().getChildNodes();
+      for (int i = 0; i < children.getLength(); i++) {
+        Node child = children.item(i);
+        if (child.getNodeType() == Node.CDATA_SECTION_NODE
+            || child.getNodeType() == Node.TEXT_NODE) {
+          String data = ((CharacterData) child).getData();
+          if (data.trim().length() > 0) {
+            runStatementFirst = true;
+          }
+        } else if (child.getNodeType() == Node.ELEMENT_NODE
+            && "selectKey".equals(child.getNodeName())) {
+          buildSelectKeyStatement(parentId, new NodeletContext(child, configuration.getVariables()), runStatementFirst);
+
+          break;
+        }
+      }
+    } catch (ClassNotFoundException e) {
+      throw new RuntimeException("Error loading result class.  Cause: " + e, e);
+    }
+  }
+
+  public String getFirstToken(String s) {
+    return new StringTokenizer(s, ", ", false).nextToken();
+  }
+
+  public String[] getAllButFirstToken(String s) {
+    List strings = new ArrayList();
+    StringTokenizer parser = new StringTokenizer(s, ", ", false);
+    parser.nextToken();
+    while (parser.hasMoreTokens()) {
+      strings.add(parser.nextToken());
+    }
+    return (String[]) strings.toArray(new String[strings.size()]);
+  }
+
+  private void buildSelectKeyStatement(String parentId, NodeletContext context, boolean runStatementFirstParam) throws ClassNotFoundException {
+    final String keyPropName = context.getStringAttribute("keyProperty");
+    String resultClassName = context.getStringAttribute("resultClass");
+    final SimpleSqlSource source = new SimpleSqlSource(mapParser, context);
+
+    final boolean runStatementFirst = "post".equalsIgnoreCase(context.getStringAttribute("type", runStatementFirstParam ? "post" : "pre"));
+    final String keyStatementId = SqlMapSessionImpl.selectKeyIdFor(parentId);
+    TypeHandler typeHandler = configuration.getTypeHandlerRegistry().getUnkownTypeHandler();
+    if (resultClassName != null) {
+      resultClassName = configuration.getTypeAliasRegistry().resolveAlias(resultClassName);
+      final Class resultClass = Resources.classForName(resultClassName);
+      typeHandler = configuration.getTypeHandlerRegistry().getTypeHandler(resultClass);
+    }
+
+    ResultMapping.Builder mappingBuilder = new ResultMapping.Builder(keyPropName, keyPropName, typeHandler);
+    ArrayList<ResultMapping> resultMappingArrayList = new ArrayList<ResultMapping>();
+    resultMappingArrayList.add(mappingBuilder.build());
+
+    ResultMap.Builder resultMapBuilder = new ResultMap.Builder(keyStatementId + "ResultMap", HashMap.class, resultMappingArrayList);
+    ArrayList<ResultMap> resultMapList = new ArrayList<ResultMap>();
+    resultMapList.add(resultMapBuilder.build());
+
+    MappedStatement.Builder builder = new MappedStatement.Builder(configuration, keyStatementId, source);
+    builder.resultMaps(resultMapList);
+
+    configuration.setPostSelectKey(keyStatementId, runStatementFirst);
+    configuration.addMappedStatement(builder.build());
+  }
+
+}