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 [18/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-core/src/main/java/org/apache/ibatis/mapping/ResultMapping.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/mapping/ResultMapping.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/mapping/ResultMapping.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/mapping/ResultMapping.java Thu Aug 7 16:21:46 2008
@@ -0,0 +1,111 @@
+package org.apache.ibatis.mapping;
+
+import org.apache.ibatis.type.*;
+
+import java.util.*;
+
+public class ResultMapping {
+
+ private String property;
+ private String column;
+ private Class javaType;
+ private JdbcType jdbcType;
+ private TypeHandler typeHandler;
+ private String nestedResultMapId;
+ private String nestedQueryId;
+ private List<ResultFlag> flags;
+ private List<ResultMapping> composites;
+
+ private ResultMapping() {
+ }
+
+ public static class Builder {
+ private ResultMapping resultMapping = new ResultMapping();
+
+ public Builder(String property, String column, TypeHandler typeHandler) {
+ resultMapping.property = property;
+ resultMapping.column = column;
+ resultMapping.typeHandler = typeHandler;
+ resultMapping.flags = new ArrayList<ResultFlag>();
+ resultMapping.composites = new ArrayList<ResultMapping>();
+ }
+
+ public Builder javaType(Class javaType) {
+ resultMapping.javaType = javaType;
+ return this;
+ }
+
+ public Builder jdbcType(JdbcType jdbcType) {
+ resultMapping.jdbcType = jdbcType;
+ return this;
+ }
+
+ public Builder nestedResultMapId(String nestedResultMapId) {
+ resultMapping.nestedResultMapId = nestedResultMapId;
+ return this;
+ }
+
+ public Builder nestedQueryId(String nestedQueryId) {
+ resultMapping.nestedQueryId = nestedQueryId;
+ return this;
+ }
+
+ public Builder flags(List<ResultFlag> flags) {
+ resultMapping.flags = flags;
+ return this;
+ }
+
+ public ResultMapping build() {
+ //lock down collections
+ resultMapping.flags = Collections.unmodifiableList(resultMapping.flags);
+ resultMapping.composites = Collections.unmodifiableList(resultMapping.composites);
+ return resultMapping;
+ }
+
+ public Builder composites(List<ResultMapping> composites) {
+ resultMapping.composites = composites;
+ return this;
+ }
+ }
+
+ public String getProperty() {
+ return property;
+ }
+
+ public String getColumn() {
+ return column;
+ }
+
+ public Class getJavaType() {
+ return javaType;
+ }
+
+ public JdbcType getJdbcType() {
+ return jdbcType;
+ }
+
+ public TypeHandler getTypeHandler() {
+ return typeHandler;
+ }
+
+ public String getNestedResultMapId() {
+ return nestedResultMapId;
+ }
+
+ public String getNestedQueryId() {
+ return nestedQueryId;
+ }
+
+ public List<ResultFlag> getFlags() {
+ return flags;
+ }
+
+ public List<ResultMapping> getComposites() {
+ return composites;
+ }
+
+ public boolean isCompositeResult() {
+ return this.composites != null && !this.composites.isEmpty();
+ }
+
+}
Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/mapping/ResultSetType.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/mapping/ResultSetType.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/mapping/ResultSetType.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/mapping/ResultSetType.java Thu Aug 7 16:21:46 2008
@@ -0,0 +1,19 @@
+package org.apache.ibatis.mapping;
+
+import java.sql.ResultSet;
+
+public enum ResultSetType {
+ FORWARD_ONLY(ResultSet.TYPE_FORWARD_ONLY),
+ SCROLL_INSENSITIVE(ResultSet.TYPE_SCROLL_INSENSITIVE),
+ SCROLL_SENSITIVE(ResultSet.TYPE_SCROLL_SENSITIVE);
+
+ private int value;
+
+ ResultSetType(int value) {
+ this.value = value;
+ }
+
+ public int getValue() {
+ return value;
+ }
+}
Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/mapping/SqlSource.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/mapping/SqlSource.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/mapping/SqlSource.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/mapping/SqlSource.java Thu Aug 7 16:21:46 2008
@@ -0,0 +1,11 @@
+package org.apache.ibatis.mapping;
+
+import java.util.List;
+
+public interface SqlSource {
+
+ String getSql(Object parameterObject);
+
+ List<ParameterMapping> getParameterMappings(Object parameterObject);
+
+}
Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/mapping/StatementType.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/mapping/StatementType.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/mapping/StatementType.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/mapping/StatementType.java Thu Aug 7 16:21:46 2008
@@ -0,0 +1,5 @@
+package org.apache.ibatis.mapping;
+
+public enum StatementType {
+ STATEMENT, PREPARED, CALLABLE
+}
Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/migration/ScriptRunner.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/migration/ScriptRunner.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/migration/ScriptRunner.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/migration/ScriptRunner.java Thu Aug 7 16:21:46 2008
@@ -0,0 +1,242 @@
+package org.apache.ibatis.migration;
+
+
+import javax.sql.DataSource;
+import java.io.*;
+import java.sql.*;
+
+/**
+ * Utility to run database scripts
+ */
+public class ScriptRunner {
+
+ private static final String DEFAULT_DELIMITER = ";";
+
+ private DataSource dataSource;
+ private Connection connection;
+ private String driver;
+ private String url;
+ private String username;
+ private String password;
+
+ private boolean stopOnError;
+ private boolean autoCommit;
+
+ private PrintWriter logWriter = new PrintWriter(System.out);
+ private PrintWriter errorLogWriter = new PrintWriter(System.err);
+
+ private String delimiter = DEFAULT_DELIMITER;
+ private boolean fullLineDelimiter = false;
+
+ public ScriptRunner(DataSource dataSource, boolean autoCommit, boolean stopOnError) {
+ this.dataSource = dataSource;
+ this.autoCommit = autoCommit;
+ this.stopOnError = stopOnError;
+ }
+
+ public ScriptRunner(Connection connection, boolean autoCommit, boolean stopOnError) {
+ this.connection = connection;
+ this.autoCommit = autoCommit;
+ this.stopOnError = stopOnError;
+ }
+
+ public ScriptRunner(String driver, String url, String username, String password, boolean autoCommit, boolean stopOnError) {
+ this.driver = driver;
+ this.url = url;
+ this.username = username;
+ this.password = password;
+ this.autoCommit = autoCommit;
+ this.stopOnError = stopOnError;
+ }
+
+ public void setDelimiter(String delimiter, boolean fullLineDelimiter) {
+ this.delimiter = delimiter;
+ this.fullLineDelimiter = fullLineDelimiter;
+ }
+
+ public void setLogWriter(PrintWriter logWriter) {
+ this.logWriter = logWriter;
+ }
+
+ public void setErrorLogWriter(PrintWriter errorLogWriter) {
+ this.errorLogWriter = errorLogWriter;
+ }
+
+ public void runScript(Reader reader) throws IOException, SQLException {
+ try {
+ if (dataSource != null) {
+ connection = dataSource.getConnection();
+ try {
+ configureAutoCommitAndRun(reader);
+ } finally {
+ connection.close();
+ }
+ } else if (connection != null) {
+ configureAutoCommitAndRun(reader);
+ } else {
+ Class driverType = Class.forName(driver);
+ DriverManager.registerDriver((Driver) driverType.newInstance());
+ connection = DriverManager.getConnection(url, username, password);
+ try {
+ configureAutoCommitAndRun(reader);
+ } finally {
+ try {
+ connection.close();
+ } finally {
+ connection = null;
+ }
+ }
+ }
+ } catch (IOException e) {
+ throw e;
+ } catch (SQLException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new RuntimeException("Error running script. Cause: " + e, e);
+ }
+ }
+
+ private void configureAutoCommitAndRun(Reader reader) throws SQLException, IOException {
+ boolean originalAutoCommit = connection.getAutoCommit();
+ try {
+ if (originalAutoCommit != this.autoCommit) {
+ connection.setAutoCommit(this.autoCommit);
+ }
+ runScriptWithConnection(connection, reader);
+ } finally {
+ connection.setAutoCommit(originalAutoCommit);
+ }
+ }
+
+ /**
+ * Runs an SQL script (read in using the Reader parameter) using the connection passed in
+ *
+ * @param conn - the connection to use for the script
+ * @param reader - the source of the script
+ * @throws java.sql.SQLException if any SQL errors occur
+ * @throws java.io.IOException if there is an error reading from the Reader
+ */
+ private void runScriptWithConnection(Connection conn, Reader reader)
+ throws IOException, SQLException {
+ StringBuffer command = null;
+ try {
+ LineNumberReader lineReader = new LineNumberReader(reader);
+ String line;
+ while ((line = lineReader.readLine()) != null) {
+ if (command == null) {
+ command = new StringBuffer();
+ }
+ String trimmedLine = line.trim();
+ if (trimmedLine.startsWith("--")) {
+ println(trimmedLine);
+ } else if (trimmedLine.length() < 1 || trimmedLine.startsWith("//")) {
+ //Do nothing
+ } else if (trimmedLine.length() < 1 || trimmedLine.startsWith("--")) {
+ //Do nothing
+ } else if (!fullLineDelimiter && trimmedLine.endsWith(getDelimiter())
+ || fullLineDelimiter && trimmedLine.equals(getDelimiter())) {
+ command.append(line.substring(0, line.lastIndexOf(getDelimiter())));
+ command.append(" ");
+ Statement statement = conn.createStatement();
+
+ println(command);
+
+ boolean hasResults = false;
+ if (stopOnError) {
+ hasResults = statement.execute(command.toString());
+ } else {
+ try {
+ hasResults = statement.execute(command.toString());
+ } catch (SQLException e) {
+ e.fillInStackTrace();
+ printlnError("Error executing: " + command);
+ printlnError(e);
+ }
+ }
+
+ if (autoCommit && !conn.getAutoCommit()) {
+ conn.commit();
+ }
+
+ ResultSet rs = statement.getResultSet();
+ if (hasResults && rs != null) {
+ ResultSetMetaData md = rs.getMetaData();
+ int cols = md.getColumnCount();
+ for (int i = 0; i < cols; i++) {
+ String name = md.getColumnLabel(i + 1);
+ print(name + "\t");
+ }
+ println("");
+ while (rs.next()) {
+ for (int i = 0; i < cols; i++) {
+ String value = rs.getString(i + 1);
+ print(value + "\t");
+ }
+ println("");
+ }
+ }
+
+ command = null;
+ try {
+ statement.close();
+ } catch (Exception e) {
+ // Ignore to workaround a bug in Jakarta DBCP
+ }
+ Thread.yield();
+ } else {
+ command.append(line);
+ command.append(" ");
+ }
+ }
+ if (!autoCommit) {
+ conn.commit();
+ }
+ } catch (SQLException e) {
+ e.fillInStackTrace();
+ printlnError("Error executing: " + command);
+ printlnError(e);
+ throw e;
+ } catch (IOException e) {
+ e.fillInStackTrace();
+ printlnError("Error executing: " + command);
+ printlnError(e);
+ throw e;
+ } finally {
+ conn.rollback();
+ flush();
+ }
+ }
+
+ private String getDelimiter() {
+ return delimiter;
+ }
+
+ private void print(Object o) {
+ if (logWriter != null) {
+ System.out.print(o);
+ }
+ }
+
+ private void println(Object o) {
+ if (logWriter != null) {
+ logWriter.println(o);
+ }
+ }
+
+ private void printlnError(Object o) {
+ if (errorLogWriter != null) {
+ errorLogWriter.println(o);
+ }
+ }
+
+ private void flush() {
+ if (logWriter != null) {
+ logWriter.flush();
+ }
+ if (errorLogWriter != null) {
+ errorLogWriter.flush();
+ }
+ }
+
+
+}
Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/plugin/Interceptor.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/plugin/Interceptor.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/plugin/Interceptor.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/plugin/Interceptor.java Thu Aug 7 16:21:46 2008
@@ -0,0 +1,9 @@
+package org.apache.ibatis.plugin;
+
+public interface Interceptor {
+
+ Object intercept(Invocation invocation) throws Throwable;
+
+ Object plugin(Object target);
+
+}
Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/plugin/InterceptorChain.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/plugin/InterceptorChain.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/plugin/InterceptorChain.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/plugin/InterceptorChain.java Thu Aug 7 16:21:46 2008
@@ -0,0 +1,20 @@
+package org.apache.ibatis.plugin;
+
+import java.util.*;
+
+public class InterceptorChain {
+
+ private final List<Interceptor> interceptors = new ArrayList<Interceptor>();
+
+ public Object pluginAll(Object target) {
+ for (Interceptor interceptor : interceptors) {
+ target = interceptor.plugin(target);
+ }
+ return target;
+ }
+
+ public void addInterceptor(Interceptor interceptor) {
+ interceptors.add(interceptor);
+ }
+
+}
Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/plugin/Intercepts.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/plugin/Intercepts.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/plugin/Intercepts.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/plugin/Intercepts.java Thu Aug 7 16:21:46 2008
@@ -0,0 +1,10 @@
+package org.apache.ibatis.plugin;
+
+import java.lang.annotation.*;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface Intercepts {
+ Signature[] value();
+}
+
Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/plugin/Invocation.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/plugin/Invocation.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/plugin/Invocation.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/plugin/Invocation.java Thu Aug 7 16:21:46 2008
@@ -0,0 +1,33 @@
+package org.apache.ibatis.plugin;
+
+import java.lang.reflect.*;
+
+public class Invocation {
+
+ private Object target;
+ private Method method;
+ private Object[] args;
+
+ public Invocation(Object target, Method method, Object[] args) {
+ this.target = target;
+ this.method = method;
+ this.args = args;
+ }
+
+ public Object getTarget() {
+ return target;
+ }
+
+ public Method getMethod() {
+ return method;
+ }
+
+ public Object[] getArgs() {
+ return args;
+ }
+
+ public Object proceed() throws InvocationTargetException, IllegalAccessException {
+ return method.invoke(target, args);
+ }
+
+}
Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/plugin/Plugin.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/plugin/Plugin.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/plugin/Plugin.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/plugin/Plugin.java Thu Aug 7 16:21:46 2008
@@ -0,0 +1,77 @@
+package org.apache.ibatis.plugin;
+
+import org.apache.ibatis.reflection.ExceptionUtil;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+public class Plugin implements InvocationHandler {
+
+ private Object target;
+ private Interceptor interceptor;
+ private Map<Class, Set<Method>> signatureMap;
+
+ private Plugin(Object target, Interceptor interceptor, Map<Class, Set<Method>> signatureMap) {
+ this.target = target;
+ this.interceptor = interceptor;
+ this.signatureMap = signatureMap;
+ }
+
+ public static Object wrap(Object target, Interceptor interceptor) {
+ Map<Class, Set<Method>> signatureMap = getSignatureMap(interceptor);
+ Class type = target.getClass();
+ Class[] interfaces = getAllInterfaces(type, signatureMap);
+ if (interfaces.length > 0) {
+ return Proxy.newProxyInstance(
+ type.getClassLoader(),
+ interfaces,
+ new Plugin(target, interceptor, signatureMap));
+ }
+ return target;
+ }
+
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ try {
+ Set<Method> methods = signatureMap.get(method.getDeclaringClass());
+ if (methods != null && methods.contains(method)) {
+ return interceptor.intercept(new Invocation(target, method, args));
+ }
+ return method.invoke(target, args);
+ } catch (Exception e) {
+ throw ExceptionUtil.unwrapThrowable(e);
+ }
+ }
+
+ private static Map<Class, Set<Method>> getSignatureMap(Interceptor interceptor) {
+ Signature[] sigs = interceptor.getClass().getAnnotation(Intercepts.class).value();
+ Map<Class, Set<Method>> signatureMap = new HashMap<Class, Set<Method>>();
+ for (Signature sig : sigs) {
+ Set<Method> methods = signatureMap.get(sig.type());
+ if (methods == null) {
+ methods = new HashSet<Method>();
+ signatureMap.put(sig.type(), methods);
+ }
+ try {
+ Method method = sig.type().getMethod(sig.method(), sig.args());
+ methods.add(method);
+ } catch (NoSuchMethodException e) {
+ throw new RuntimeException("Could not find method on " + sig.type() + " named " + sig.method() + ". Cause: " + e, e);
+ }
+ }
+ return signatureMap;
+ }
+
+ private static Class[] getAllInterfaces(Class type, Map<Class, Set<Method>> signatureMap) {
+ Set<Class> interfaces = new HashSet<Class>();
+ while (type != null) {
+ for (Class c : type.getInterfaces()) {
+ if (signatureMap.containsKey(c)) {
+ interfaces.add(c);
+ }
+ }
+ type = type.getSuperclass();
+ }
+ return interfaces.toArray(new Class[interfaces.size()]);
+ }
+
+}
Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/plugin/Signature.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/plugin/Signature.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/plugin/Signature.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/plugin/Signature.java Thu Aug 7 16:21:46 2008
@@ -0,0 +1,13 @@
+package org.apache.ibatis.plugin;
+
+import java.lang.annotation.*;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface Signature {
+ Class type();
+
+ String method();
+
+ Class[] args();
+}
\ No newline at end of file
Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/DefaultObjectFactory.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/DefaultObjectFactory.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/DefaultObjectFactory.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/DefaultObjectFactory.java Thu Aug 7 16:21:46 2008
@@ -0,0 +1,57 @@
+package org.apache.ibatis.reflection;
+
+import java.lang.reflect.Constructor;
+import java.util.*;
+
+public class DefaultObjectFactory implements ObjectFactory {
+
+ public Object create(Class type) {
+ return create(type, null, null);
+ }
+
+ public Object create(Class type, List<Class> constructorArgTypes, List<Object> constructorArgs) {
+ Class classToCreate = resolveCollectionInterface(type);
+ return instantiateClass(classToCreate, constructorArgTypes, constructorArgs);
+ }
+
+ public void setProperty(String name, String value) {
+ // no props for default
+ }
+
+ private Object instantiateClass(Class type, List<Class> constructorArgTypes, List<Object> constructorArgs) {
+ try {
+ Constructor constructor;
+ if (constructorArgTypes == null || constructorArgs == null) {
+ constructor = type.getDeclaredConstructor();
+ if (!constructor.isAccessible()) {
+ constructor.setAccessible(true);
+ }
+ return constructor.newInstance();
+ } else {
+ constructor = type.getDeclaredConstructor(constructorArgTypes.toArray(new Class[constructorArgTypes.size()]));
+ if (!constructor.isAccessible()) {
+ constructor.setAccessible(true);
+ }
+ return constructor.newInstance(constructorArgs.toArray(new Object[constructorArgs.size()]));
+ }
+ } catch (Exception e) {
+ throw new RuntimeException("Error instantiating " + type + ". Cause: " + e, e);
+ }
+ }
+
+
+ private Class resolveCollectionInterface(Class type) {
+ Class classToCreate;
+ if (type == List.class || type == Collection.class) {
+ classToCreate = ArrayList.class;
+ } else if (type == Map.class) {
+ classToCreate = HashMap.class;
+ } else if (type == Set.class) {
+ classToCreate = HashSet.class;
+ } else {
+ classToCreate = type;
+ }
+ return classToCreate;
+ }
+
+}
Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/ExceptionUtil.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/ExceptionUtil.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/ExceptionUtil.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/ExceptionUtil.java Thu Aug 7 16:21:46 2008
@@ -0,0 +1,20 @@
+package org.apache.ibatis.reflection;
+
+import java.lang.reflect.*;
+
+public class ExceptionUtil {
+
+ public static Throwable unwrapThrowable(Throwable wrapped) {
+ Throwable unwrapped = wrapped;
+ while (true) {
+ if (unwrapped instanceof InvocationTargetException) {
+ unwrapped = ((InvocationTargetException) wrapped).getTargetException();
+ } else if (unwrapped instanceof UndeclaredThrowableException) {
+ unwrapped = ((UndeclaredThrowableException) wrapped).getUndeclaredThrowable();
+ } else {
+ return unwrapped;
+ }
+ }
+ }
+
+}
Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/GetFieldInvoker.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/GetFieldInvoker.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/GetFieldInvoker.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/GetFieldInvoker.java Thu Aug 7 16:21:46 2008
@@ -0,0 +1,19 @@
+package org.apache.ibatis.reflection;
+
+import java.lang.reflect.*;
+
+class GetFieldInvoker implements Invoker {
+ private Field field;
+
+ public GetFieldInvoker(Field field) {
+ this.field = field;
+ }
+
+ public Object invoke(Object target, Object[] args) throws IllegalAccessException, InvocationTargetException {
+ return field.get(target);
+ }
+
+ public Class getType() {
+ return field.getType();
+ }
+}
Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/Invoker.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/Invoker.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/Invoker.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/Invoker.java Thu Aug 7 16:21:46 2008
@@ -0,0 +1,9 @@
+package org.apache.ibatis.reflection;
+
+import java.lang.reflect.InvocationTargetException;
+
+interface Invoker {
+ Object invoke(Object target, Object[] args) throws IllegalAccessException, InvocationTargetException;
+
+ Class getType();
+}
Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/MetaClass.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/MetaClass.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/MetaClass.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/MetaClass.java Thu Aug 7 16:21:46 2008
@@ -0,0 +1,110 @@
+package org.apache.ibatis.reflection;
+
+public class MetaClass {
+
+ private Reflector reflector;
+
+ private MetaClass(Class type) {
+ this.reflector = Reflector.forClass(type);
+ }
+
+ public static MetaClass forClass(Class type) {
+ return new MetaClass(type);
+ }
+
+ public static boolean isClassCacheEnabled() {
+ return Reflector.isClassCacheEnabled();
+ }
+
+ public static void setClassCacheEnabled(boolean classCacheEnabled) {
+ Reflector.setClassCacheEnabled(classCacheEnabled);
+ }
+
+ public MetaClass metaClassForProperty(String name) {
+ Class propType = reflector.getGetterType(name);
+ return MetaClass.forClass(propType);
+ }
+
+ public String findProperty(String name) {
+ StringBuilder prop = buildProperty(name, new StringBuilder());
+ return prop.length() > 0 ? prop.toString() : null;
+ }
+
+ public String[] getGetterNames() {
+ return reflector.getGetablePropertyNames();
+ }
+
+ public String[] getSetterNames() {
+ return reflector.getSetablePropertyNames();
+ }
+
+ public Class getSetterType(String name) {
+ PropertyTokenizer prop = new PropertyTokenizer(name);
+ if (prop.hasNext()) {
+ MetaClass metaProp = metaClassForProperty(prop.getName());
+ return metaProp.getSetterType(prop.getChildren());
+ } else {
+ return reflector.getSetterType(prop.getName());
+ }
+ }
+
+ public Class getGetterType(String name) {
+ PropertyTokenizer prop = new PropertyTokenizer(name);
+ if (prop.hasNext()) {
+ MetaClass metaProp = metaClassForProperty(prop.getName());
+ return metaProp.getGetterType(prop.getChildren());
+ } else {
+ return reflector.getGetterType(prop.getName());
+ }
+ }
+
+ public boolean hasSetter(String name) {
+ PropertyTokenizer prop = new PropertyTokenizer(name);
+ if (prop.hasNext()) {
+ MetaClass metaProp = metaClassForProperty(prop.getName());
+ return metaProp.hasSetter(prop.getChildren());
+ } else {
+ return reflector.hasSetter(prop.getName());
+ }
+ }
+
+ public boolean hasGetter(String name) {
+ PropertyTokenizer prop = new PropertyTokenizer(name);
+ if (prop.hasNext()) {
+ MetaClass metaProp = metaClassForProperty(prop.getName());
+ return metaProp.hasGetter(prop.getChildren());
+ } else {
+ return reflector.hasGetter(prop.getName());
+ }
+ }
+
+ public Invoker getGetInvoker(String name) {
+ return reflector.getGetInvoker(name);
+ }
+
+ public Invoker getSetInvoker(String name) {
+ return reflector.getSetInvoker(name);
+ }
+
+ private StringBuilder buildProperty(String name, StringBuilder builder) {
+ PropertyTokenizer prop = new PropertyTokenizer(name);
+ if (prop.hasNext()) {
+ String propertyName = reflector.findPropertyName(prop.getName());
+ if (propertyName != null) {
+ builder.append(propertyName);
+ builder.append(".");
+ MetaClass metaProp = metaClassForProperty(prop.getName());
+ metaProp.buildProperty(prop.getChildren(), builder);
+ }
+ } else {
+ String propertyName = reflector.findPropertyName(name);
+ if (propertyName != null) {
+ builder.append(propertyName);
+ }
+ }
+ return builder;
+ }
+
+}
+
+
Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/MetaObject.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/MetaObject.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/MetaObject.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/MetaObject.java Thu Aug 7 16:21:46 2008
@@ -0,0 +1,293 @@
+package org.apache.ibatis.reflection;
+
+import java.util.*;
+
+public class MetaObject {
+
+ private Object object;
+ private MetaClass metaClass;
+ private ObjectFactory objectFactory;
+
+ private static final Object[] NO_ARGUMENTS = new Object[0];
+ private static final ObjectFactory DEFAULT_OBJECT_FACTORY = new DefaultObjectFactory();
+
+ public static final MetaObject NULL_META_OBJECT = new MetaObject(NullObject.class, DEFAULT_OBJECT_FACTORY);
+
+ private MetaObject(Object object, ObjectFactory objectFactory) {
+ this.object = object;
+ this.metaClass = MetaClass.forClass(object.getClass());
+ this.objectFactory = objectFactory;
+ }
+
+ public static MetaObject forObject(Object object, ObjectFactory objectFactory) {
+ if (object == null) {
+ return NULL_META_OBJECT;
+ } else {
+ return new MetaObject(object, objectFactory);
+ }
+ }
+
+ public static MetaObject forObject(Object object) {
+ return forObject(object, DEFAULT_OBJECT_FACTORY);
+ }
+
+ public MetaObject metaObjectForProperty(String name) {
+ Object value = getValue(name);
+ return MetaObject.forObject(value);
+ }
+
+ public String findProperty(String propName) {
+ if (object instanceof Map) return propName;
+ return metaClass.findProperty(propName);
+ }
+
+ public String[] getGetterNames() {
+ if (object instanceof Map) return (String[]) ((Map) object).keySet().toArray(new String[((Map) object).size()]);
+ return metaClass.getGetterNames();
+ }
+
+ public String[] getSetterNames() {
+ if (object instanceof Map) return (String[]) ((Map) object).keySet().toArray(new String[((Map) object).size()]);
+ return metaClass.getSetterNames();
+ }
+
+ public Class getSetterType(String name) {
+ if (object instanceof Map)
+ return ((Map) object).get(name) == null ? Object.class : ((Map) object).get(name).getClass();
+ PropertyTokenizer prop = new PropertyTokenizer(name);
+ if (prop.hasNext()) {
+ MetaObject metaValue = metaObjectForProperty(prop.getIndexedName());
+ if (metaValue == MetaObject.NULL_META_OBJECT) {
+ return metaClass.getSetterType(name);
+ } else {
+ return metaValue.getSetterType(prop.getChildren());
+ }
+ } else {
+ return metaClass.getSetterType(name);
+ }
+ }
+
+ public Class getGetterType(String name) {
+ if (object instanceof Map)
+ return ((Map) object).get(name) == null ? Object.class : ((Map) object).get(name).getClass();
+ PropertyTokenizer prop = new PropertyTokenizer(name);
+ if (prop.hasNext()) {
+ MetaObject metaValue = metaObjectForProperty(prop.getIndexedName());
+ if (metaValue == MetaObject.NULL_META_OBJECT) {
+ return metaClass.getGetterType(name);
+ } else {
+ return metaValue.getGetterType(prop.getChildren());
+ }
+ } else {
+ return metaClass.getGetterType(name);
+ }
+ }
+
+ public boolean hasSetter(String name) {
+ if (object instanceof Map) return true;
+ PropertyTokenizer prop = new PropertyTokenizer(name);
+ if (prop.hasNext()) {
+ MetaObject metaValue = metaObjectForProperty(prop.getIndexedName());
+ if (metaValue == MetaObject.NULL_META_OBJECT) {
+ return metaClass.hasSetter(name);
+ } else {
+ return metaValue.hasSetter(prop.getChildren());
+ }
+ } else {
+ return metaClass.hasSetter(name);
+ }
+ }
+
+ public boolean hasGetter(String name) {
+ if (object instanceof Map) return true;
+ PropertyTokenizer prop = new PropertyTokenizer(name);
+ if (prop.hasNext()) {
+ MetaObject metaValue = metaObjectForProperty(prop.getIndexedName());
+ if (metaValue == MetaObject.NULL_META_OBJECT) {
+ return metaClass.hasGetter(name);
+ } else {
+ return metaValue.hasGetter(prop.getChildren());
+ }
+ } else {
+ return metaClass.hasGetter(name);
+ }
+ }
+
+ public Object getValue(String name) {
+ PropertyTokenizer prop = new PropertyTokenizer(name);
+ if (prop.hasNext()) {
+ MetaObject metaValue = metaObjectForProperty(prop.getIndexedName());
+ if (metaValue == MetaObject.NULL_META_OBJECT) {
+ return null;
+ } else {
+ return metaValue.getValue(prop.getChildren());
+ }
+ } else {
+ return getProperty(object, prop);
+ }
+ }
+
+ public void setValue(String name, Object value) {
+ PropertyTokenizer prop = new PropertyTokenizer(name);
+ if (prop.hasNext()) {
+ MetaObject metaValue = metaObjectForProperty(prop.getIndexedName());
+ if (metaValue == MetaObject.NULL_META_OBJECT) {
+ if (value == null && prop.getChildren() != null) {
+ return; // don't instantiate child path if value is null
+ } else {
+ Class type = getSetterType(prop.getName());
+ try {
+ Object newObject = objectFactory.create(type);
+ metaValue = MetaObject.forObject(newObject);
+ setProperty(object, prop, newObject);
+ } catch (Exception e) {
+ throw new RuntimeException("Cannot set value of property '" + name + "' because '" + name + "' is null and cannot be instantiated on instance of " + type.getName() + ". Cause:" + e.toString(), e);
+ }
+ }
+ }
+ metaValue.setValue(prop.getChildren(), value);
+ } else {
+ setProperty(object, prop, value);
+ }
+
+ }
+
+ private Object getProperty(Object object, PropertyTokenizer prop) {
+ if (prop.getIndex() != null) {
+ return getIndexedProperty(object, prop);
+ } else {
+ return getBeanOrMapProperty(object, prop);
+ }
+ }
+
+ private Object getBeanOrMapProperty(Object object, PropertyTokenizer prop) {
+ if (object instanceof Map) {
+ return ((Map) object).get(prop.getName());
+ } else {
+ return getBeanProperty(object, prop);
+ }
+ }
+
+ private void setProperty(Object object, PropertyTokenizer prop, Object value) {
+ if (prop.getIndex() != null) {
+ setIndexedProperty(object, prop, value);
+ } else if (object instanceof Map) {
+ ((Map) object).put(prop.getName(), value);
+ } else {
+ setBeanProperty(object, prop, value);
+ }
+ }
+
+ private Object getBeanProperty(Object object, PropertyTokenizer prop) {
+ try {
+ Invoker method = metaClass.getGetInvoker(prop.getName());
+ try {
+ return method.invoke(object, NO_ARGUMENTS);
+ } catch (Throwable t) {
+ throw ExceptionUtil.unwrapThrowable(t);
+ }
+ } catch (RuntimeException e) {
+ throw e;
+ } catch (Throwable t) {
+ throw new RuntimeException("Could not get property '" + prop.getName() + "' from " + object + ". Cause: " + t.toString(), t);
+ }
+ }
+
+ private void setBeanProperty(Object object, PropertyTokenizer prop, Object value) {
+ try {
+ Invoker method = metaClass.getSetInvoker(prop.getName());
+ Object[] params = {value};
+ try {
+ method.invoke(object, params);
+ } catch (Throwable t) {
+ throw ExceptionUtil.unwrapThrowable(t);
+ }
+ } catch (Throwable t) {
+ throw new RuntimeException("Could not set property '" + prop.getName() + "' for " + object + ". Cause: " + t.toString(), t);
+ }
+ }
+
+ private Object getIndexedProperty(Object object, PropertyTokenizer prop) {
+ Object value;
+ try {
+ int i = Integer.parseInt(prop.getIndex());
+ Object list;
+ if ("".equals(prop.getName())) {
+ list = object;
+ } else {
+ list = getBeanOrMapProperty(object, prop);
+ }
+ if (list instanceof List) {
+ value = ((List) list).get(i);
+ } else if (list instanceof Object[]) {
+ value = ((Object[]) list)[i];
+ } else if (list instanceof char[]) {
+ value = ((char[]) list)[i];
+ } else if (list instanceof boolean[]) {
+ value = ((boolean[]) list)[i];
+ } else if (list instanceof byte[]) {
+ value = ((byte[]) list)[i];
+ } else if (list instanceof double[]) {
+ value = ((double[]) list)[i];
+ } else if (list instanceof float[]) {
+ value = ((float[]) list)[i];
+ } else if (list instanceof int[]) {
+ value = ((int[]) list)[i];
+ } else if (list instanceof long[]) {
+ value = ((long[]) list)[i];
+ } else if (list instanceof short[]) {
+ value = ((short[]) list)[i];
+ } else {
+ throw new RuntimeException("The '" + prop.getName() + "' property of " + object + " is not a List or Array.");
+ }
+ } catch (RuntimeException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new RuntimeException("Error getting ordinal list from JavaBean. Cause " + e, e);
+ }
+ return value;
+ }
+
+ private void setIndexedProperty(Object object, PropertyTokenizer prop, Object value) {
+ try {
+ int i = Integer.parseInt(prop.getIndex());
+ Object list;
+ if ("".equals(prop.getName())) {
+ list = object;
+ } else {
+ list = getBeanOrMapProperty(object, prop);
+ }
+ if (list instanceof List) {
+ ((List) list).set(i, value);
+ } else if (list instanceof Object[]) {
+ ((Object[]) list)[i] = value;
+ } else if (list instanceof char[]) {
+ ((char[]) list)[i] = (Character) value;
+ } else if (list instanceof boolean[]) {
+ ((boolean[]) list)[i] = (Boolean) value;
+ } else if (list instanceof byte[]) {
+ ((byte[]) list)[i] = (Byte) value;
+ } else if (list instanceof double[]) {
+ ((double[]) list)[i] = (Double) value;
+ } else if (list instanceof float[]) {
+ ((float[]) list)[i] = (Float) value;
+ } else if (list instanceof int[]) {
+ ((int[]) list)[i] = (Integer) value;
+ } else if (list instanceof long[]) {
+ ((long[]) list)[i] = (Long) value;
+ } else if (list instanceof short[]) {
+ ((short[]) list)[i] = (Short) value;
+ } else {
+ throw new RuntimeException("The '" + prop.getName() + "' property of " + object + " is not a List or Array.");
+ }
+ } catch (RuntimeException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new RuntimeException("Error getting ordinal value from JavaBean. Cause " + e, e);
+ }
+ }
+
+ private static class NullObject {
+ }
+
+}
Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/MethodInvoker.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/MethodInvoker.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/MethodInvoker.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/MethodInvoker.java Thu Aug 7 16:21:46 2008
@@ -0,0 +1,27 @@
+package org.apache.ibatis.reflection;
+
+import java.lang.reflect.*;
+
+class MethodInvoker implements Invoker {
+
+ private Class type;
+ private Method method;
+
+ public MethodInvoker(Method method) {
+ this.method = method;
+
+ if (method.getParameterTypes().length == 1) {
+ type = method.getParameterTypes()[0];
+ } else {
+ type = method.getReturnType();
+ }
+ }
+
+ public Object invoke(Object target, Object[] args) throws IllegalAccessException, InvocationTargetException {
+ return method.invoke(target, args);
+ }
+
+ public Class getType() {
+ return type;
+ }
+}
Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/ObjectFactory.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/ObjectFactory.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/ObjectFactory.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/ObjectFactory.java Thu Aug 7 16:21:46 2008
@@ -0,0 +1,13 @@
+package org.apache.ibatis.reflection;
+
+import java.util.List;
+
+public interface ObjectFactory {
+
+ Object create(Class type);
+
+ Object create(Class type, List<Class> constructorArgTypes, List<Object> constructorArgs);
+
+ void setProperty(String name, String value);
+
+}
Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/PropertyNamer.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/PropertyNamer.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/PropertyNamer.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/PropertyNamer.java Thu Aug 7 16:21:46 2008
@@ -0,0 +1,27 @@
+package org.apache.ibatis.reflection;
+
+import java.util.Locale;
+
+public class PropertyNamer {
+
+ public static String methodToProperty(String name) {
+ if (name.startsWith("is")) {
+ name = name.substring(2);
+ } else if (name.startsWith("get") || name.startsWith("set")) {
+ name = name.substring(3);
+ } else {
+ throw new RuntimeException("Error parsing property name '" + name + "'. Didn't start with 'is', 'get' or 'set'.");
+ }
+
+ if (name.length() == 1 || (name.length() > 1 && !Character.isUpperCase(name.charAt(1)))) {
+ name = name.substring(0, 1).toLowerCase(Locale.US) + name.substring(1);
+ }
+
+ return name;
+ }
+
+ public static boolean isProperty(String name) {
+ return name.startsWith("get") || name.startsWith("set") || name.startsWith("is");
+ }
+
+}
Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/PropertyTokenizer.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/PropertyTokenizer.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/PropertyTokenizer.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/PropertyTokenizer.java Thu Aug 7 16:21:46 2008
@@ -0,0 +1,59 @@
+package org.apache.ibatis.reflection;
+
+import java.util.Iterator;
+
+class PropertyTokenizer implements Iterable<PropertyTokenizer>, Iterator<PropertyTokenizer> {
+ private String name;
+ private String indexedName;
+ private String index;
+ private String children;
+
+ public PropertyTokenizer(String fullname) {
+ int delim = fullname.indexOf('.');
+ if (delim > -1) {
+ name = fullname.substring(0, delim);
+ children = fullname.substring(delim + 1);
+ } else {
+ name = fullname;
+ children = null;
+ }
+ indexedName = name;
+ delim = name.indexOf('[');
+ if (delim > -1) {
+ index = name.substring(delim + 1, name.length() - 1);
+ name = name.substring(0, delim);
+ }
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getIndex() {
+ return index;
+ }
+
+ public String getIndexedName() {
+ return indexedName;
+ }
+
+ public String getChildren() {
+ return children;
+ }
+
+ public boolean hasNext() {
+ return children != null;
+ }
+
+ public PropertyTokenizer next() {
+ return new PropertyTokenizer(children);
+ }
+
+ public void remove() {
+ throw new UnsupportedOperationException("Remove is not supported, as it has no meaning in the context of properties.");
+ }
+
+ public Iterator<PropertyTokenizer> iterator() {
+ return this;
+ }
+}
Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/Reflector.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/Reflector.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/Reflector.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/Reflector.java Thu Aug 7 16:21:46 2008
@@ -0,0 +1,422 @@
+package org.apache.ibatis.reflection;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+/**
+ * This class represents a cached set of class definition information that
+ * allows for easy mapping between property names and getter/setter methods.
+ */
+class Reflector {
+
+ private static boolean classCacheEnabled = true;
+ private static final String[] EMPTY_STRING_ARRAY = new String[0];
+ private static final Map<Class, Reflector> REFLECTOR_MAP = Collections.synchronizedMap(new HashMap<Class, Reflector>());
+
+ private Class type;
+ private String[] readablePropertyNames = EMPTY_STRING_ARRAY;
+ private String[] writeablePropertyNames = EMPTY_STRING_ARRAY;
+ private Map<String, Invoker> setMethods = new HashMap<String, Invoker>();
+ private Map<String, Invoker> getMethods = new HashMap<String, Invoker>();
+ private Map<String, Class> setTypes = new HashMap<String, Class>();
+ private Map<String, Class> getTypes = new HashMap<String, Class>();
+ private Constructor defaultConstructor;
+
+ private Map<String, String> caseInsensitivePropertyMap = new HashMap<String, String>();
+
+ private Reflector(Class clazz) {
+ type = clazz;
+ addDefaultConstructor(clazz);
+ addGetMethods(clazz);
+ addSetMethods(clazz);
+ addFields(clazz);
+ readablePropertyNames = getMethods.keySet().toArray(new String[getMethods.keySet().size()]);
+ writeablePropertyNames = setMethods.keySet().toArray(new String[setMethods.keySet().size()]);
+ for (String propName : readablePropertyNames) {
+ caseInsensitivePropertyMap.put(propName.toUpperCase(), propName);
+ }
+ for (String propName : writeablePropertyNames) {
+ caseInsensitivePropertyMap.put(propName.toUpperCase(), propName);
+ }
+ }
+
+ private void addDefaultConstructor(Class clazz) {
+ Constructor[] consts = clazz.getDeclaredConstructors();
+ for (Constructor constructor : consts) {
+ if (constructor.getParameterTypes().length == 0) {
+ if (canAccessPrivateMethods()) {
+ try {
+ constructor.setAccessible(true);
+ } catch (Exception e) {
+ // Ignored. This is only a final precaution, nothing we can do.
+ }
+ }
+ if (constructor.isAccessible()) {
+ this.defaultConstructor = constructor;
+ }
+ }
+ }
+ }
+
+ private void addGetMethods(Class cls) {
+ Method[] methods = getAllMethodsForClass(cls);
+ for (Method method : methods) {
+ String name = method.getName();
+ if (name.startsWith("get") && name.length() > 3) {
+ if (method.getParameterTypes().length == 0) {
+ name = PropertyNamer.methodToProperty(name);
+ addGetMethod(name, method);
+ }
+ } else if (name.startsWith("is") && name.length() > 2) {
+ if (method.getParameterTypes().length == 0) {
+ name = PropertyNamer.methodToProperty(name);
+ addGetMethod(name, method);
+ }
+ }
+ }
+ }
+
+ private void addGetMethod(String name, Method method) {
+ if (isValidPropertyName(name)) {
+ getMethods.put(name, new MethodInvoker(method));
+ getTypes.put(name, method.getReturnType());
+ }
+ }
+
+ private void addSetMethods(Class cls) {
+ Map<String, List<Method>> conflictingSetters = new HashMap<String, List<Method>>();
+ Method[] methods = getAllMethodsForClass(cls);
+ for (Method method : methods) {
+ String name = method.getName();
+ if (name.startsWith("set") && name.length() > 3) {
+ if (method.getParameterTypes().length == 1) {
+ name = PropertyNamer.methodToProperty(name);
+ addSetterConflict(conflictingSetters, name, method);
+ }
+ }
+ }
+ resolveSetterConflicts(conflictingSetters);
+ }
+
+ private void addSetterConflict(Map<String, List<Method>> conflictingSetters, String name, Method method) {
+ List<Method> list = conflictingSetters.get(name);
+ if (list == null) {
+ list = new ArrayList<Method>();
+ conflictingSetters.put(name, list);
+ }
+ list.add(method);
+ }
+
+ private void resolveSetterConflicts(Map<String, List<Method>> conflictingSetters) {
+ for (String propName : conflictingSetters.keySet()) {
+ List<Method> setters = conflictingSetters.get(propName);
+ Method firstMethod = setters.get(0);
+ if (setters.size() == 1) {
+ addSetMethod(propName, firstMethod);
+ } else {
+ Class expectedType = getTypes.get(propName);
+ if (expectedType == null) {
+ throw new RuntimeException("Illegal overloaded setter method with ambiguous type for property "
+ + propName + " in class " + firstMethod.getDeclaringClass() + ". This breaks the JavaBeans " +
+ "specification and can cause unpredicatble results.");
+ } else {
+ Iterator<Method> methods = setters.iterator();
+ Method setter = null;
+ while (methods.hasNext()) {
+ Method method = methods.next();
+ if (method.getParameterTypes().length == 1
+ && expectedType.equals(method.getParameterTypes()[0])) {
+ setter = method;
+ break;
+ }
+ }
+ if (setter == null) {
+ throw new RuntimeException("Illegal overloaded setter method with ambiguous type for property "
+ + propName + " in class " + firstMethod.getDeclaringClass() + ". This breaks the JavaBeans " +
+ "specification and can cause unpredicatble results.");
+ }
+ addSetMethod(propName, setter);
+ }
+ }
+ }
+ }
+
+ private void addSetMethod(String name, Method method) {
+ if (isValidPropertyName(name)) {
+ setMethods.put(name, new MethodInvoker(method));
+ setTypes.put(name, method.getParameterTypes()[0]);
+ }
+ }
+
+ private void addFields(Class clazz) {
+ Field[] fields = clazz.getDeclaredFields();
+ for (Field field : fields) {
+ if (canAccessPrivateMethods()) {
+ try {
+ field.setAccessible(true);
+ } catch (Exception e) {
+ // Ignored. This is only a final precaution, nothing we can do.
+ }
+ }
+ if (field.isAccessible()) {
+ if (!setMethods.containsKey(field.getName())) {
+ if (!Modifier.isFinal(field.getModifiers())) {
+ addSetField(field);
+ }
+ }
+ if (!getMethods.containsKey(field.getName())) {
+ addGetField(field);
+ }
+ }
+ }
+ if (clazz.getSuperclass() != null) {
+ addFields(clazz.getSuperclass());
+ }
+ }
+
+ private void addSetField(Field field) {
+ if (isValidPropertyName(field.getName())) {
+ setMethods.put(field.getName(), new SetFieldInvoker(field));
+ setTypes.put(field.getName(), field.getType());
+ }
+ }
+
+ private void addGetField(Field field) {
+ if (isValidPropertyName(field.getName())) {
+ getMethods.put(field.getName(), new GetFieldInvoker(field));
+ getTypes.put(field.getName(), field.getType());
+ }
+ }
+
+ private boolean isValidPropertyName(String name) {
+ return !(name.startsWith("$") || "serialVersionUID".equals(name) || "class".equals(name));
+ }
+
+ private Method[] getAllMethodsForClass(Class cls) {
+ if (cls.isInterface()) {
+ // interfaces only have public methods - so the
+ // simple call is all we need (this will also get superinterface methods)
+ return cls.getMethods();
+ } else {
+ // need to get all the declared methods in this class
+ // and any super-class - then need to set access appropriatly
+ // for private methods
+ return getClassMethods(cls);
+ }
+ }
+
+ /**
+ * This method returns an array containing all methods
+ * declared in this class and any superclass.
+ * We use this method, instead of the simpler Class.getMethods(),
+ * because we want to look for private methods as well.
+ *
+ * @param cls The class
+ * @return An array containing all methods in this class
+ */
+ private Method[] getClassMethods(Class cls) {
+ HashMap<String, Method> uniqueMethods = new HashMap<String, Method>();
+ Class currentClass = cls;
+ while (currentClass != null) {
+ addUniqueMethods(uniqueMethods, currentClass.getDeclaredMethods());
+
+ // we also need to look for interface methods -
+ // because the class may be abstract
+ Class[] interfaces = currentClass.getInterfaces();
+ for (Class anInterface : interfaces) {
+ addUniqueMethods(uniqueMethods, anInterface.getMethods());
+ }
+
+ currentClass = currentClass.getSuperclass();
+ }
+
+ Collection<Method> methods = uniqueMethods.values();
+
+ return methods.toArray(new Method[methods.size()]);
+ }
+
+ private void addUniqueMethods(HashMap<String, Method> uniqueMethods, Method[] methods) {
+ for (Method currentMethod : methods) {
+ String signature = getSignature(currentMethod);
+ // check to see if the method is already known
+ // if it is known, then an extended class must have
+ // overridden a method
+ if (!uniqueMethods.containsKey(signature)) {
+ if (canAccessPrivateMethods()) {
+ try {
+ currentMethod.setAccessible(true);
+ } catch (Exception e) {
+ // Ignored. This is only a final precaution, nothing we can do.
+ }
+ }
+
+ uniqueMethods.put(signature, currentMethod);
+ }
+ }
+ }
+
+ private String getSignature(Method method) {
+ StringBuffer sb = new StringBuffer();
+ sb.append(method.getName());
+ Class[] parameters = method.getParameterTypes();
+
+ for (int i = 0; i < parameters.length; i++) {
+ if (i == 0) {
+ sb.append(':');
+ } else {
+ sb.append(',');
+ }
+ sb.append(parameters[i].getName());
+ }
+
+ return sb.toString();
+ }
+
+ private static boolean canAccessPrivateMethods() {
+ try {
+ SecurityManager securityManager = System.getSecurityManager();
+ if (null != securityManager) {
+ securityManager.checkPermission(new ReflectPermission("suppressAccessChecks"));
+ }
+ } catch (SecurityException e) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Gets the name of the class the instance provides information for
+ *
+ * @return The class name
+ */
+ public Class getType() {
+ return type;
+ }
+
+ public Constructor getDefaultConstructor() {
+ if (defaultConstructor != null) {
+ return defaultConstructor;
+ } else {
+ throw new RuntimeException("There is no default constructor for " + type);
+ }
+ }
+
+ public Invoker getSetInvoker(String propertyName) {
+ Invoker method = setMethods.get(propertyName);
+ if (method == null) {
+ throw new RuntimeException("There is no setter for property named '" + propertyName + "' in '" + type + "'");
+ }
+ return method;
+ }
+
+ public Invoker getGetInvoker(String propertyName) {
+ Invoker method = getMethods.get(propertyName);
+ if (method == null) {
+ throw new RuntimeException("There is no getter for property named '" + propertyName + "' in '" + type + "'");
+ }
+ return method;
+ }
+
+ /**
+ * Gets the type for a property setter
+ *
+ * @param propertyName - the name of the property
+ * @return The Class of the propery setter
+ */
+ public Class getSetterType(String propertyName) {
+ Class clazz = setTypes.get(propertyName);
+ if (clazz == null) {
+ throw new RuntimeException("There is no setter for property named '" + propertyName + "' in '" + type + "'");
+ }
+ return clazz;
+ }
+
+ /**
+ * Gets the type for a property getter
+ *
+ * @param propertyName - the name of the property
+ * @return The Class of the propery getter
+ */
+ public Class getGetterType(String propertyName) {
+ Class clazz = getTypes.get(propertyName);
+ if (clazz == null) {
+ throw new RuntimeException("There is no getter for property named '" + propertyName + "' in '" + type + "'");
+ }
+ return clazz;
+ }
+
+ /**
+ * Gets an array of the readable properties for an object
+ *
+ * @return The array
+ */
+ public String[] getGetablePropertyNames() {
+ return readablePropertyNames;
+ }
+
+ /**
+ * Gets an array of the writeable properties for an object
+ *
+ * @return The array
+ */
+ public String[] getSetablePropertyNames() {
+ return writeablePropertyNames;
+ }
+
+ /**
+ * Check to see if a class has a writeable property by name
+ *
+ * @param propertyName - the name of the property to check
+ * @return True if the object has a writeable property by the name
+ */
+ public boolean hasSetter(String propertyName) {
+ return setMethods.keySet().contains(propertyName);
+ }
+
+ /**
+ * Check to see if a class has a readable property by name
+ *
+ * @param propertyName - the name of the property to check
+ * @return True if the object has a readable property by the name
+ */
+ public boolean hasGetter(String propertyName) {
+ return getMethods.keySet().contains(propertyName);
+ }
+
+ public String findPropertyName(String name) {
+ return caseInsensitivePropertyMap.get(name.toUpperCase());
+ }
+
+ /**
+ * Gets an instance of ClassInfo for the specified class.
+ *
+ * @param clazz The class for which to lookup the method cache.
+ * @return The method cache for the class
+ */
+ public static Reflector forClass(Class clazz) {
+ if (classCacheEnabled) {
+ synchronized (clazz) {
+ Reflector cached = REFLECTOR_MAP.get(clazz);
+ if (cached == null) {
+ cached = new Reflector(clazz);
+ REFLECTOR_MAP.put(clazz, cached);
+ }
+ return cached;
+ }
+ } else {
+ return new Reflector(clazz);
+ }
+ }
+
+ public static void setClassCacheEnabled(boolean classCacheEnabled) {
+ Reflector.classCacheEnabled = classCacheEnabled;
+ }
+
+ public static boolean isClassCacheEnabled() {
+ return classCacheEnabled;
+ }
+
+}
+
+
+
Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/SetFieldInvoker.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/SetFieldInvoker.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/SetFieldInvoker.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/SetFieldInvoker.java Thu Aug 7 16:21:46 2008
@@ -0,0 +1,20 @@
+package org.apache.ibatis.reflection;
+
+import java.lang.reflect.*;
+
+class SetFieldInvoker implements Invoker {
+ private Field field;
+
+ public SetFieldInvoker(Field field) {
+ this.field = field;
+ }
+
+ public Object invoke(Object target, Object[] args) throws IllegalAccessException, InvocationTargetException {
+ field.set(target, args[0]);
+ return null;
+ }
+
+ public Class getType() {
+ return field.getType();
+ }
+}
Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/BaseTypeHandler.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/BaseTypeHandler.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/BaseTypeHandler.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/BaseTypeHandler.java Thu Aug 7 16:21:46 2008
@@ -0,0 +1,49 @@
+package org.apache.ibatis.type;
+
+import java.sql.*;
+
+public abstract class BaseTypeHandler implements TypeHandler {
+
+ public void setParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType)
+ throws SQLException {
+ if (parameter == null) {
+ if (jdbcType == null) {
+ throw new RuntimeException("JDBC requires that the JdbcType must be specified for all nullable parameters.");
+ }
+ ps.setNull(i, jdbcType.TYPE_CODE);
+ } else {
+ setNonNullParameter(ps, i, parameter, jdbcType);
+ }
+ }
+
+ public Object getResult(ResultSet rs, String columnName)
+ throws SQLException {
+ Object result = getNullableResult(rs, columnName);
+ if (rs.wasNull()) {
+ return null;
+ } else {
+ return result;
+ }
+ }
+
+ public Object getResult(CallableStatement cs, int columnIndex)
+ throws SQLException {
+ Object result = getNullableResult(cs, columnIndex);
+ if (cs.wasNull()) {
+ return null;
+ } else {
+ return result;
+ }
+ }
+
+ public abstract void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType)
+ throws SQLException;
+
+ public abstract Object getNullableResult(ResultSet rs, String columnName)
+ throws SQLException;
+
+ public abstract Object getNullableResult(CallableStatement cs, int columnIndex)
+ throws SQLException;
+
+}
+
Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/BigDecimalTypeHandler.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/BigDecimalTypeHandler.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/BigDecimalTypeHandler.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/BigDecimalTypeHandler.java Thu Aug 7 16:21:46 2008
@@ -0,0 +1,24 @@
+package org.apache.ibatis.type;
+
+import java.math.BigDecimal;
+import java.sql.*;
+
+public class BigDecimalTypeHandler extends BaseTypeHandler {
+
+ public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType)
+ throws SQLException {
+ ps.setBigDecimal(i, ((BigDecimal) parameter));
+ }
+
+ public Object getNullableResult(ResultSet rs, String columnName)
+ throws SQLException {
+ return rs.getBigDecimal(columnName);
+ }
+
+ public Object getNullableResult(CallableStatement cs, int columnIndex)
+ throws SQLException {
+ return cs.getBigDecimal(columnIndex);
+ }
+
+
+}
Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/BlobTypeHandler.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/BlobTypeHandler.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/BlobTypeHandler.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/BlobTypeHandler.java Thu Aug 7 16:21:46 2008
@@ -0,0 +1,35 @@
+package org.apache.ibatis.type;
+
+import java.io.ByteArrayInputStream;
+import java.sql.*;
+
+public class BlobTypeHandler extends BaseTypeHandler {
+
+ public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType)
+ throws SQLException {
+ byte[] bytes = (byte[]) parameter;
+ ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
+ ps.setBinaryStream(i, bis, bytes.length);
+ }
+
+ public Object getNullableResult(ResultSet rs, String columnName)
+ throws SQLException {
+ Blob blob = rs.getBlob(columnName);
+ byte[] returnValue = null;
+ if (null != blob) {
+ returnValue = blob.getBytes(1, (int) blob.length());
+ }
+ return returnValue;
+ }
+
+ public Object getNullableResult(CallableStatement cs, int columnIndex)
+ throws SQLException {
+ Blob blob = cs.getBlob(columnIndex);
+ byte[] returnValue = null;
+ if (null != blob) {
+ returnValue = blob.getBytes(1, (int) blob.length());
+ }
+ return returnValue;
+ }
+
+}
\ No newline at end of file
Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/BooleanTypeHandler.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/BooleanTypeHandler.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/BooleanTypeHandler.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/BooleanTypeHandler.java Thu Aug 7 16:21:46 2008
@@ -0,0 +1,23 @@
+package org.apache.ibatis.type;
+
+import java.sql.*;
+
+public class BooleanTypeHandler extends BaseTypeHandler {
+
+ public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType)
+ throws SQLException {
+ ps.setBoolean(i, (Boolean) parameter);
+ }
+
+ public Object getNullableResult(ResultSet rs, String columnName)
+ throws SQLException {
+ return rs.getBoolean(columnName);
+ }
+
+ public Object getNullableResult(CallableStatement cs, int columnIndex)
+ throws SQLException {
+ return cs.getBoolean(columnIndex);
+ }
+
+
+}
Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/ByteArrayTypeHandler.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/ByteArrayTypeHandler.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/ByteArrayTypeHandler.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/ByteArrayTypeHandler.java Thu Aug 7 16:21:46 2008
@@ -0,0 +1,23 @@
+package org.apache.ibatis.type;
+
+import java.sql.*;
+
+public class ByteArrayTypeHandler extends BaseTypeHandler {
+
+ public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType)
+ throws SQLException {
+ ps.setBytes(i, (byte[]) parameter);
+ }
+
+ public Object getNullableResult(ResultSet rs, String columnName)
+ throws SQLException {
+ return rs.getBytes(columnName);
+ }
+
+ public Object getNullableResult(CallableStatement cs, int columnIndex)
+ throws SQLException {
+ return cs.getBytes(columnIndex);
+ }
+
+
+}
Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/ByteTypeHandler.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/ByteTypeHandler.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/ByteTypeHandler.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/ByteTypeHandler.java Thu Aug 7 16:21:46 2008
@@ -0,0 +1,23 @@
+package org.apache.ibatis.type;
+
+import java.sql.*;
+
+public class ByteTypeHandler extends BaseTypeHandler {
+
+ public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType)
+ throws SQLException {
+ ps.setByte(i, (Byte) parameter);
+ }
+
+ public Object getNullableResult(ResultSet rs, String columnName)
+ throws SQLException {
+ return rs.getByte(columnName);
+ }
+
+ public Object getNullableResult(CallableStatement cs, int columnIndex)
+ throws SQLException {
+ return cs.getByte(columnIndex);
+ }
+
+
+}
Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/ClobTypeHandler.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/ClobTypeHandler.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/ClobTypeHandler.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/ClobTypeHandler.java Thu Aug 7 16:21:46 2008
@@ -0,0 +1,38 @@
+package org.apache.ibatis.type;
+
+import java.io.StringReader;
+import java.sql.*;
+
+public class ClobTypeHandler extends BaseTypeHandler {
+
+
+ public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType)
+ throws SQLException {
+ String s = (String) parameter;
+ StringReader reader = new StringReader(s);
+ ps.setCharacterStream(i, reader, s.length());
+ }
+
+ public Object getNullableResult(ResultSet rs, String columnName)
+ throws SQLException {
+ String value = "";
+ Clob clob = rs.getClob(columnName);
+ if (clob != null) {
+ int size = (int) clob.length();
+ value = clob.getSubString(1, size);
+ }
+ return value;
+ }
+
+ public Object getNullableResult(CallableStatement cs, int columnIndex)
+ throws SQLException {
+ String value = "";
+ Clob clob = cs.getClob(columnIndex);
+ if (clob != null) {
+ int size = (int) clob.length();
+ value = clob.getSubString(1, size);
+ }
+ return value;
+ }
+
+}
Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/DateOnlyTypeHandler.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/DateOnlyTypeHandler.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/DateOnlyTypeHandler.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/DateOnlyTypeHandler.java Thu Aug 7 16:21:46 2008
@@ -0,0 +1,31 @@
+package org.apache.ibatis.type;
+
+import java.sql.*;
+import java.util.Date;
+
+public class DateOnlyTypeHandler extends BaseTypeHandler {
+
+ public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType)
+ throws SQLException {
+ ps.setDate(i, new java.sql.Date(((Date) parameter).getTime()));
+ }
+
+ public Object getNullableResult(ResultSet rs, String columnName)
+ throws SQLException {
+ java.sql.Date sqlDate = rs.getDate(columnName);
+ if (sqlDate != null) {
+ return new java.util.Date(sqlDate.getTime());
+ }
+ return null;
+ }
+
+ public Object getNullableResult(CallableStatement cs, int columnIndex)
+ throws SQLException {
+ java.sql.Date sqlDate = cs.getDate(columnIndex);
+ if (sqlDate != null) {
+ return new java.util.Date(sqlDate.getTime());
+ }
+ return null;
+ }
+
+}
Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/DateTypeHandler.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/DateTypeHandler.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/DateTypeHandler.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/DateTypeHandler.java Thu Aug 7 16:21:46 2008
@@ -0,0 +1,31 @@
+package org.apache.ibatis.type;
+
+import java.sql.*;
+import java.util.Date;
+
+public class DateTypeHandler extends BaseTypeHandler {
+
+ public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType)
+ throws SQLException {
+ ps.setTimestamp(i, new java.sql.Timestamp(((Date) parameter).getTime()));
+ }
+
+ public Object getNullableResult(ResultSet rs, String columnName)
+ throws SQLException {
+ java.sql.Timestamp sqlTimestamp = rs.getTimestamp(columnName);
+ if (sqlTimestamp != null) {
+ return new java.util.Date(sqlTimestamp.getTime());
+ }
+ return null;
+ }
+
+ public Object getNullableResult(CallableStatement cs, int columnIndex)
+ throws SQLException {
+ java.sql.Timestamp sqlTimestamp = cs.getTimestamp(columnIndex);
+ if (sqlTimestamp != null) {
+ return new java.util.Date(sqlTimestamp.getTime());
+ }
+ return null;
+ }
+
+}
Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/DoubleTypeHandler.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/DoubleTypeHandler.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/DoubleTypeHandler.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/DoubleTypeHandler.java Thu Aug 7 16:21:46 2008
@@ -0,0 +1,22 @@
+package org.apache.ibatis.type;
+
+import java.sql.*;
+
+public class DoubleTypeHandler extends BaseTypeHandler {
+
+ public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType)
+ throws SQLException {
+ ps.setDouble(i, (Double) parameter);
+ }
+
+ public Object getNullableResult(ResultSet rs, String columnName)
+ throws SQLException {
+ return rs.getDouble(columnName);
+ }
+
+ public Object getNullableResult(CallableStatement cs, int columnIndex)
+ throws SQLException {
+ return cs.getDouble(columnIndex);
+ }
+
+}
Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/EnumTypeHandler.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/EnumTypeHandler.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/EnumTypeHandler.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/EnumTypeHandler.java Thu Aug 7 16:21:46 2008
@@ -0,0 +1,27 @@
+package org.apache.ibatis.type;
+
+import java.sql.*;
+
+public class EnumTypeHandler extends BaseTypeHandler implements TypeHandler {
+
+ private Class type;
+
+ public EnumTypeHandler(Class type) {
+ this.type = type;
+ }
+
+ public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType) throws SQLException {
+ ps.setString(i, parameter.toString());
+ }
+
+ public Object getNullableResult(ResultSet rs, String columnName) throws SQLException {
+ String s = rs.getString(columnName);
+ return s == null ? null : Enum.valueOf(type, s);
+ }
+
+ public Object getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
+ String s = cs.getString(columnIndex);
+ return s == null ? null : Enum.valueOf(type, s);
+ }
+
+}
\ No newline at end of file
Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/FloatTypeHandler.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/FloatTypeHandler.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/FloatTypeHandler.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/FloatTypeHandler.java Thu Aug 7 16:21:46 2008
@@ -0,0 +1,22 @@
+package org.apache.ibatis.type;
+
+import java.sql.*;
+
+public class FloatTypeHandler extends BaseTypeHandler {
+
+ public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType)
+ throws SQLException {
+ ps.setFloat(i, (Float) parameter);
+ }
+
+ public Object getNullableResult(ResultSet rs, String columnName)
+ throws SQLException {
+ return rs.getFloat(columnName);
+ }
+
+ public Object getNullableResult(CallableStatement cs, int columnIndex)
+ throws SQLException {
+ return cs.getFloat(columnIndex);
+ }
+
+}
Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/IntegerTypeHandler.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/IntegerTypeHandler.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/IntegerTypeHandler.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/IntegerTypeHandler.java Thu Aug 7 16:21:46 2008
@@ -0,0 +1,22 @@
+package org.apache.ibatis.type;
+
+import java.sql.*;
+
+public class IntegerTypeHandler extends BaseTypeHandler {
+
+ public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType)
+ throws SQLException {
+ ps.setInt(i, (Integer) parameter);
+ }
+
+ public Object getNullableResult(ResultSet rs, String columnName)
+ throws SQLException {
+ return rs.getInt(columnName);
+ }
+
+ public Object getNullableResult(CallableStatement cs, int columnIndex)
+ throws SQLException {
+ return cs.getInt(columnIndex);
+ }
+
+}
Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/JdbcType.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/JdbcType.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/JdbcType.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/JdbcType.java Thu Aug 7 16:21:46 2008
@@ -0,0 +1,50 @@
+package org.apache.ibatis.type;
+
+import java.sql.Types;
+
+public enum JdbcType {
+
+ BIT(Types.BIT),
+ TINYINT(Types.TINYINT),
+ SMALLINT(Types.SMALLINT),
+ INTEGER(Types.INTEGER),
+ BIGINT(Types.BIGINT),
+ FLOAT(Types.FLOAT),
+ REAL(Types.REAL),
+ DOUBLE(Types.DOUBLE),
+ NUMERIC(Types.NUMERIC),
+ DECIMAL(Types.DECIMAL),
+ CHAR(Types.CHAR),
+ VARCHAR(Types.VARCHAR),
+ LONGVARCHAR(Types.LONGVARCHAR),
+ DATE(Types.DATE),
+ TIME(Types.TIME),
+ TIMESTAMP(Types.TIMESTAMP),
+ BINARY(Types.BINARY),
+ VARBINARY(Types.VARBINARY),
+ LONGVARBINARY(Types.LONGVARBINARY),
+ NULL(Types.NULL),
+ OTHER(Types.OTHER),
+ BLOB(Types.BLOB),
+ CLOB(Types.CLOB),
+ BOOLEAN(Types.BOOLEAN),
+ CURSOR(-10), // Oracle
+ UNDEFINED(Integer.MIN_VALUE + 1000);
+
+ // ----------------
+ // -- Unsupported--
+ // ----------------
+ //JAVA_OBJECT(Types.JAVA_OBJECT),
+ //DISTINCT(Types.DISTINCT),
+ //STRUCT(Types.STRUCT),
+ //ARRAY(Types.ARRAY),
+ //REF(Types.REF),
+ //DATALINK(Types.DATALINK),
+
+ public final int TYPE_CODE;
+
+ JdbcType(int code) {
+ this.TYPE_CODE = code;
+ }
+
+}
Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/LongTypeHandler.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/LongTypeHandler.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/LongTypeHandler.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/LongTypeHandler.java Thu Aug 7 16:21:46 2008
@@ -0,0 +1,22 @@
+package org.apache.ibatis.type;
+
+import java.sql.*;
+
+public class LongTypeHandler extends BaseTypeHandler {
+
+ public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType)
+ throws SQLException {
+ ps.setLong(i, (Long) parameter);
+ }
+
+ public Object getNullableResult(ResultSet rs, String columnName)
+ throws SQLException {
+ return rs.getLong(columnName);
+ }
+
+ public Object getNullableResult(CallableStatement cs, int columnIndex)
+ throws SQLException {
+ return cs.getLong(columnIndex);
+ }
+
+}
Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/ObjectTypeHandler.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/ObjectTypeHandler.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/ObjectTypeHandler.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/ObjectTypeHandler.java Thu Aug 7 16:21:46 2008
@@ -0,0 +1,22 @@
+package org.apache.ibatis.type;
+
+import java.sql.*;
+
+public class ObjectTypeHandler extends BaseTypeHandler {
+
+ public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType)
+ throws SQLException {
+ ps.setObject(i, parameter);
+ }
+
+ public Object getNullableResult(ResultSet rs, String columnName)
+ throws SQLException {
+ return rs.getObject(columnName);
+ }
+
+ public Object getNullableResult(CallableStatement cs, int columnIndex)
+ throws SQLException {
+ return cs.getObject(columnIndex);
+ }
+
+}
Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/ShortTypeHandler.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/ShortTypeHandler.java?rev=683745&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/ShortTypeHandler.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/type/ShortTypeHandler.java Thu Aug 7 16:21:46 2008
@@ -0,0 +1,22 @@
+package org.apache.ibatis.type;
+
+import java.sql.*;
+
+public class ShortTypeHandler extends BaseTypeHandler {
+
+ public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType)
+ throws SQLException {
+ ps.setShort(i, (Short) parameter);
+ }
+
+ public Object getNullableResult(ResultSet rs, String columnName)
+ throws SQLException {
+ return rs.getShort(columnName);
+ }
+
+ public Object getNullableResult(CallableStatement cs, int columnIndex)
+ throws SQLException {
+ return cs.getShort(columnIndex);
+ }
+
+}