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 [6/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/mapping/sql/dynamic/elements/IterateTagHandler.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/mapping/sql/dynamic/elements/IterateTagHandler.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/mapping/sql/dynamic/elements/IterateTagHandler.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/mapping/sql/dynamic/elements/IterateTagHandler.java Thu Aug  7 16:21:46 2008
@@ -0,0 +1,112 @@
+package com.ibatis.sqlmap.engine.mapping.sql.dynamic.elements;
+
+import org.apache.ibatis.reflection.MetaObject;
+
+public class IterateTagHandler extends BaseTagHandler {
+
+  public int doStartFragment(SqlTagContext ctx, SqlTag tag, Object parameterObject) {
+    IterateContext iterate = (IterateContext) ctx.getAttribute(tag);
+    if (iterate == null) {
+      IterateContext parentIterate = ctx.peekIterateContext();
+
+      ctx.pushRemoveFirstPrependMarker(tag);
+
+      Object collection;
+      String prop = tag.getPropertyAttr();
+      if (prop != null && !prop.equals("")) {
+        if (null != parentIterate && parentIterate.isAllowNext()) {
+          parentIterate.next();
+          parentIterate.setAllowNext(false);
+          if (!parentIterate.hasNext()) {
+            parentIterate.setFinal(true);
+          }
+        }
+
+        if (parentIterate != null) {
+          prop = parentIterate.addIndexToTagProperty(prop);
+        }
+
+        collection = MetaObject.forObject(parameterObject).getValue(prop);
+      } else {
+        collection = parameterObject;
+      }
+      iterate = new IterateContext(collection, tag, parentIterate);
+
+      iterate.setProperty(null == prop ? "" : prop);
+
+      ctx.setAttribute(tag, iterate);
+      ctx.pushIterateContext(iterate);
+    } else if ("iterate".equals(tag.getRemoveFirstPrepend())) {
+      ctx.reEnableRemoveFirstPrependMarker();
+    }
+
+    if (iterate.hasNext()) {
+      return INCLUDE_BODY;
+    } else {
+      return SKIP_BODY;
+    }
+  }
+
+  public int doEndFragment(SqlTagContext ctx, SqlTag tag, Object parameterObject, StringBuffer bodyContent) {
+    IterateContext iterate = (IterateContext) ctx.getAttribute(tag);
+
+    if (iterate.hasNext() || iterate.isFinal()) {
+
+      if (iterate.isAllowNext()) {
+        iterate.next();
+      }
+
+      if (bodyContent.toString().trim().length() > 0) {
+        // the sub element produced a result.  If it is the first one
+        // to produce a result, then we need to add the open
+        // text.  If it is not the first to produce a result then
+        // we need to add the conjunction text
+        if (iterate.someSubElementsHaveContent()) {
+          if (tag.isConjunctionAvailable()) {
+            bodyContent.insert(0, tag.getConjunctionAttr());
+          }
+        } else {
+          // we need to specify that this is the first content
+          // producing element so that the doPrepend method will
+          // add the prepend
+          iterate.setPrependEnabled(true);
+
+          if (tag.isOpenAvailable()) {
+            bodyContent.insert(0, tag.getOpenAttr());
+          }
+        }
+        iterate.setSomeSubElementsHaveContent(true);
+      }
+
+      if (iterate.isLast() && iterate.someSubElementsHaveContent()) {
+        if (tag.isCloseAvailable()) {
+          bodyContent.append(tag.getCloseAttr());
+        }
+      }
+
+      iterate.setAllowNext(true);
+      if (iterate.isFinal()) {
+        return super.doEndFragment(ctx, tag, parameterObject, bodyContent);
+      } else {
+        return REPEAT_BODY;
+      }
+
+    } else {
+      return super.doEndFragment(ctx, tag, parameterObject, bodyContent);
+    }
+  }
+
+  public void doPrepend(SqlTagContext ctx, SqlTag tag, Object parameterObject, StringBuffer bodyContent) {
+    IterateContext iterate = (IterateContext) ctx.getAttribute(tag);
+    if (iterate.isPrependEnabled()) {
+      super.doPrepend(ctx, tag, parameterObject, bodyContent);
+      iterate.setPrependEnabled(false);  // only do the prepend one time
+    }
+  }
+
+  public boolean isPostParseRequired() {
+    return true;
+  }
+
+}
+

Added: ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/mapping/sql/dynamic/elements/RemoveFirstPrependMarker.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/mapping/sql/dynamic/elements/RemoveFirstPrependMarker.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/mapping/sql/dynamic/elements/RemoveFirstPrependMarker.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/mapping/sql/dynamic/elements/RemoveFirstPrependMarker.java Thu Aug  7 16:21:46 2008
@@ -0,0 +1,41 @@
+package com.ibatis.sqlmap.engine.mapping.sql.dynamic.elements;
+
+/**
+ * This inner class i used strictly to house whether the
+ * removeFirstPrepend has been used in a particular nested
+ * situation.
+ *
+ * @author Brandon Goodin
+ */
+class RemoveFirstPrependMarker {
+
+  private boolean removeFirstPrepend;
+  private SqlTag tag;
+
+  public RemoveFirstPrependMarker(SqlTag tag, boolean removeFirstPrepend) {
+    this.removeFirstPrepend = removeFirstPrepend;
+    this.tag = tag;
+  }
+
+  /**
+   * @return Returns the removeFirstPrepend.
+   */
+  public boolean isRemoveFirstPrepend() {
+    return removeFirstPrepend;
+  }
+
+  /**
+   * @param removeFirstPrepend The removeFirstPrepend to set.
+   */
+  public void setRemoveFirstPrepend(boolean removeFirstPrepend) {
+    this.removeFirstPrepend = removeFirstPrepend;
+  }
+
+  /**
+   * @return Returns the sqlTag.
+   */
+  public SqlTag getSqlTag() {
+    return tag;
+  }
+
+}

Added: ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/mapping/sql/dynamic/elements/SqlTag.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/mapping/sql/dynamic/elements/SqlTag.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/mapping/sql/dynamic/elements/SqlTag.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/mapping/sql/dynamic/elements/SqlTag.java Thu Aug  7 16:21:46 2008
@@ -0,0 +1,156 @@
+package com.ibatis.sqlmap.engine.mapping.sql.dynamic.elements;
+
+import com.ibatis.sqlmap.engine.mapping.sql.SqlChild;
+
+import java.util.*;
+
+public class SqlTag implements SqlChild, DynamicParent {
+
+  private String name;
+  private SqlTagHandler handler;
+
+  // general attributes
+  private String prependAttr;
+  private String propertyAttr;
+  private String removeFirstPrepend;
+
+  // conditional attributes
+  private String comparePropertyAttr;
+  private String compareValueAttr;
+
+  // iterate attributes
+  private String openAttr;
+  private String closeAttr;
+  private String conjunctionAttr;
+
+  private SqlTag parent;
+  private List children = new ArrayList();
+
+  private boolean postParseRequired = false;
+
+  public String getName() {
+    return name;
+  }
+
+  public void setName(String name) {
+    this.name = name;
+  }
+
+  public SqlTagHandler getHandler() {
+    return handler;
+  }
+
+  public void setHandler(SqlTagHandler handler) {
+    this.handler = handler;
+  }
+
+  public boolean isPrependAvailable() {
+    return prependAttr != null && prependAttr.length() > 0;
+  }
+
+  public boolean isCloseAvailable() {
+    return closeAttr != null && closeAttr.length() > 0;
+  }
+
+  public boolean isOpenAvailable() {
+    return openAttr != null && openAttr.length() > 0;
+  }
+
+  public boolean isConjunctionAvailable() {
+    return conjunctionAttr != null && conjunctionAttr.length() > 0;
+  }
+
+  public String getPrependAttr() {
+    return prependAttr;
+  }
+
+  public void setPrependAttr(String prependAttr) {
+    this.prependAttr = prependAttr;
+  }
+
+  public String getPropertyAttr() {
+    return propertyAttr;
+  }
+
+  public void setPropertyAttr(String propertyAttr) {
+    this.propertyAttr = propertyAttr;
+  }
+
+  public String getComparePropertyAttr() {
+    return comparePropertyAttr;
+  }
+
+  public void setComparePropertyAttr(String comparePropertyAttr) {
+    this.comparePropertyAttr = comparePropertyAttr;
+  }
+
+  public String getCompareValueAttr() {
+    return compareValueAttr;
+  }
+
+  public void setCompareValueAttr(String compareValueAttr) {
+    this.compareValueAttr = compareValueAttr;
+  }
+
+  public String getOpenAttr() {
+    return openAttr;
+  }
+
+  public void setOpenAttr(String openAttr) {
+    this.openAttr = openAttr;
+  }
+
+  public String getCloseAttr() {
+    return closeAttr;
+  }
+
+  public void setCloseAttr(String closeAttr) {
+    this.closeAttr = closeAttr;
+  }
+
+  public String getConjunctionAttr() {
+    return conjunctionAttr;
+  }
+
+  public void setConjunctionAttr(String conjunctionAttr) {
+    this.conjunctionAttr = conjunctionAttr;
+  }
+
+
+  public void addChild(SqlChild child) {
+    if (child instanceof SqlTag) {
+      ((SqlTag) child).parent = this;
+    }
+    children.add(child);
+  }
+
+  public Iterator getChildren() {
+    return children.iterator();
+  }
+
+  public SqlTag getParent() {
+    return parent;
+  }
+
+  public String getRemoveFirstPrepend() {
+    return removeFirstPrepend;
+  }
+
+  public void setRemoveFirstPrepend(String removeFirstPrepend) {
+    this.removeFirstPrepend = removeFirstPrepend;
+  }
+
+  /**
+   * @return Returns the postParseRequired.
+   */
+  public boolean isPostParseRequired() {
+    return postParseRequired;
+  }
+
+  /**
+   * @param iterateAncestor The postParseRequired to set.
+   */
+  public void setPostParseRequired(boolean iterateAncestor) {
+    this.postParseRequired = iterateAncestor;
+  }
+}

Added: ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/mapping/sql/dynamic/elements/SqlTagContext.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/mapping/sql/dynamic/elements/SqlTagContext.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/mapping/sql/dynamic/elements/SqlTagContext.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/mapping/sql/dynamic/elements/SqlTagContext.java Thu Aug  7 16:21:46 2008
@@ -0,0 +1,189 @@
+package com.ibatis.sqlmap.engine.mapping.sql.dynamic.elements;
+
+import org.apache.ibatis.mapping.ParameterMapping;
+
+import java.io.*;
+import java.util.*;
+
+public class SqlTagContext {
+
+  private StringWriter sw;
+  private PrintWriter out;
+
+  private HashMap attributes;
+
+  private LinkedList removeFirstPrependStack;
+  private LinkedList iterateContextStack;
+
+  private List<ParameterMapping> parameterMappings = new ArrayList<ParameterMapping>();
+  private String dynamicSql;
+
+
+  public SqlTagContext() {
+    sw = new StringWriter();
+    out = new PrintWriter(sw);
+    attributes = new HashMap();
+    removeFirstPrependStack = new LinkedList();
+    iterateContextStack = new LinkedList();
+  }
+
+  public PrintWriter getWriter() {
+    return out;
+  }
+
+  public String getBodyText() {
+    out.flush();
+    return sw.getBuffer().toString();
+  }
+
+  public void setAttribute(Object key, Object value) {
+    attributes.put(key, value);
+  }
+
+  public Object getAttribute(Object key) {
+    return attributes.get(key);
+  }
+
+  public void addParameterMapping(ParameterMapping mapping) {
+    parameterMappings.add(mapping);
+  }
+
+  public List<ParameterMapping> getParameterMappings() {
+    return parameterMappings;
+  }
+
+  public boolean isEmptyRemoveFirtPrepend() {
+    return removeFirstPrependStack.size() <= 0;
+  }
+
+  /**
+   * examine the value of the top RemoveFirstPrependMarker object on the stack.
+   *
+   * @param sqlTag
+   * @return was the first prepend removed
+   */
+  public boolean peekRemoveFirstPrependMarker(SqlTag sqlTag) {
+
+    RemoveFirstPrependMarker removeFirstPrepend =
+        (RemoveFirstPrependMarker) removeFirstPrependStack.get(1);
+
+    return removeFirstPrepend.isRemoveFirstPrepend();
+  }
+
+  /**
+   * pop the first RemoveFirstPrependMarker once the recursion is on it's way out
+   * of the recursion loop and return it's internal value.
+   *
+   * @param tag
+   */
+  public void popRemoveFirstPrependMarker(SqlTag tag) {
+
+    RemoveFirstPrependMarker removeFirstPrepend =
+        (RemoveFirstPrependMarker) removeFirstPrependStack.getFirst();
+
+    if (tag == removeFirstPrepend.getSqlTag()) {
+      removeFirstPrependStack.removeFirst();
+    }
+  }
+
+  /**
+   * push a new RemoveFirstPrependMarker object with the specified internal state
+   *
+   * @param tag
+   */
+  public void pushRemoveFirstPrependMarker(SqlTag tag) {
+
+    if (tag.getHandler() instanceof DynamicTagHandler) {
+      // this was added to retain default behavior
+      if (tag.isPrependAvailable()) {
+        removeFirstPrependStack.addFirst(
+            new RemoveFirstPrependMarker(tag, true));
+      } else {
+        removeFirstPrependStack.addFirst(
+            new RemoveFirstPrependMarker(tag, false));
+      }
+    } else if ("true".equals(tag.getRemoveFirstPrepend())
+        || "iterate".equals(tag.getRemoveFirstPrepend())) {
+      // you must be specific about the removal otherwise it
+      // will function as ibatis has always functioned and add
+      // the prepend
+      removeFirstPrependStack.addFirst(
+          new RemoveFirstPrependMarker(tag, true));
+    } else if (!tag.isPrependAvailable() &&
+        !"true".equals(tag.getRemoveFirstPrepend()) &&
+        !"iterate".equals(tag.getRemoveFirstPrepend()) &&
+        tag.getParent() != null) {
+      // if no prepend or removeFirstPrepend is specified 
+      // we need to look to the parent tag for default values
+      if ("true".equals(tag.getParent().getRemoveFirstPrepend())
+          || "iterate".equals(tag.getParent().getRemoveFirstPrepend())) {
+        removeFirstPrependStack.addFirst(
+            new RemoveFirstPrependMarker(tag, true));
+      }
+    } else {
+      removeFirstPrependStack.addFirst(
+          new RemoveFirstPrependMarker(tag, false));
+    }
+
+  }
+
+  /**
+   * set a new internal state for top RemoveFirstPrependMarker object
+   */
+  public void disableRemoveFirstPrependMarker() {
+    ((RemoveFirstPrependMarker) removeFirstPrependStack.get(1)).setRemoveFirstPrepend(false);
+  }
+
+  public void reEnableRemoveFirstPrependMarker() {
+    ((RemoveFirstPrependMarker) removeFirstPrependStack.get(0)).setRemoveFirstPrepend(true);
+  }
+
+  /**
+   * iterate context is stored here for nested dynamic tags in
+   * the body of the iterate tag
+   *
+   * @param iterateContext
+   */
+  public void pushIterateContext(IterateContext iterateContext) {
+    iterateContextStack.addFirst(iterateContext);
+  }
+
+  /**
+   * iterate context is removed here from the stack when iterate tag is finished being
+   * processed
+   *
+   * @return the top element of the context stack
+   */
+  public IterateContext popIterateContext() {
+    IterateContext retVal = null;
+    if (!iterateContextStack.isEmpty()) {
+      retVal = (IterateContext) iterateContextStack.removeFirst();
+    }
+    return retVal;
+  }
+
+  /**
+   * iterate context is removed here from the stack when iterate tag is finished being
+   * processed
+   *
+   * @return the top element on the context stack
+   */
+  public IterateContext peekIterateContext() {
+    IterateContext retVal = null;
+    if (!iterateContextStack.isEmpty()) {
+      retVal = (IterateContext) iterateContextStack.getFirst();
+    }
+    return retVal;
+  }
+
+
+  public void setDynamicSql(String dynamicSql) {
+    this.dynamicSql = dynamicSql;
+  }
+
+  public String getDynamicSql() {
+    return dynamicSql;
+  }
+
+}
+

Added: ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/mapping/sql/dynamic/elements/SqlTagHandler.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/mapping/sql/dynamic/elements/SqlTagHandler.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/mapping/sql/dynamic/elements/SqlTagHandler.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/mapping/sql/dynamic/elements/SqlTagHandler.java Thu Aug  7 16:21:46 2008
@@ -0,0 +1,16 @@
+package com.ibatis.sqlmap.engine.mapping.sql.dynamic.elements;
+
+public interface SqlTagHandler {
+
+  // BODY TAG
+  public static final int SKIP_BODY = 0;
+  public static final int INCLUDE_BODY = 1;
+  public static final int REPEAT_BODY = 2;
+
+  public int doStartFragment(SqlTagContext ctx, SqlTag tag, Object parameterObject);
+
+  public int doEndFragment(SqlTagContext ctx, SqlTag tag, Object parameterObject, StringBuffer bodyContent);
+
+  public void doPrepend(SqlTagContext ctx, SqlTag tag, Object parameterObject, StringBuffer bodyContent);
+
+}

Added: ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/mapping/sql/dynamic/elements/SqlTagHandlerFactory.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/mapping/sql/dynamic/elements/SqlTagHandlerFactory.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/mapping/sql/dynamic/elements/SqlTagHandlerFactory.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/mapping/sql/dynamic/elements/SqlTagHandlerFactory.java Thu Aug  7 16:21:46 2008
@@ -0,0 +1,35 @@
+package com.ibatis.sqlmap.engine.mapping.sql.dynamic.elements;
+
+import java.util.*;
+
+public class SqlTagHandlerFactory {
+
+  private static final Map HANDLER_MAP = new HashMap();
+
+  static {
+    HANDLER_MAP.put("isEmpty", new IsEmptyTagHandler());
+    HANDLER_MAP.put("isEqual", new IsEqualTagHandler());
+    HANDLER_MAP.put("isGreaterEqual", new IsGreaterEqualTagHandler());
+    HANDLER_MAP.put("isGreaterThan", new IsGreaterThanTagHandler());
+    HANDLER_MAP.put("isLessEqual", new IsLessEqualTagHandler());
+    HANDLER_MAP.put("isLessThan", new IsLessThanTagHandler());
+    HANDLER_MAP.put("isNotEmpty", new IsNotEmptyTagHandler());
+    HANDLER_MAP.put("isNotEqual", new IsNotEqualTagHandler());
+    HANDLER_MAP.put("isNotNull", new IsNotNullTagHandler());
+    HANDLER_MAP.put("isNotParameterPresent", new IsNotParameterPresentTagHandler());
+    HANDLER_MAP.put("isNotPropertyAvailable", new IsNotPropertyAvailableTagHandler());
+    HANDLER_MAP.put("isNull", new IsNullTagHandler());
+    HANDLER_MAP.put("isParameterPresent", new IsParameterPresentTagHandler());
+    HANDLER_MAP.put("isPropertyAvailable", new IsPropertyAvailableTagHandler());
+    HANDLER_MAP.put("iterate", new IterateTagHandler());
+    HANDLER_MAP.put("dynamic", new DynamicTagHandler());
+  }
+
+  private SqlTagHandlerFactory() {
+  }
+
+  public static SqlTagHandler getSqlTagHandler(String name) {
+    return (SqlTagHandler) HANDLER_MAP.get(name);
+  }
+
+}

Added: ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/mapping/sql/raw/RawSql.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/mapping/sql/raw/RawSql.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/mapping/sql/raw/RawSql.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/mapping/sql/raw/RawSql.java Thu Aug  7 16:21:46 2008
@@ -0,0 +1,35 @@
+package com.ibatis.sqlmap.engine.mapping.sql.raw;
+
+import com.ibatis.sqlmap.engine.mapping.sql.Sql;
+import org.apache.ibatis.mapping.*;
+
+import java.util.List;
+
+/**
+ * A non-executable SQL container simply for
+ * communicating raw SQL around the framework.
+ */
+public class RawSql implements Sql {
+
+  private String sql;
+
+  public RawSql(String sql) {
+    this.sql = sql;
+  }
+
+  public String getSql(Object parameterObject) {
+    return sql;
+  }
+
+  public List<ParameterMapping> getParameterMappings(Object parameterObject) {
+    return null;
+  }
+
+  public ParameterMap getParameterMap(Object parameterObject) {
+    throw new RuntimeException("Method not implemented on RawSql.");
+  }
+
+
+}
+
+

Added: ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/mapping/sql/simple/SimpleDynamicSql.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/mapping/sql/simple/SimpleDynamicSql.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/mapping/sql/simple/SimpleDynamicSql.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/mapping/sql/simple/SimpleDynamicSql.java Thu Aug  7 16:21:46 2008
@@ -0,0 +1,84 @@
+package com.ibatis.sqlmap.engine.mapping.sql.simple;
+
+import com.ibatis.sqlmap.client.SqlMapException;
+import com.ibatis.sqlmap.engine.mapping.sql.Sql;
+import org.apache.ibatis.mapping.ParameterMapping;
+import org.apache.ibatis.reflection.MetaObject;
+import org.apache.ibatis.type.TypeHandlerRegistry;
+
+import java.util.*;
+
+public class SimpleDynamicSql implements Sql {
+
+  private static final String ELEMENT_TOKEN = "$";
+
+  private String sqlStatement;
+  private List<ParameterMapping> parameterMappings;
+  TypeHandlerRegistry typeHandlerRegistry;
+
+  public SimpleDynamicSql(String sqlStatement, List<ParameterMapping> parameterMappings, TypeHandlerRegistry typeHandlerRegistry) {
+    this.sqlStatement = sqlStatement;
+    this.parameterMappings = parameterMappings;
+    this.typeHandlerRegistry = typeHandlerRegistry;
+  }
+
+  public String getSql(Object parameterObject) {
+    return processDynamicElements(sqlStatement, parameterObject);
+  }
+
+  public List<ParameterMapping> getParameterMappings(Object parameterObject) {
+    return parameterMappings;
+  }
+
+  public static boolean isSimpleDynamicSql(String sql) {
+    return sql != null && sql.indexOf(ELEMENT_TOKEN) > -1;
+  }
+
+  private String processDynamicElements(String sql, Object parameterObject) {
+    StringTokenizer parser = new StringTokenizer(sql, ELEMENT_TOKEN, true);
+    StringBuffer newSql = new StringBuffer();
+
+    String token = null;
+    String lastToken = null;
+    while (parser.hasMoreTokens()) {
+      token = parser.nextToken();
+
+      if (ELEMENT_TOKEN.equals(lastToken)) {
+        if (ELEMENT_TOKEN.equals(token)) {
+          newSql.append(ELEMENT_TOKEN);
+          token = null;
+        } else {
+
+          Object value = null;
+          if (parameterObject != null) {
+            if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {
+              value = parameterObject;
+            } else {
+              value = MetaObject.forObject(parameterObject).getValue(token);
+            }
+          }
+          if (value != null) {
+            newSql.append(String.valueOf(value));
+          }
+
+          token = parser.nextToken();
+          if (!ELEMENT_TOKEN.equals(token)) {
+            throw new SqlMapException("Unterminated dynamic element in sql (" + sql + ").");
+          }
+          token = null;
+        }
+      } else {
+        if (!ELEMENT_TOKEN.equals(token)) {
+          newSql.append(token);
+        }
+      }
+
+      lastToken = token;
+    }
+
+    return newSql.toString();
+  }
+
+
+}
+

Added: ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/mapping/sql/statik/StaticSql.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/mapping/sql/statik/StaticSql.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/mapping/sql/statik/StaticSql.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/mapping/sql/statik/StaticSql.java Thu Aug  7 16:21:46 2008
@@ -0,0 +1,23 @@
+package com.ibatis.sqlmap.engine.mapping.sql.statik;
+
+import com.ibatis.sqlmap.engine.mapping.sql.Sql;
+import org.apache.ibatis.mapping.ParameterMapping;
+
+import java.util.List;
+
+public class StaticSql implements Sql {
+
+  private String sqlStatement;
+
+  public StaticSql(String sqlStatement) {
+    this.sqlStatement = sqlStatement.replace('\r', ' ').replace('\n', ' ');
+  }
+
+  public String getSql(Object parameterObject) {
+    return sqlStatement;
+  }
+
+  public List<ParameterMapping> getParameterMappings(Object parameterObject) {
+    return null;
+  }
+}

Added: ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/mapping/statement/PaginatedDataList.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/mapping/statement/PaginatedDataList.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/mapping/statement/PaginatedDataList.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/mapping/statement/PaginatedDataList.java Thu Aug  7 16:21:46 2008
@@ -0,0 +1,260 @@
+package com.ibatis.sqlmap.engine.mapping.statement;
+
+
+import com.ibatis.common.util.PaginatedList;
+import com.ibatis.sqlmap.client.SqlMapExecutor;
+
+import java.sql.SQLException;
+import java.util.*;
+
+public class PaginatedDataList implements PaginatedList {
+
+  private SqlMapExecutor sqlMapExecutor;
+  private String statementName;
+  private Object parameterObject;
+
+  private int pageSize;
+  private int index;
+
+  private List prevPageList;
+  private List currentPageList;
+  private List nextPageList;
+
+  public PaginatedDataList(SqlMapExecutor sqlMapExecutor, String statementName, Object parameterObject, int pageSize)
+      throws SQLException {
+    this.sqlMapExecutor = sqlMapExecutor;
+    this.statementName = statementName;
+    this.parameterObject = parameterObject;
+    this.pageSize = pageSize;
+    this.index = 0;
+    pageTo(0);
+  }
+
+  private void pageForward() {
+    try {
+      prevPageList = currentPageList;
+      currentPageList = nextPageList;
+      nextPageList = getList(index + 1, pageSize);
+    } catch (SQLException e) {
+      throw new RuntimeException("Unexpected error while repaginating paged list.  Cause: " + e, e);
+    }
+  }
+
+  private void pageBack() {
+    try {
+      nextPageList = currentPageList;
+      currentPageList = prevPageList;
+      if (index > 0) {
+        prevPageList = getList(index - 1, pageSize);
+      } else {
+        prevPageList = new ArrayList();
+      }
+    } catch (SQLException e) {
+      throw new RuntimeException("Unexpected error while repaginating paged list.  Cause: " + e, e);
+    }
+  }
+
+  private void safePageTo(int idx) {
+    try {
+      pageTo(idx);
+    } catch (SQLException e) {
+      throw new RuntimeException("Unexpected error while repaginating paged list.  Cause: " + e, e);
+    }
+  }
+
+  public void pageTo(int idx) throws SQLException {
+    index = idx;
+
+    List list;
+
+    if (idx < 1) {
+      list = getList(idx, pageSize * 2);
+    } else {
+      list = getList(idx - 1, pageSize * 3);
+    }
+
+    if (list.size() < 1) {
+      prevPageList = new ArrayList(0);
+      currentPageList = new ArrayList(0);
+      nextPageList = new ArrayList(0);
+    } else {
+      if (idx < 1) {
+        prevPageList = new ArrayList(0);
+        if (list.size() <= pageSize) {
+          currentPageList = list.subList(0, list.size());
+          nextPageList = new ArrayList(0);
+        } else {
+          currentPageList = list.subList(0, pageSize);
+          nextPageList = list.subList(pageSize, list.size());
+        }
+      } else {
+        if (list.size() <= pageSize) {
+          prevPageList = list.subList(0, list.size());
+          currentPageList = new ArrayList(0);
+          nextPageList = new ArrayList(0);
+        } else if (list.size() <= pageSize * 2) {
+          prevPageList = list.subList(0, pageSize);
+          currentPageList = list.subList(pageSize, list.size());
+          nextPageList = new ArrayList(0);
+        } else {
+          prevPageList = list.subList(0, pageSize);
+          currentPageList = list.subList(pageSize, pageSize * 2);
+          nextPageList = list.subList(pageSize * 2, list.size());
+        }
+      }
+    }
+
+  }
+
+
+  private List getList(int idx, int localPageSize) throws SQLException {
+    return sqlMapExecutor.queryForList(statementName, parameterObject, (idx) * pageSize, localPageSize);
+  }
+
+
+  public boolean nextPage() {
+    if (isNextPageAvailable()) {
+      index++;
+      pageForward();
+      return true;
+    } else {
+      return false;
+    }
+  }
+
+  public boolean previousPage() {
+    if (isPreviousPageAvailable()) {
+      index--;
+      pageBack();
+      return true;
+    } else {
+      return false;
+    }
+  }
+
+  public void gotoPage(int pageNumber) {
+    safePageTo(pageNumber);
+  }
+
+  public int getPageSize() {
+    return pageSize;
+  }
+
+  public boolean isFirstPage() {
+    return index == 0;
+  }
+
+  public boolean isMiddlePage() {
+    return !(isFirstPage() || isLastPage());
+  }
+
+  public boolean isLastPage() {
+    return nextPageList.size() < 1;
+  }
+
+  public boolean isNextPageAvailable() {
+    return nextPageList.size() > 0;
+  }
+
+  public boolean isPreviousPageAvailable() {
+    return prevPageList.size() > 0;
+  }
+
+  public int size() {
+    return currentPageList.size();
+  }
+
+  public boolean isEmpty() {
+    return currentPageList.isEmpty();
+  }
+
+  public boolean contains(Object o) {
+    return currentPageList.contains(o);
+  }
+
+  public Iterator iterator() {
+    return currentPageList.iterator();
+  }
+
+  public Object[] toArray() {
+    return currentPageList.toArray();
+  }
+
+  public Object[] toArray(Object a[]) {
+    return currentPageList.toArray(a);
+  }
+
+  public boolean containsAll(Collection c) {
+    return currentPageList.containsAll(c);
+  }
+
+  public Object get(int index) {
+    return currentPageList.get(index);
+  }
+
+  public int indexOf(Object o) {
+    return currentPageList.indexOf(o);
+  }
+
+  public int lastIndexOf(Object o) {
+    return currentPageList.lastIndexOf(o);
+  }
+
+  public ListIterator listIterator() {
+    return currentPageList.listIterator();
+  }
+
+  public ListIterator listIterator(int index) {
+    return currentPageList.listIterator(index);
+  }
+
+  public List subList(int fromIndex, int toIndex) {
+    return currentPageList.subList(fromIndex, toIndex);
+  }
+
+  public boolean add(Object o) {
+    return currentPageList.add(o);
+  }
+
+  public boolean remove(Object o) {
+    return currentPageList.remove(o);
+  }
+
+  public boolean addAll(Collection c) {
+    return currentPageList.addAll(c);
+  }
+
+  public boolean addAll(int index, Collection c) {
+    return currentPageList.addAll(index, c);
+  }
+
+  public boolean removeAll(Collection c) {
+    return currentPageList.removeAll(c);
+  }
+
+  public boolean retainAll(Collection c) {
+    return currentPageList.retainAll(c);
+  }
+
+  public void clear() {
+    currentPageList.clear();
+  }
+
+  public Object set(int index, Object element) {
+    return currentPageList.set(index, element);
+  }
+
+  public void add(int index, Object element) {
+    currentPageList.add(index, element);
+  }
+
+  public Object remove(int index) {
+    return currentPageList.remove(index);
+  }
+
+
+  public int getPageIndex() {
+    return index;
+  }
+
+}

Added: ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/transaction/BaseTransaction.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/transaction/BaseTransaction.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/transaction/BaseTransaction.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/transaction/BaseTransaction.java Thu Aug  7 16:21:46 2008
@@ -0,0 +1,14 @@
+package com.ibatis.sqlmap.engine.transaction;
+
+public abstract class BaseTransaction implements Transaction {
+  private boolean commitRequired;
+
+  public boolean isCommitRequired() {
+    return commitRequired;
+  }
+
+  public void setCommitRequired(boolean commitRequired) {
+    this.commitRequired = commitRequired;
+  }
+
+}

Added: ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/transaction/BaseTransactionConfig.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/transaction/BaseTransactionConfig.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/transaction/BaseTransactionConfig.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/transaction/BaseTransactionConfig.java Thu Aug  7 16:21:46 2008
@@ -0,0 +1,26 @@
+package com.ibatis.sqlmap.engine.transaction;
+
+import javax.sql.DataSource;
+
+public abstract class BaseTransactionConfig implements TransactionConfig {
+
+  protected DataSource dataSource;
+  protected boolean forceCommit;
+
+  public boolean isForceCommit() {
+    return forceCommit;
+  }
+
+  public void setForceCommit(boolean forceCommit) {
+    this.forceCommit = forceCommit;
+  }
+
+  public DataSource getDataSource() {
+    return dataSource;
+  }
+
+  public void setDataSource(DataSource ds) {
+    this.dataSource = ds;
+  }
+
+}

Added: ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/transaction/IsolationLevel.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/transaction/IsolationLevel.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/transaction/IsolationLevel.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/transaction/IsolationLevel.java Thu Aug  7 16:21:46 2008
@@ -0,0 +1,31 @@
+package com.ibatis.sqlmap.engine.transaction;
+
+import java.sql.*;
+
+public class IsolationLevel {
+
+  public static final int UNSET_ISOLATION_LEVEL = -9999;
+
+  private int isolationLevel = UNSET_ISOLATION_LEVEL;
+  private int originalIsolationLevel = UNSET_ISOLATION_LEVEL;
+
+  public void setIsolationLevel(int isolationLevel) {
+    this.isolationLevel = isolationLevel;
+  }
+
+  public void applyIsolationLevel(Connection conn) throws SQLException {
+    if (isolationLevel != UNSET_ISOLATION_LEVEL) {
+      originalIsolationLevel = conn.getTransactionIsolation();
+      if (isolationLevel != originalIsolationLevel) {
+        conn.setTransactionIsolation(isolationLevel);
+      }
+    }
+  }
+
+  public void restoreIsolationLevel(Connection conn) throws SQLException {
+    if (isolationLevel != originalIsolationLevel) {
+      conn.setTransactionIsolation(originalIsolationLevel);
+    }
+  }
+
+}

Added: ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/transaction/Transaction.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/transaction/Transaction.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/transaction/Transaction.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/transaction/Transaction.java Thu Aug  7 16:21:46 2008
@@ -0,0 +1,21 @@
+package com.ibatis.sqlmap.engine.transaction;
+
+import org.apache.ibatis.executor.Executor;
+
+import java.sql.SQLException;
+
+public interface Transaction {
+
+  public void commit(boolean required) throws SQLException, TransactionException;
+
+  public void rollback(boolean required) throws SQLException, TransactionException;
+
+  public void close() throws SQLException, TransactionException;
+
+  public Executor getExecutor() throws SQLException, TransactionException;
+
+  public boolean isCommitRequired();
+
+  public void setCommitRequired(boolean commitRequired);
+
+}

Added: ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/transaction/TransactionConfig.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/transaction/TransactionConfig.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/transaction/TransactionConfig.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/transaction/TransactionConfig.java Thu Aug  7 16:21:46 2008
@@ -0,0 +1,25 @@
+package com.ibatis.sqlmap.engine.transaction;
+
+import org.apache.ibatis.mapping.Configuration;
+
+import javax.sql.DataSource;
+import java.sql.SQLException;
+import java.util.Properties;
+
+public interface TransactionConfig {
+
+  Transaction newTransaction(Configuration configuration, int transactionIsolation)
+      throws SQLException, TransactionException;
+
+  DataSource getDataSource();
+
+  void setDataSource(DataSource ds);
+
+  boolean isForceCommit();
+
+  void setForceCommit(boolean forceCommit);
+
+  void setProperties(Properties props)
+      throws SQLException, TransactionException;
+
+}

Added: ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/transaction/TransactionException.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/transaction/TransactionException.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/transaction/TransactionException.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/transaction/TransactionException.java Thu Aug  7 16:21:46 2008
@@ -0,0 +1,23 @@
+package com.ibatis.sqlmap.engine.transaction;
+
+import com.ibatis.sqlmap.client.SqlMapException;
+
+
+public class TransactionException extends SqlMapException {
+
+  public TransactionException() {
+  }
+
+  public TransactionException(String msg) {
+    super(msg);
+  }
+
+  public TransactionException(Throwable cause) {
+    super(cause);
+  }
+
+  public TransactionException(String msg, Throwable cause) {
+    super(msg, cause);
+  }
+
+}

Added: ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/transaction/TransactionManager.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/transaction/TransactionManager.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/transaction/TransactionManager.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/transaction/TransactionManager.java Thu Aug  7 16:21:46 2008
@@ -0,0 +1,122 @@
+package com.ibatis.sqlmap.engine.transaction;
+
+import com.ibatis.sqlmap.client.SqlMapException;
+import com.ibatis.sqlmap.engine.builder.Ibatis2Configuration;
+import com.ibatis.sqlmap.engine.transaction.user.UserProvidedTransaction;
+import org.apache.ibatis.mapping.Configuration;
+import org.apache.ibatis.executor.Executor;
+
+import java.sql.*;
+
+public class TransactionManager {
+
+  private ThreadLocal<Transaction> localTransaction = new ThreadLocal<Transaction>();
+
+  private TransactionConfig trasactionConfig;
+  private Configuration configuration;
+
+  public TransactionManager(Ibatis2Configuration config, TransactionConfig transactionConfig) {
+    this.trasactionConfig = transactionConfig;
+    this.configuration = config;
+  }
+
+  public void begin() throws SQLException, TransactionException {
+    begin(IsolationLevel.UNSET_ISOLATION_LEVEL);
+  }
+
+  public void begin(Connection connection) {
+    Transaction transaction = localTransaction.get();
+    if (transaction != null) {
+      throw new TransactionException("TransactionManager could not start a new transaction. " +
+          "A transaction is already started.");
+    }
+    transaction = new UserProvidedTransaction(configuration, connection);
+    transaction.setCommitRequired(false);
+    localTransaction.set(transaction);
+  }
+
+  public void begin(int transactionIsolation) throws SQLException, TransactionException {
+    Transaction transaction = localTransaction.get();
+    if (transaction != null) {
+      throw new TransactionException("TransactionManager could not start a new transaction.  " +
+          "A transaction is already started.");
+    }
+    transaction = trasactionConfig.newTransaction(configuration, transactionIsolation);
+    transaction.setCommitRequired(false);
+    localTransaction.set(transaction);
+  }
+
+  public void commit() throws SQLException, TransactionException {
+    Transaction trans = localTransaction.get();
+    if (trans == null) {
+      throw new TransactionException("TransactionManager could not commit.  No transaction is started.");
+    }
+    boolean required = trans.isCommitRequired() || trasactionConfig.isForceCommit();
+    trans.commit(required);
+    trans.setCommitRequired(false);
+  }
+
+  public void end() throws SQLException, TransactionException {
+    Transaction transaction = localTransaction.get();
+    if (transaction != null) {
+      try {
+        try {
+          boolean required = transaction.isCommitRequired() || trasactionConfig.isForceCommit();
+          transaction.rollback(required);
+        } finally {
+          transaction.setCommitRequired(false);
+          transaction.close();
+        }
+      } finally {
+        localTransaction.set(null);
+      }
+    }
+  }
+
+  public Connection getCurrentConnection() throws SQLException {
+    return getCurrentExecutor().getConnection();
+  }
+
+  public Executor getCurrentExecutor() throws SQLException {
+    return getCurrentTransaction().getExecutor();
+  }
+
+  public Transaction getCurrentTransaction() throws SQLException {
+    Transaction transaction = localTransaction.get();
+    if (transaction != null) {
+      try {
+        return transaction;
+      } catch (TransactionException e) {
+        throw new SqlMapException("Could not get transaction.  Cause: " + e, e);
+      }
+    }
+    throw new SQLException("Could not get current transaction, because there was no transaction started.");
+  }
+
+  public TransactionConfig getTrasactionConfig() {
+    return trasactionConfig;
+  }
+
+  public boolean isInTransaction() {
+    return this.localTransaction.get() != null;
+  }
+
+  public Object doInTransaction(TransactionScope transactionScope) throws SQLException {
+    Transaction transaction = this.localTransaction.get();
+    if (transaction == null) {
+      try {
+        begin();
+        transaction = this.localTransaction.get();
+        Object result = transactionScope.execute(transaction);
+        commit();
+        return result;
+      } finally {
+        end();
+      }
+    } else {
+      return transactionScope.execute(transaction);
+    }
+
+  }
+
+}
\ No newline at end of file

Added: ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/transaction/TransactionScope.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/transaction/TransactionScope.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/transaction/TransactionScope.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/transaction/TransactionScope.java Thu Aug  7 16:21:46 2008
@@ -0,0 +1,7 @@
+package com.ibatis.sqlmap.engine.transaction;
+
+import java.sql.SQLException;
+
+public interface TransactionScope {
+  Object execute(Transaction transaction) throws SQLException;
+}

Added: ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/transaction/external/ExternalTransaction.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/transaction/external/ExternalTransaction.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/transaction/external/ExternalTransaction.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/transaction/external/ExternalTransaction.java Thu Aug  7 16:21:46 2008
@@ -0,0 +1,73 @@
+package com.ibatis.sqlmap.engine.transaction.external;
+
+import com.ibatis.sqlmap.engine.transaction.*;
+import org.apache.ibatis.mapping.Configuration;
+import org.apache.ibatis.executor.Executor;
+
+import javax.sql.DataSource;
+import java.sql.*;
+
+public class ExternalTransaction extends BaseTransaction {
+
+  private DataSource dataSource;
+  private boolean defaultAutoCommit;
+  private boolean setAutoCommitAllowed;
+  private IsolationLevel isolationLevel = new IsolationLevel();
+  private Configuration configuration;
+  private Executor executor;
+
+  public ExternalTransaction(Configuration configuration, DataSource ds, boolean defaultAutoCommit, boolean setAutoCommitAllowed, int isolationLevel) throws TransactionException {
+    // Check Parameters
+    this.configuration = configuration;
+    dataSource = ds;
+    if (dataSource == null) {
+      throw new TransactionException("ExternalTransaction initialization failed.  DataSource was null.");
+    }
+
+    this.defaultAutoCommit = defaultAutoCommit;
+    this.setAutoCommitAllowed = setAutoCommitAllowed;
+    this.isolationLevel.setIsolationLevel(isolationLevel);
+  }
+
+  private void init() throws SQLException, TransactionException {
+    // Open JDBC Transaction
+    Connection connection = dataSource.getConnection();
+    if (connection == null) {
+      throw new TransactionException("ExternalTransaction could not start transaction.  Cause: The DataSource returned a null connection.");
+    }
+    // Isolation Level
+    isolationLevel.applyIsolationLevel(connection);
+    // AutoCommit
+    if (setAutoCommitAllowed) {
+      if (connection.getAutoCommit() != defaultAutoCommit) {
+        connection.setAutoCommit(defaultAutoCommit);
+      }
+    }
+    executor = configuration.newExecutor(connection);
+  }
+
+  public void commit(boolean required) throws SQLException, TransactionException {
+  }
+
+  public void rollback(boolean required) throws SQLException, TransactionException {
+  }
+
+  public void close() throws SQLException, TransactionException {
+    if (executor != null) {
+      try {
+        isolationLevel.restoreIsolationLevel(executor.getConnection());
+      } finally {
+        executor.close();
+        executor = null;
+      }
+    }
+  }
+
+  public Executor getExecutor() throws SQLException, TransactionException {
+    if (executor == null) {
+      init();
+    }
+    return executor;
+  }
+
+}

Added: ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/transaction/external/ExternalTransactionConfig.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/transaction/external/ExternalTransactionConfig.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/transaction/external/ExternalTransactionConfig.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/transaction/external/ExternalTransactionConfig.java Thu Aug  7 16:21:46 2008
@@ -0,0 +1,25 @@
+package com.ibatis.sqlmap.engine.transaction.external;
+
+import com.ibatis.sqlmap.engine.transaction.*;
+import org.apache.ibatis.mapping.Configuration;
+
+import java.sql.SQLException;
+import java.util.Properties;
+
+public class ExternalTransactionConfig extends BaseTransactionConfig {
+
+  private boolean defaultAutoCommit = false;
+  private boolean setAutoCommitAllowed = true;
+
+  public Transaction newTransaction(Configuration configuration, int transactionIsolation) throws SQLException, TransactionException {
+    return new ExternalTransaction(configuration, dataSource, defaultAutoCommit, setAutoCommitAllowed, transactionIsolation);
+  }
+
+  public void setProperties(Properties props) throws SQLException, TransactionException {
+    String dacProp = props.getProperty("DefaultAutoCommit");
+    String sacaProp = props.getProperty("SetAutoCommitAllowed");
+    defaultAutoCommit = "true".equals(dacProp);
+    setAutoCommitAllowed = "true".equals(sacaProp) || sacaProp == null;
+  }
+
+}

Added: ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/transaction/jdbc/JdbcTransaction.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/transaction/jdbc/JdbcTransaction.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/transaction/jdbc/JdbcTransaction.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/transaction/jdbc/JdbcTransaction.java Thu Aug  7 16:21:46 2008
@@ -0,0 +1,72 @@
+package com.ibatis.sqlmap.engine.transaction.jdbc;
+
+import com.ibatis.sqlmap.engine.transaction.*;
+import org.apache.ibatis.mapping.Configuration;
+import org.apache.ibatis.executor.Executor;
+
+import javax.sql.DataSource;
+import java.sql.*;
+
+public class JdbcTransaction extends BaseTransaction {
+
+  private DataSource dataSource;
+  private IsolationLevel isolationLevel = new IsolationLevel();
+  private Configuration configuration;
+  private Executor executor;
+
+  public JdbcTransaction(Configuration configuration, DataSource ds, int isolationLevel) throws TransactionException {
+    // Check Parameters
+    this.configuration = configuration;
+    dataSource = ds;
+    if (dataSource == null) {
+      throw new TransactionException("JdbcTransaction initialization failed.  DataSource was null.");
+    }
+    this.isolationLevel.setIsolationLevel(isolationLevel);
+  }
+
+  private void init() throws SQLException, TransactionException {
+    // Open JDBC Transaction
+    Connection connection = dataSource.getConnection();
+    if (connection == null) {
+      throw new TransactionException("JdbcTransaction could not start transaction.  Cause: The DataSource returned a null connection.");
+    }
+    // Isolation Level
+    isolationLevel.applyIsolationLevel(connection);
+    // AutoCommit
+    if (connection.getAutoCommit()) {
+      connection.setAutoCommit(false);
+    }
+    executor = configuration.newExecutor(connection);
+  }
+
+  public void commit(boolean required) throws SQLException, TransactionException {
+    if (executor != null) {
+      executor.commit(required);
+    }
+  }
+
+  public void rollback(boolean required) throws SQLException, TransactionException {
+    if (executor != null) {
+      executor.rollback(required);
+    }
+  }
+
+  public void close() throws SQLException, TransactionException {
+    if (executor != null) {
+      try {
+        isolationLevel.restoreIsolationLevel(executor.getConnection());
+      } finally {
+        executor.close();
+        executor = null;
+      }
+    }
+  }
+
+  public Executor getExecutor() throws SQLException, TransactionException {
+    if (executor == null) {
+      init();
+    }
+    return executor;
+  }
+
+}

Added: ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/transaction/jdbc/JdbcTransactionConfig.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/transaction/jdbc/JdbcTransactionConfig.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/transaction/jdbc/JdbcTransactionConfig.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/transaction/jdbc/JdbcTransactionConfig.java Thu Aug  7 16:21:46 2008
@@ -0,0 +1,18 @@
+package com.ibatis.sqlmap.engine.transaction.jdbc;
+
+import com.ibatis.sqlmap.engine.transaction.*;
+import org.apache.ibatis.mapping.Configuration;
+
+import java.sql.SQLException;
+import java.util.Properties;
+
+public class JdbcTransactionConfig extends BaseTransactionConfig {
+
+  public Transaction newTransaction(Configuration configuration, int transactionIsolation) throws SQLException, TransactionException {
+    return new JdbcTransaction(configuration, dataSource, transactionIsolation);
+  }
+
+  public void setProperties(Properties props) throws SQLException, TransactionException {
+  }
+
+}

Added: ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/transaction/jta/JtaTransaction.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/transaction/jta/JtaTransaction.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/transaction/jta/JtaTransaction.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/transaction/jta/JtaTransaction.java Thu Aug  7 16:21:46 2008
@@ -0,0 +1,118 @@
+package com.ibatis.sqlmap.engine.transaction.jta;
+
+import com.ibatis.sqlmap.engine.transaction.*;
+import org.apache.ibatis.mapping.Configuration;
+import org.apache.ibatis.executor.Executor;
+
+import javax.sql.DataSource;
+import javax.transaction.*;
+import java.sql.*;
+
+public class JtaTransaction extends BaseTransaction {
+
+  private UserTransaction userTransaction;
+  private DataSource dataSource;
+  private Configuration configuration;
+  private Executor executor;
+  private IsolationLevel isolationLevel = new IsolationLevel();
+
+  private boolean commmitted = false;
+  private boolean newTransaction = false;
+
+  public JtaTransaction(Configuration configuration, UserTransaction utx, DataSource ds, int isolationLevel) throws TransactionException {
+    // Check parameters
+    this.configuration = configuration;
+    userTransaction = utx;
+    dataSource = ds;
+    if (userTransaction == null) {
+      throw new TransactionException("JtaTransaction initialization failed.  UserTransaction was null.");
+    }
+    if (dataSource == null) {
+      throw new TransactionException("JtaTransaction initialization failed.  DataSource was null.");
+    }
+    this.isolationLevel.setIsolationLevel(isolationLevel);
+  }
+
+  private void init() throws TransactionException, SQLException {
+    // Start JTA Transaction
+    try {
+      newTransaction = userTransaction.getStatus() == Status.STATUS_NO_TRANSACTION;
+      if (newTransaction) {
+        userTransaction.begin();
+      }
+    } catch (Exception e) {
+      throw new TransactionException("JtaTransaction could not start transaction.  Cause: ", e);
+    }
+
+    // Open JDBC Connection
+    Connection connection = dataSource.getConnection();
+    if (connection == null) {
+      throw new TransactionException("JtaTransaction could not start transaction.  Cause: The DataSource returned a null connection.");
+    }
+    // Isolation Level
+    isolationLevel.applyIsolationLevel(connection);
+    // AutoCommit
+    if (connection.getAutoCommit()) {
+      connection.setAutoCommit(false);
+    }
+    executor = configuration.newExecutor(connection);
+  }
+
+  public void commit(boolean required) throws SQLException, TransactionException {
+    if (required) {
+      if (executor != null) {
+        if (commmitted) {
+          throw new TransactionException("JtaTransaction could not commit because this transaction has already been committed.");
+        }
+        try {
+          if (newTransaction) {
+            userTransaction.commit();
+          }
+        } catch (Exception e) {
+          throw new TransactionException("JtaTransaction could not commit.  Cause: ", e);
+        }
+        commmitted = true;
+      }
+    }
+  }
+
+  public void rollback(boolean required) throws SQLException, TransactionException {
+    if (required) {
+      if (executor != null) {
+        if (!commmitted) {
+          try {
+            if (userTransaction != null) {
+              if (newTransaction) {
+                userTransaction.rollback();
+              } else {
+                userTransaction.setRollbackOnly();
+              }
+            }
+          } catch (Exception e) {
+            throw new TransactionException("JtaTransaction could not rollback.  Cause: ", e);
+          }
+        }
+      }
+    }
+  }
+
+  public void close() throws SQLException, TransactionException {
+    if (executor != null) {
+      try {
+        isolationLevel.restoreIsolationLevel(executor.getConnection());
+      } finally {
+        executor.close();
+        executor = null;
+      }
+    }
+  }
+
+  public Executor getExecutor() throws SQLException, TransactionException {
+    if (executor == null) {
+      init();
+    }
+    return executor;
+  }
+
+
+}

Added: ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/transaction/jta/JtaTransactionConfig.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/transaction/jta/JtaTransactionConfig.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/transaction/jta/JtaTransactionConfig.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/transaction/jta/JtaTransactionConfig.java Thu Aug  7 16:21:46 2008
@@ -0,0 +1,32 @@
+package com.ibatis.sqlmap.engine.transaction.jta;
+
+import com.ibatis.sqlmap.client.SqlMapException;
+import com.ibatis.sqlmap.engine.transaction.*;
+import org.apache.ibatis.mapping.Configuration;
+
+import javax.naming.*;
+import javax.transaction.UserTransaction;
+import java.sql.SQLException;
+import java.util.Properties;
+
+public class JtaTransactionConfig extends BaseTransactionConfig {
+
+  private UserTransaction userTransaction;
+
+  public Transaction newTransaction(Configuration configuration, int transactionIsolation) throws SQLException, TransactionException {
+    return new JtaTransaction(configuration, userTransaction, dataSource, transactionIsolation);
+  }
+
+  public void setProperties(Properties props) throws SQLException, TransactionException {
+    String utxName = null;
+    try {
+      utxName = (String) props.get("UserTransaction");
+      InitialContext initCtx = new InitialContext();
+      userTransaction = (UserTransaction) initCtx.lookup(utxName);
+    } catch (NamingException e) {
+      throw new SqlMapException("Error initializing JtaTransactionConfig while looking up UserTransaction (" + utxName + ").  Cause: " + e);
+    }
+  }
+
+}
+

Added: ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/transaction/user/UserProvidedTransaction.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/transaction/user/UserProvidedTransaction.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/transaction/user/UserProvidedTransaction.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/main/java/com/ibatis/sqlmap/engine/transaction/user/UserProvidedTransaction.java Thu Aug  7 16:21:46 2008
@@ -0,0 +1,32 @@
+package com.ibatis.sqlmap.engine.transaction.user;
+
+import com.ibatis.sqlmap.engine.transaction.*;
+import org.apache.ibatis.mapping.Configuration;
+import org.apache.ibatis.executor.Executor;
+
+import java.sql.*;
+
+public class UserProvidedTransaction extends BaseTransaction {
+
+  private Executor executor;
+
+  public UserProvidedTransaction(Configuration configuration, Connection connection) {
+    this.executor = configuration.newExecutor(connection);
+  }
+
+  public void commit(boolean required) throws SQLException, TransactionException {
+    executor.commit(required);
+  }
+
+  public void rollback(boolean required) throws SQLException, TransactionException {
+    executor.rollback(required);
+  }
+
+  public void close() throws SQLException, TransactionException {
+  }
+
+  public Executor getExecutor() throws SQLException, TransactionException {
+    return executor;
+  }
+
+}

Added: ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/test/java/badbeans/BeanWithDifferentTypeGetterSetter.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/test/java/badbeans/BeanWithDifferentTypeGetterSetter.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/test/java/badbeans/BeanWithDifferentTypeGetterSetter.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/test/java/badbeans/BeanWithDifferentTypeGetterSetter.java Thu Aug  7 16:21:46 2008
@@ -0,0 +1,15 @@
+package badbeans;
+
+public class BeanWithDifferentTypeGetterSetter {
+
+  private String value;
+
+
+  public String getValue() {
+    return value;
+  }
+
+  public void setValue(Integer value) {
+    this.value = value.toString();
+  }
+}

Added: ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/test/java/badbeans/BeanWithDifferentTypeOverloadedSetter.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/test/java/badbeans/BeanWithDifferentTypeOverloadedSetter.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/test/java/badbeans/BeanWithDifferentTypeOverloadedSetter.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/test/java/badbeans/BeanWithDifferentTypeOverloadedSetter.java Thu Aug  7 16:21:46 2008
@@ -0,0 +1,19 @@
+package badbeans;
+
+public class BeanWithDifferentTypeOverloadedSetter {
+
+  private String value;
+
+
+  public String getValue() {
+    return value;
+  }
+
+  public void setValue(Double value) {
+    this.value = value.toString();
+  }
+
+  public void setValue(Integer value) {
+    this.value = value.toString();
+  }
+}

Added: ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/test/java/badbeans/BeanWithNoGetterOverloadedSetters.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/test/java/badbeans/BeanWithNoGetterOverloadedSetters.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/test/java/badbeans/BeanWithNoGetterOverloadedSetters.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/test/java/badbeans/BeanWithNoGetterOverloadedSetters.java Thu Aug  7 16:21:46 2008
@@ -0,0 +1,16 @@
+package badbeans;
+
+public class BeanWithNoGetterOverloadedSetters {
+
+  private String value;
+
+
+  public void setValue(String value) {
+    this.value = value;
+  }
+
+  public void setValue(Integer value) {
+    this.value = value.toString();
+  }
+
+}

Added: ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/test/java/badbeans/BeanWithOverloadedSetter.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/test/java/badbeans/BeanWithOverloadedSetter.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/test/java/badbeans/BeanWithOverloadedSetter.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/test/java/badbeans/BeanWithOverloadedSetter.java Thu Aug  7 16:21:46 2008
@@ -0,0 +1,19 @@
+package badbeans;
+
+public class BeanWithOverloadedSetter {
+
+  private String value;
+
+
+  public String getValue() {
+    return value;
+  }
+
+  public void setValue(String value) {
+    this.value = value;
+  }
+
+  public void setValue(Integer value) {
+    this.value = value.toString();
+  }
+}

Added: ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/test/java/badbeans/GoodBean.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/test/java/badbeans/GoodBean.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/test/java/badbeans/GoodBean.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/test/java/badbeans/GoodBean.java Thu Aug  7 16:21:46 2008
@@ -0,0 +1,15 @@
+package badbeans;
+
+public class GoodBean {
+
+  private String value;
+
+
+  public String getValue() {
+    return value;
+  }
+
+  public void setValue(String value) {
+    this.value = value;
+  }
+}

Added: ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/test/java/com/ibatis/common/resources/ResourcesTest.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/test/java/com/ibatis/common/resources/ResourcesTest.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/test/java/com/ibatis/common/resources/ResourcesTest.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/test/java/com/ibatis/common/resources/ResourcesTest.java Thu Aug  7 16:21:46 2008
@@ -0,0 +1,387 @@
+/*
+ * Created on Apr 18, 2004
+ *
+ * To change the template for this generated file go to
+ * Window - Preferences - Java - Code Generation - Code and Comments
+ */
+package com.ibatis.common.resources;
+
+import junit.framework.TestCase;
+
+import java.io.*;
+import java.net.URL;
+import java.util.*;
+
+/**
+ * To change the template for this generated type comment go to
+ * Window - Preferences - Java - Code Generation - Code and Comments
+ */
+public class ResourcesTest extends TestCase {
+  private boolean isUsingPrivateClassloader = false;
+
+  public static void main(String[] args) {
+    junit.textui.TestRunner.run(ResourcesTest.class);
+  }
+
+  /*
+   * @see TestCase#setUp()
+   */
+  protected void setUp() throws Exception {
+    super.setUp();
+  }
+
+  /*
+   * @see TestCase#tearDown()
+   */
+  protected void tearDown() throws Exception {
+    super.tearDown();
+  }
+
+  public void testSetDefaultClassLoader() {
+    ClassLoader classLoader = new TestCL(this.getClass().getClassLoader());
+    ClassLoader tmp = Resources.getDefaultClassLoader();
+    Resources.setDefaultClassLoader(classLoader);
+    assertEquals(classLoader, Resources.getDefaultClassLoader());
+    Resources.setDefaultClassLoader(tmp);
+    assertNotSame(classLoader, Resources.getDefaultClassLoader());
+  }
+
+  /*
+   * Class to test for URL getResourceURL(String)
+   */
+  public void testGetResourceURLString() {
+    String resourceName;
+    URL url;
+
+    resourceName = "java/lang/String.class";
+    url = null;
+    try {
+      url = Resources.getResourceURL(resourceName);
+      assertNotNull(url);
+      url = null;
+    } catch (IOException e) {
+      fail("Could not load resource " + resourceName);
+    }
+
+    resourceName = "java.lang.YouAreAMonkeyCoderIfYouHaveThisClass";
+    url = null;
+    try {
+      Resources.getResourceURL(resourceName);
+      fail("You are a monkey coder, and the Resources class loaded a bogus class.");
+    } catch (IOException e) {
+      //  This is expected...
+      assertNull(url);
+    }
+  }
+
+  /*
+   * Class to test for URL getResourceURL(ClassLoader, String)
+   */
+  public void testGetResourceURLClassLoaderString() {
+    String resourceName;
+    URL url;
+    ClassLoader classLoader;
+
+    classLoader = new TestCL(this.getClass().getClassLoader());
+    resourceName = "java/lang/String.class";
+    url = null;
+    isUsingPrivateClassloader = false;
+    try {
+      assertFalse(isUsingPrivateClassloader);
+      url = Resources.getResourceURL(classLoader, resourceName);
+      assertNotNull(url);
+      assertTrue(isUsingPrivateClassloader);
+      url = null;
+    } catch (IOException e) {
+      fail("Could not load resource " + resourceName);
+    }
+
+    resourceName = "java.lang.YouAreAMonkeyCoderIfYouHaveThisClass";
+    url = null;
+    isUsingPrivateClassloader = false;
+    try {
+      assertFalse(isUsingPrivateClassloader);
+      Resources.getResourceURL(classLoader, resourceName);
+      fail("You are a monkey coder, and the Resources class loaded a bogus class.");
+    } catch (IOException e) {
+      //  This is expected...
+      assertNull(url);
+      assertTrue(isUsingPrivateClassloader);
+    }
+  }
+
+  /*
+   * Class to test for InputStream getResourceAsStream(String)
+   */
+  public void testGetResourceAsStreamString() {
+    InputStream inputStream;
+    String resourceName;
+
+    resourceName = "java/lang/String.class";
+    inputStream = null;
+    try {
+      inputStream = Resources.getResourceAsStream(resourceName);
+      assertNotNull(inputStream);
+    } catch (IOException e) {
+      fail("Could not load resource " + resourceName);
+    }
+
+    resourceName = "java.lang.YouAreAMonkeyCoderIfYouHaveThisClass";
+    inputStream = null;
+    try {
+      Resources.getResourceURL(resourceName);
+      fail("You are a monkey coder, and the Resources class loaded a bogus class.");
+    } catch (IOException e) {
+      //  This is expected...
+      assertNull(inputStream);
+    }
+  }
+
+  /*
+   * Class to test for InputStream getResourceAsStream(ClassLoader, String)
+   */
+  public void testGetResourceAsStreamClassLoaderString() {
+    InputStream inputStream;
+    String resourceName;
+    ClassLoader classLoader;
+
+    classLoader = new TestCL(this.getClass().getClassLoader());
+    resourceName = "java/lang/String.class";
+    inputStream = null;
+    isUsingPrivateClassloader = false;
+    try {
+      assertFalse(isUsingPrivateClassloader);
+      inputStream = Resources.getResourceAsStream(classLoader, resourceName);
+      assertNotNull(inputStream);
+      assertTrue(isUsingPrivateClassloader);
+    } catch (IOException e) {
+      fail("Could not load resource " + resourceName);
+    }
+
+    resourceName = "java.lang.YouAreAMonkeyCoderIfYouHaveThisClass";
+    inputStream = null;
+    isUsingPrivateClassloader = false;
+    try {
+      assertFalse(isUsingPrivateClassloader);
+      Resources.getResourceURL(classLoader, resourceName);
+      fail("You are a monkey coder, and the Resources class loaded a bogus class.");
+    } catch (IOException e) {
+      //  This is expected...
+      assertNull(inputStream);
+      assertTrue(isUsingPrivateClassloader);
+    }
+  }
+
+  /*
+   * Class to test for Properties getResourceAsProperties(String)
+   */
+  public void testGetResourceAsPropertiesString() {
+    String resourceName;
+    String testProp = "name";
+    String testPropValue = "value";
+    String testProp2 = "name2";
+    String testPropValue2 = "value2";
+    Properties properties;
+
+    resourceName = "com/ibatis/common/resources/resourcestest.properties";
+    properties = null;
+    try {
+      properties = Resources.getResourceAsProperties(resourceName);
+      assertNotNull(properties);
+      assertEquals(properties.get(testProp), testPropValue);
+      assertEquals(properties.get(testProp2), testPropValue2);
+    } catch (IOException e) {
+      fail("Could not read test properties file: " + resourceName);
+    }
+
+    resourceName = "com/ibatis/common/resources/dont-create-this-file-or-the-test-will-fail.properties";
+    properties = null;
+
+    try {
+      properties = Resources.getResourceAsProperties(resourceName);
+      fail("Are you TRYING to break this test? If not, Resources loaded a bad properties file: " + resourceName);
+    } catch (IOException e) {
+      assertNull(properties);
+    }
+  }
+
+  /*
+   * Class to test for Properties getResourceAsProperties(ClassLoader, String)
+   */
+  public void testGetResourceAsPropertiesClassLoaderString() {
+    String resourceName;
+    String testProp = "name";
+    String testPropValue = "value";
+    String testProp2 = "name2";
+    String testPropValue2 = "value2";
+    Properties properties;
+    ClassLoader classLoader = new TestCL(this.getClass().getClassLoader());
+
+    resourceName = "com/ibatis/common/resources/resourcestest.properties";
+    properties = null;
+    isUsingPrivateClassloader = false;
+    try {
+      assertNull(properties);
+      assertFalse(isUsingPrivateClassloader);
+      properties = Resources.getResourceAsProperties(classLoader, resourceName);
+      assertNotNull(properties);
+      assertTrue(isUsingPrivateClassloader);
+      assertEquals(properties.get(testProp), testPropValue);
+      assertEquals(properties.get(testProp2), testPropValue2);
+    } catch (IOException e) {
+      fail("Could not read test properties file: " + resourceName);
+    }
+
+    resourceName = "com/ibatis/common/resources/dont-create-this-file-or-the-test-will-fail.properties";
+    properties = null;
+    isUsingPrivateClassloader = false;
+    try {
+      assertFalse(isUsingPrivateClassloader);
+      properties = Resources.getResourceAsProperties(classLoader, resourceName);
+      fail("Are you TRYING to break this test? If not, Resources loaded a bad properties file: " + resourceName);
+    } catch (IOException e) {
+      assertNull(properties);
+      assertTrue(isUsingPrivateClassloader);
+    }
+  }
+
+  /*
+   * Class to test for Reader getResourceAsReader(String)
+   */
+  public void testGetResourceAsReaderString() {
+  }
+
+  /*
+   * Class to test for Reader getResourceAsReader(ClassLoader, String)
+   */
+  public void testGetResourceAsReaderClassLoaderString() {
+  }
+
+  /*
+   * Class to test for File getResourceAsFile(String)
+   */
+  public void testGetResourceAsFileString() {
+  }
+
+  /*
+   * Class to test for File getResourceAsFile(ClassLoader, String)
+   */
+  public void testGetResourceAsFileClassLoaderString() {
+  }
+
+  public void testGetUrlAsStream() {
+  }
+
+  public void testGetUrlAsReader() {
+  }
+
+  public void testGetUrlAsProperties() {
+  }
+
+  public void testClassForName() {
+  }
+
+  /*
+   * Class to test for Object instantiate(String)
+   */
+  public void testInstantiateString() {
+  }
+
+  /*
+   * Class to test for Object instantiate(Class)
+   */
+  public void testInstantiateClass() {
+  }
+
+  /* A stupid simple classloader for testing
+   */
+  private class TestCL extends ClassLoader {
+
+
+    public TestCL(ClassLoader parent) {
+      super(parent);
+    }
+
+    public synchronized void clearAssertionStatus() {
+      isUsingPrivateClassloader = true;
+      super.clearAssertionStatus();
+    }
+
+    protected Package definePackage(String name, String specTitle,
+                                    String specVersion, String specVendor, String implTitle,
+                                    String implVersion, String implVendor, URL sealBase)
+        throws IllegalArgumentException {
+      isUsingPrivateClassloader = true;
+      return super.definePackage(name, specTitle, specVersion,
+          specVendor, implTitle, implVersion, implVendor, sealBase);
+    }
+
+    protected Class findClass(String name) throws ClassNotFoundException {
+      isUsingPrivateClassloader = true;
+      return super.findClass(name);
+    }
+
+    protected String findLibrary(String libname) {
+      isUsingPrivateClassloader = true;
+      return super.findLibrary(libname);
+    }
+
+    protected URL findResource(String name) {
+      isUsingPrivateClassloader = true;
+      return super.findResource(name);
+    }
+
+    protected Enumeration findResources(String name) throws IOException {
+      isUsingPrivateClassloader = true;
+      return super.findResources(name);
+    }
+
+    protected Package getPackage(String name) {
+      isUsingPrivateClassloader = true;
+      return super.getPackage(name);
+    }
+
+    protected Package[] getPackages() {
+      isUsingPrivateClassloader = true;
+      return super.getPackages();
+    }
+
+    public URL getResource(String name) {
+      isUsingPrivateClassloader = true;
+      return super.getResource(name);
+    }
+
+    public InputStream getResourceAsStream(String name) {
+      isUsingPrivateClassloader = true;
+      return super.getResourceAsStream(name);
+    }
+
+    protected synchronized Class loadClass(String name, boolean resolve)
+        throws ClassNotFoundException {
+      isUsingPrivateClassloader = true;
+      return super.loadClass(name, resolve);
+    }
+
+    public Class loadClass(String name) throws ClassNotFoundException {
+      isUsingPrivateClassloader = true;
+      return super.loadClass(name);
+    }
+
+    public synchronized void setClassAssertionStatus(String className,
+                                                     boolean enabled) {
+      isUsingPrivateClassloader = true;
+      super.setClassAssertionStatus(className, enabled);
+    }
+
+    public synchronized void setDefaultAssertionStatus(boolean enabled) {
+      isUsingPrivateClassloader = true;
+      super.setDefaultAssertionStatus(enabled);
+    }
+
+    public synchronized void setPackageAssertionStatus(String packageName,
+                                                       boolean enabled) {
+      isUsingPrivateClassloader = true;
+      super.setPackageAssertionStatus(packageName, enabled);
+    }
+  }
+}

Added: ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/test/java/com/ibatis/common/resources/resourcestest.properties
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/test/java/com/ibatis/common/resources/resourcestest.properties?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/test/java/com/ibatis/common/resources/resourcestest.properties (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-compat/src/test/java/com/ibatis/common/resources/resourcestest.properties Thu Aug  7 16:21:46 2008
@@ -0,0 +1,2 @@
+name=value
+name2=value2